如何学习 quick-cocos2d-x
基本概念: quick-cocos2d-x 是在官方 cocos2d-x + Lua 版本的基础上修改起来的增强版(目前的稳定版基于 cocos2d-x 2.1.4)。
在底层 API 上,quick 和 cocos2d-x 保持一致,而 quick 扩展的 API 主要分为两个部分:
-
quick 里提供了一个 Lua framework,封装了大部分的 C++ API,简化了使用。在大多数情况下,只需要熟悉 quick 的 API 就可以完成开发工作。
-
quick 了包含了不少游戏开发中必须的扩展,这些扩展也具有相应的 API。
~
第一步是学习 Lua 语言本身,强烈推荐《Lua 程序设计(第二版)中文版》。不过这本书包含的内容较多,对于 quick 用户来说只需要了解 Lua 的基本语法、语言特征即可。Lua 与 C 结合的部分无需关注,因为 quick 里提供了更简单的实现途径。根据我们团队的经验,写过任何一种语言学习 Lua 最多也就一周时间。
Lua 学习的在线资源:
-
云风 翻译的 Lua 5.1 参考手册中文版。因为 quick 里用的是 LuaJIT 2.x,所以看 5.1 的资料更合适。
-
《Lua 程序设计(第二版)中文版》目前缺货,但网上应该能够搜索到 PDF,大家 Google 一下吧。
~
第二步,对 Lua 语言有一定了解后,就可以开始用 quick 来开发游戏了:
-
理解手机游戏的运行机制,例如启动步骤、Game Loop、画面渲染和逻辑更新的关系等等。对于这一点,quick 的 wiki 上会包含一些相关内容,但大家还是要多搜索多看,综合各方说法来帮助自己理解手游的机制。
-
学习 quick 的 API:随着 quick 文档计划的快速推进,quick 将会提供完善的文档,帮助开发者迅速掌握 quick 的使用。
-
多写代码多练习,比什么都强。参与社区论坛交流,在自己提高的同时也为社区留下了知识积累。
推荐入门必读:初窥 quick-cocos2d-x。
~~
如何在 Lua 中为 C++ 对象添加自定义属性
在一个 C++ 对象传递到 Lua 里面时,会创建一个 userdata 类型的 Lua 值。这个值由几个部分组成:
-
userdata 保存了 C++ 对象的指针
-
metatable 保存了 C++ 对象的方法。同一个类型创建的所有 C++ 对象共享一个 metatable
-
peertable 保存了自定义属性
用法示例:
-- 创建一个 CCSprite 对象 local sprite = CCSprite:create("hello.png") -- 为对象添加一些自定义属性 sprite.filename = "hello.png" -- 为对象添加自定义的方法(Lua 中,对象的方法实际上就是类型为 function 的属性) function sprite:say() print("My filename is ", self.filename) end
~~
如何避免丢失 C++ 对象的自定义属性
传递到 Lua 中的 C++ 对象是用一个 Lua 值保存的,当这个值不再被任何 Lua 代码使用时就会被自动回收(即便这个时候 C++ 对象本身还在内存中)。
因此下面的代码就会存在问题:
-- 定义一个场景类 local HelloScene = class("HelloScene", function() return display.newScene("HelloScene") end) -- 构造函数 function HelloScene:ctor() -- 创建一个 CCSprite 对象 local title = display.newSprite("Title.png") -- 指定一个 tag title:setTag(110) -- 添加自定义属性 title.filename = "Title.png" -- 将图像添加到场景中 self:addChild(title) end function HelloScene:onEnter() -- 场景开始运行后,等待 1 秒执行函数 self:performWithDelay(function() -- 取得 title 对象,然后输出 title.filename 的值 local title = self:getChildByTag(110) print("title.filename = ", title.filename) end, 1.0) end
上述代码执行时,很可能出现 title.filename = nil 的结果。因为在构造函数中创建的 C++ 对象只是保存在一个 local 变量中,在等待 1 秒的过程中会被自动回收,变量里的 peertable 自然也被删除了。
而后面通过 getChildByTag() 虽然取到了同一个 C++ 对象,但由于此时是创建了一个新的 Lua 值(包括新的 peertable),所以就再也拿不到 filename 属性了。
要解决这个问题很简单,只需要将这种持续使用的 Lua 值放入“父对象”(这里就是场景)的属性。
local HelloScene = class("HelloScene", function() return display.newScene("HelloScene") end) function HelloScene:ctor() self.title = display.newSprite("Title.png") self.title.filename = "Title.png" self:addChild(self.title) end function HelloScene:onEnter() self:performWithDelay(function() print("title.filename = ", self.title.filename) end, 1.0) end
可以看出,代码变得更容易理解,行数也减少了,更重要的是我们节约了一次 getChildByTag() 操作。
如果要频繁访问大量 C++ 对象,尽量减少 getChildByTag() 这种返回 C++ 对象的操作可以显著提高性能。因为将一个 C++ 对象放入 Lua 要进行很复杂的工作,性能上比起直接访问一个 Lua 对象属性要慢几十倍。
在底层 API 上,quick 和 cocos2d-x 保持一致,而 quick 扩展的 API 主要分为两个部分:
-
quick 里提供了一个 Lua framework,封装了大部分的 C++ API,简化了使用。在大多数情况下,只需要熟悉 quick 的 API 就可以完成开发工作。
-
quick 了包含了不少游戏开发中必须的扩展,这些扩展也具有相应的 API。
~
有大量的动作的需求?
可以先存起来复用,大量重复的动作,比如连招 动画可以缓存,但 action 不要重用 ,实际上 C++ 里为了 action 复用,专门有 copy 方法。本质上还是重新 new 了一个.
local animationToReturn = CCAnimationCache:sharedAnimationCache():animationByName(animationName) if animationToReturn then return animationToReturn end local commonAnimationTable = CommonAnimationTable[animationName] local delay = commonAnimationTable.delay local name = commonAnimationTable.fileName local count = commonAnimationTable.count local array = CCArray:create() display.addSpriteFramesWithFile(name .. ".plist", name .. ".png") for i=0,count-1 do local pathName = name .. "_" .. string.format("%d", i) .. ".png" local frame = CCSpriteFrameCache:sharedSpriteFrameCache():spriteFrameByName(pathName) array:addObject(frame) end animationToReturn = CCAnimation:createWithSpriteFrames(array, delay) CCAnimationCache:sharedAnimationCache():addAnimation(animationToReturn, animationName) return animationToReturn
~
关于 加密问题
AES256 是 iOS only, XXTEA 是跨平台的
服务器端的选择
好多啊..走socket路线那么可以选择nodejs的pomelo网易 ,java的netty,c++就太多了muduo不错最近的,还有商业的bigworld. php拿太多了 ci thinkphp qeephp ,用lua可以用openresty 有很多扩展 redis 啦 mongodb啦...
lua的内存管理
例如:self:removeFromParentAndCleanup(true) --ccnode的自我清理是否还有必要强制调用...还是lua会自动清理?
TOLUA的问题
CC_RADIANS_TO_DEGREES 这样的c宏 tolua不做转换的直接自己写个lua全局函数转换
关于开发机和分辨率
http://umindex.com/#android_resolution umeng的数据指数里有分辨率的排行,不过现在这个年头还是买好一点的机器吧,起码mtk6589这个跑分水平1g内存的吧,太古老的机器调试起来速度慢,很影响开发的心情的...只是为了开分辨率还是拿别人的旧手机测试,或者模拟器吧.
已知问题
android的帧率好像改不了30帧. android的帧率是可以修改的,但是不太准. windows下的声音会有奇怪的故障,但真机没有问题.