[转]页游开发中的 Python 组件与模式Presentation Transcript
转: 页游开发中的 Python 组件与模式Presentation Transcript
- 1. 页游开发中的 Python 组件与模式 赖勇浩( http://laiyonghao.com ) 2012-10-21 上海
- 2. 去年我来过……
- 3. 回顾……• 幻灯: http://www.slideshare.net/laiyonghao/py thon-webgame-10452102• 录像(上海 45 分钟版): http://e.gensee.com/v_3df867_14• 录像(广州 91 分钟版): http://v.youku.com/v_playlist/f16785412 o1p4.html 偏向于“最佳实践”的经验分享
- 4. 今天不一样……
- 5. 直奔主题!class Player(object): def signin(self, usr, pwd): ... self._signin = True def do_sth(self): if not self._signin: self.client.need_signin() return ...
- 6. 有什么问题?def do_sth_1(...def do_sth_2(...def do_sth_3(...def do_sth_4(...…
- 7. 一般这样解决掉……@ensure_signindef do_sth(self, *a, **kw): … Decorator !!!
- 8. 还有什么问题?def do_sth_1(... if notdef do_sth_2(... self._signin: ...def do_sth_3(... if not self._in_battle: ...def do_sth_4(...… if not self._is_dead: ... ...
- 9. 还是这样解决掉?@ensure_signin@ensure_in_battle@ensuer_is_alivedef do_sth(self, *a, **kw): … ???
- 10. 好像哪里不对……• 戴太多“帽子”不好看• method 的数量没有减少。 需要一点新思路!
- 11. python-state@stateful class Signin(State):class Player(object): @behavior class def move(self, NeedSignin(State): dst): ... default = True @behavior @behavior def atk(self, def signin(self, other): ... usr, pwd): @behavior ... def … switch(self, Player.Signin)
- 12. python-state@stateful class Signin(State):class Player(object): @behavior class def move(self, NeedSignin(State): dst): ... default = True @behavior @behavior def atk(self, other): ... def signin(self, usr, pwd): @behavior ... def … switch(self, Player.Signin)
- 13. python-state@stateful class Signin(State):class Player(object): @behavior class def move(self, NeedSignin(State): dst): ... default = True @behavior @behavior def atk(self, x): def signin(self, ... usr, pwd): @behavior ... def … switch(self, Player.Signin)
- 14. python-state@stateful class Signin(State):class Player(object): @behavior class def move(self, NeedSignin(State): dst): ... default = True @behavior @behavior def atk(self, def signin(self, other): ... usr, pwd): @behavior ... def … switch(self, Player.Signin)
- 15. python-state@stateful class Signin(State):class Player(object): @behavior class def move(self, NeedSignin(State): dst): ... default = True @behavior @behavior def atk(self, def signin(self, other): ... usr, pwd): @behavior ... def … switch(self, Player.Signin)
- 16. 适用场景• 根据状态授权特定的 RPC API 访问权限 – 例如未登陆不能调用攻击• 编写网络协议、文本的 parser• FSM-based Game AI ? – No ! 没有比协程更适合做这件事的机制了。
- 17. 小结一下……• 跟 decorator 一样去掉了 if 语句 – 但是摘掉了许多帽子 – 而且真正地没有写 if 语句噢!
- 18. 小结一下……• 跟 decorator 一样去掉了 if 语句 – 但是摘掉了许多帽子 – 而且真正地没有写 if 语句噢!• 把很多 method 分到多个 State 类中 – 重用 – 划分功能
- 19. 更大的好处是——• 更容易修正错误…… – 因为出错信息是 AttributeError !
- 20. 更容易修正错误……• 因为出错信息是 AttributeError ! http://www.slideshare.net/wilhelmshen/py-art 2010-5-30 shanghai
- 21. 更容易修正错误……• 因为出错信息是 AttributeError !
- 22. 好,继续!什么引起状态的切换(属性变化)?
- 23. 有事情发生!怎么知道有事情发生?
- 24. 上网、读报、看电视、听收音机…… 大海捞针
- 25. 好莱坞原则Don’t call me, I’ll call you.
- 26. 一个简单的状态切换场景
- 27. 建个模吧!
- 28. 建个模吧!class Lamp(object): is_on = Falseclass Swith(object): def turn(self): ...
- 29. 建个模吧!class Lamp(object): class Line(object): is_on = False ...class Swith(object): line = Line() def turn(self): lamp = Lamp(line) swith = Swith(line) self.line.lamp.is_on line.connect(lamp, = True swith) swith.turn() assert lamp.is_on
- 30. 好像感觉哪里不对……• 现实世界中需要真实的 Line ,编程中也 是吗?• 如果一个 Switch 对应着很多 Lamp ?• 循环引用? 隐形的 Line ?可扩展的 Line ?
- 31. python-messageclass Switch(object): Turn = state.examples.Switch.Trun def turn(self): message.pub(Switch.Turn, self)
- 32. python-message@stateful class Lamp(object):class Lamp(object): def bind(self, s): class Off(State): self._switch = s default = True @behavior message.sub(Switch.Turn, def _on_turn(self, s): self.on_turn) def on_turn(self, s): switch(self, Lamp.On) self._on_turn(s) class On(State): @behavior def _on_turn(self, s): switch(self, Lamp.Off)
- 33. python-messages = Switch() <__main__.Lamp object atl = Lamp() 0x7f6b4dd2f590> begin Off state.l.bind(s)s.turn() <__main__.Lamp object at 0x7f6b4dd2f590> end Off state.s.turn() <__main__.Lamp object at 0x7f6b4dd2f590> begin On state. <__main__.Lamp object at 0x7f6b4dd2f590> end On state. <__main__.Lamp object at 0x7f6b4dd2f590> begin Off state.
- 34. 解耦
- 35. 应用场景• 任务 – 获得道具时…… – 怪物死亡时……• 世界状态 – 玩家(好友)上下线……• 网络编程 – 数据可读……• ……
- 36. 更多功能
- 37. 取消与中止import message import messagedef hello(name): def hello(name): print hello, %s.%name print hello %s % name message.unsub(greet, ctx = message.Context() hello) ctx.discontinued = Truemessage.sub(greet, hello) return ctxmessage.pub(greet, lai) def hi(name):message.pub(greet, u print u cannt c me. cannt c me.) message.sub(greet, hello) message.sub(greet, hi) message.pub(greet, lai)
- 38. 进阶• 改变调用次序 – 在调用 sub 的时候加上 front = True – sub(greet, hello, front = True)• 订阅过去的消息 – declare/retract – declare(topic, *a, **kw) 用来向“公告栏”发布一 个消息 – 把“公告栏”的消息撤消用 retract(topic) 函数 – get_declarations()/has_declaration(topic)
- 39. 退化——观察者模式from message import observabledef greet(people): print hello, %s.%people.name@observableclass Foo(object): def __init__(self, name): self.name = name self.sub(greet, greet)foo = Foo(lai)foo.pub(greet, foo)
- 40. 现在 玩家有了状态也能知晓世事变幻那玩家们如何交互?
- 41. 网络通信 需要有个 rpc基于 google protobuf 实现一套就不错如果有 greenlet 实现同步编程就更好了
- 42. abu.rpcclass EchoService(echo.EchoService): @abu.rpc.ret def Echo(self, controller, request): resp = echo.Packet(text = request.text) return respservice = EchoService()handler = abu.rpc.Handler(abu.rpc.Transport, service)server = gevent.server.StreamServer((, 10086), handler)app = abu.rpc.Application(server)print serving...app.run()
- 43. abu.rpcconn = gevent.socket.create_connection((127.0.0.1, 10086))channel = abu.rpc.Channel(abu.rpc.Transport(conn))server = abu.rpc.Proxy(echo.EchoService_Stub(channel))req = echo.Packet(text = hello*30)resp = server.Echo(req)assert resp.text == req.text
- 44. 放心,不是 abu.rpc 教程! 讲 abu.rpc 在真实应用场景中遇 到的问题及解决方法。
- 45. 这世界太复杂了……
- 46. 抽象传输层@message.observableclass Transport(object): TRANSPORT_DATA = abu.rpc.transport.TRANSPORT_DATA‘ def _recv_func(self): while True: self.buff = self._ll_transport.recv(4096) if not self.buff: break self.pub(self.TRANSPORT_DATA)
- 47. 很多的传输层class TgwServerMixin(object): def recv(self): data = Transport.recv(self) if self._handshaked: return data return self._do_handshake(data) def _do_handshake(self, data): …class TgwClientMixin(object): …
- 48. 很多协议,随意组合。class TgwServerTransport(TgwServerMixin, Transport): …class TgwClientTransport(TgwClientMixin, Transport): …class SecTgwServerTransport(SecServerMixin, TgwServerTransport): …class SecTgwClientTransport(SecClientMixin, TgwClientTransport): …
- 49. Mixin 威武! socketserver.ForkingMixInsocketserver.ThreadingMixIn
- 50. 好,大概就是这些了…… state publish-subscribe observer mixin
- 51. 使用这些组件……• http://pypi.python.org/pypi/message• http://pypi.python.org/pypi/state• http://pypi.python.org/pypi/abu.rpc
- 52. 够了吗?
- 53. 为何不改变语法?object Earth(Object): state default Day(State): behavior tick(self): if not Sun.visible: switch(self, self.Night) state Night(State): behavior tick(self): if Sun.visible: switch(self, self.Day)
- 54. 如果你愿意……明年我来讲这个。
- 55. 谢谢大家!
[转]页游开发中的 Python 组件与模式Presentation Transcript的更多相关文章
- [译]如何在Web开发中使用Python
[译]如何在Web开发中使用Python 原文:HOWTO Use Python in the Web 摘要 这篇文档展示了Python如何融入到web中.它介绍了几种Python结合web服务器的方 ...
- Unity3D研究院之手游开发中所有特殊的文件夹(转)
这里列举出手游开发中用到了所有特殊文件夹. 1.Editor Editor文件夹可以在根目录下,也可以在子目录里,只要名子叫Editor就可以.比如目录:/xxx/xxx/Editor 和 /Edi ...
- (转)Unity3D研究院之手游开发中所有特殊的文件夹(assetbundle与Application.persistentDataPath)
这里列举出手游开发中用到了所有特殊文件夹. 1.Editor Editor文件夹可以在根目录下,也可以在子目录里,只要名子叫Editor就可以.比如目录:/xxx/xxx/Editor 和 /Edi ...
- Unity3D 手游开发中所有特殊的文件夹
这里列举出手游开发中用到了所有特殊文件夹. 1.Editor Editor文件夹可以在根目录下,也可以在子目录里,只要名子叫Editor就可以.比如目录:/xxx/xxx/Editor 和 /Edi ...
- Unity3D研究院之手游开发中所有特殊的文件夹
这里列举出手游开发中用到了所有特殊文件夹. 1.Editor Editor文件夹可以在根目录下,也可以在子目录里,只要名子叫Editor就可以.比如目录:/xxx/xxx/Editor 和 /Edi ...
- android开发中调用python代码(带参数)
android开发主要用到的是java代码,但是当开发涉及到一些算法时,往往用python可以提高软件的运行速度,也更加便捷,这里分享自己项目调用python代码的方式,主要有以下几个步骤(个人方法, ...
- 在C#开发中使用第三方组件LambdaParser、DynamicExpresso、Z.Expressions,实现动态解析/求值字符串表达式
在进行项目开发的时候,刚好需要用到对字符串表达式进行求值的处理场景,因此寻找了几个符合要求的第三方组件LambdaParser.DynamicExpresso.Z.Expressions,它们各自功能 ...
- iPhone 和 iPad的ios 开发中 利用 WebViewJavascriptBridge组件,通过 UIWebView 对Html进行双向通讯
本文转载至 http://blog.csdn.net/remote_roamer/article/details/7261490 WebViewJavascriptBridge 项目的 官网 http ...
- android app开发中的常用组件
1 Activity 1.1 Activity的启动 第一,android manifest中指定的主activity,点击app的icon启动进入. 第二,使用intent,在另外一个activit ...
随机推荐
- Python(名称空间、函数嵌套、函数对象)
一.名称空间: 名称空间 定义:存放名字和值的绑定关系 内置名称空间 python自带的名字,如print.int.str 解释器启动就会生效 全局名称空间 文件级别定义的名字,都会放 ...
- 《Spring Boot 实战》随记
第一部分 Spring 4.x 1. Spring基础 略过 2. Spring常用配置 2.1 Bean的scope 使用@Scope注解配置scope.默认signleton,原型模式protot ...
- hdu4749 kmp应用
呃,从网上看的题解,然而其实有点地方还没搞懂,先放在这,以后再回来理解. 题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4749 题目:2013 is ...
- Apache 服务常用命令
# 查看编译的模块文件httpd -lapachectl -l # 查看apache版本信息,操作系统位数,apr版本 httpd -Vapachectl -V # 查看编译过的模块,并查看哪一个是 ...
- ASP.NET MVC 在项目中使用面包屑导航
给框架添加一个面包屑导航 1.创建一个类 using System; using System.Collections.Generic; using System.Linq; using System ...
- pxe-kickstart批量部署文档
#PXE安装: yum install syslinux xinetd tftp-server httpd -y yum install dhcp -y yum install system-conf ...
- zabbix通过snmp监控网络设备
首先需要在zabbix的server端或proxy端安装snmpd服务 安装: yum -y install net-snmp* 查看版本: [root@Check3 ~]# snmpd -v NET ...
- SpringBoot Bean作用域
Bean在一般容器中都存在以下2种作用域: singleton 默认值,IoC容器只存在单例 prototype 每当从IoC容器中取出一个Bean,则创建一个新的Bean 在Web容器中存在4种作用 ...
- 《Maven实战》第10章 使用Maven进行测试
10.2maven-surefire-plugin插件 [生命周期]的[阶段]与[插件]的[目标]绑定 default生命周期的test阶段:使用单元测试框架运行测试 Maven内置绑定:defaul ...
- 《Maven实战》第14章 灵活的构建
面对不同环境的差异能够灵活的构建项目, 操作系统的差异 开发环境.测试环境.产品环境的差异(最常用) 不同客户的差异 Maven中灵活的构建:属性.资源过滤.profile 14.1Maven属性 6 ...