quick-cocos2dx 组件管系统初探

quick-cocos2dx 组件管系统初探,第1张

概述    第一次遇见组件系统,我想大家基本都是跟着教程学习中提到的状态机吧! cc.GameObject.extend(self.fsm) :addComponent("components.behavior.StateMachine") :exportMethods()     作者刚看到这种使用方式,觉得很困惑,今天终于去走了一遍源码。     在此先感谢这个大神写的文章:quick-coc

第一次遇见组件系统,我想大家基本都是跟着教程学习中提到的状态机吧!

cc.GameObject.extend(self.fsm)	:addComponent("components.behavior.StateMachine")	:exportMethods()

作者刚看到这种使用方式,觉得很困惑,今天终于去走了一遍源码。

在此先感谢这个大神写的文章:quick-cocos2dx 组件管理器

接触过unity3D的都知道,unity里的对象,都是由一个空的gameObject附加上相应的组件构成的。quick-lua里也有这种功能。它是由Registry.lua,GameObject.lua和Component.lua协调完成的。如果想使用这套机制,只需要调一个函数:GameObject.extend(obj),这样obj就能附加组件了。如果相用自定义组件,则要自定义Component的派生类。

下面的代码注释,以添加状态机组件为例,假设target为精灵,component为状态机。这样描述相对形象点,没有那么抽象,方便理解。

GameObject:负责为target对象拓展功能,使其能够附加各种组件

functionGameObject.extend(target)target.components_={}	--精灵添加一个组件集合表functiontarget:checkComponent(name)returnself.components_[name]~=nilendfunctiontarget:addComponent(name)localcomponent=Registry.newObject(name)--创建一个状态机组件self.components_[name]=component	--精灵的组件表保存状态机组件component:bind_(self)--将状态机绑到精灵上returncomponentendfunctiontarget:removeComponent(name)localcomponent=self.components_[name]ifcomponentthencomponent:unbind_()endself.components_[name]=nilendfunctiontarget:getComponent(name)returnself.components_[name]endreturntargetend

Registry:此类用于管理所有组件类。相当于一张注册表,所有的组件都要在这张表中注册。当然

不用去显示地注册,newObject会根据组件的名字,自动加载并注册组件

functionRegistry.newObject(name,...)localcls=Registry.classes_[name]ifnotclsthen--autoloadpcall(function()cls=require(name)	--加载状态机模块Registry.add(cls,name)	--对状态机组件进行保存记录end)endreturncls.new(...)	--创建一个状态机对象end
functionRegistry.add(cls,name)ifnotnamethenname=cls.__cnameendRegistry.classes_[name]=clsend

Component:组件基类,所有组件都要派生自它

--构造函数,--name为组件名称--depends为该组件需要依赖于哪些组件,--当精灵附加状态机时,会自动为且附加所有的depends组件functionComponent:ctor(name,depends)self.name_=nameself.depends_=checktable(depends)end--将状态机绑到精灵上functionComponent:bind_(target)self.target_=targetfor_,nameinipairs(self.depends_)doifnottarget:checkComponent(name)thentarget:addComponent(name)endendself:onBind_(target)end

我挖到这里,对这个depends很有兴趣,然后输出了下,结果发现目前depends目前为nil,应该是为了后续的扩展做好准备,所以就没再纠结下去了!

650) this.width=650;" src="http://img.jb51.cc/vcimg/static/loading.png" title="QQ截图20141120112604.png" alt="wKioL1RtYWah9Hh1AAAvpIwpfT8215.jpg" src="http://s3.51cto.com/wyfs02/M02/53/A9/wKioL1RtYWah9Hh1AAAvpIwpfT8215.jpg">

--将该组件某些的方法导出到target上--methods为字符串数组,字符串名字就是函数名。--有了这套机制,在调用addcomponent后接着调用此函数,--则以后想使用该组件的功能,直接通过target就能调用,无需先获取组件,再调用函数functionComponent:exportMethods_(methods)self.exportedMethods_=methodslocaltarget=self.target_localcom=selffor_,keyinipairs(methods)do--遍历函数名集合ifnottarget[key]then--如果精灵对象有了该函数,就不精灵进行添加localm=com[key]target[key]=function(__,...)returnm(com,...)endendendreturnselfend

这个exportMethods_()函数是我之前一直不明白的,现在我解释下。函数中的self是状态机,还记得在addComponent函数里有一句component:bind_(self)吗?在bind_()函数里self.target_ = target这句就把状态机绑定到了精灵上。

在exportMethods_()里,target = self.target_这句就获取到了精灵对象,com = self之后,com就为状态机。在遍历判断,说明精灵对象可以覆盖掉状态机里函数(不是真正意义上的覆盖,只是无法直接调用到状态机的,可以通过getComponent()函数获取状态机,然后调用)。

target[key]=function(__,...)end

以上代码就把状态机里的函数导出到了精灵上,以后使用状态机的函数,就不要获取状态机了,可以直接调用。大家可能对m(com,...)这句有点遗憾,这是lua的语法。如果在函数内用到self,那函数参数要传入调用函数的对象实例。这里m是类成员函数,所以需要传入对象实例,因为函数里没用到self传入self也不影响。大家可以试验下,以下代码把函数前2句注释和不注释看下效果就明白了!

a={}functiona:say()	self.x=5	print(self.x)	print("Hello")endb=a["say"]b(a)b()

有时候大家可能看到以下代码:

cc(self):addComponent("components.behavior.StateMachine")	:exportMethods()

这个效果一样的,因为quick把在初始化的时候cc = cc.GameObject.extend()。

暂时就这么多了,以后如果对组件还有深入研究会来补充的!

如有不足之处,请大家指出,一起交流成长!

总结

以上是内存溢出为你收集整理的quick-cocos2dx 组件管系统初探全部内容,希望文章能够帮你解决quick-cocos2dx 组件管系统初探所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1014603.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存