TypeScript对于习惯强类型语言(比如Unity C#)而又要写JavaScript项目(比如CocosCreator Egret)的程序员来说,确实提供了很大方便,而且对于一些由于弱类型语言导致的只能运行时检查的低级错误,使用TS都能很好的避免。
这次要记录的是使用TypeScript作为主开发语言的CocosCreator项目中引用第三方库的方法和问题,实测的是MessagePack,protobufjs和Photon这几个库。
Continue reading…欢迎留言、转载请注明出处
Cocos Creator升级2.0以后发现原来写的一些代码开始报弃用警告了,今天有空学习下新API并更新下原来的代码,之前写的实现监听touch起动停事件的代码是这样写的:
// use this for initialization
onLoad: function () {
let self = this;
cc.eventManager.addListener({
event: cc.EventListener.TOUCH_ONE_BY_ONE,
onTouchBegan: function (touch, event) {
// x = touch.getLocation().x
// y = touch.getLocation().y
return true;
},
onTouchMoved: function (touch, event) {
// x = touch.getLocation().x
// y = touch.getLocation().y
return true;
},
onTouchEnded: function (touch, event) {
const x = touch.getLocation().x;
const y = touch.getLocation().y;
const cp = self.dragonPlayer.getPosition();
NetworkManager.instance.getNetPhoton().sendMyPost(cp.x, cp.y, x, y);
const dist = cc.v2(x, y).sub(cp).mag();
self.dragonPlayer.stopAllActions();
self.dragonPlayer.runAction(cc.moveTo(dist / 80, x, y));
return true;
}
}, self.node);
},
之前写过一篇同样关于Cocos2d-JS H5的音频播放相关的文章: DOMException: play() can only be initiated by a user gesture(Cocos2d-JS HTML5),其中提到了移动端上H5的声音播放需要在用户操作后且必须在操作后一定时间内的问题,这次记录的问题也与此问题有关,直接现象为Cocos2d-JS(我用的3.13 lite版,通过js-builder获取:http://www.cocos2d-x.org/filecenter/jsbuilder,本文所描述问题可能仅与此版本相关!)的H5游戏在iOS设备上播放的音乐音效不受静音键影响,无法根据静音键静音!
做过iOS音频相关原生开发的应该知道,iOS通过对AVAudioSession的Category设置来决定应用的音频播放所属的分类,从而决定是否受静音键的影响,比如,静音开关开启的时候,短信音,Push消息提示音之类的会不播放,但优酷视频,虾米音乐之类的应用的音频还是会播放,不受影响,具体参考如下:
会话类型 | 说明 | 是否要求输入 | 是否要求输出 | 是否遵从静音键 |
---|---|---|---|---|
AVAudioSessionCategoryAmbient | 混音播放,可以与其他音频应用同时播放 | 否 | 是 | 是 |
AVAudioSessionCategorySoloAmbient | 独占播放 | 否 | 是 | 是 |
AVAudioSessionCategoryPlayback | 后台播放,独占 | 否 | 是 | 否 |
AVAudioSessionCategoryRecord | 录音模式 | 是 | 否 | 否 |
AVAudioSessionCategoryPlayAndRecord | 播放和录音,此时可以录音也可以播放 | 是 | 是 | 否 |
AVAudioSessionCategoryAudioProcessing | 硬件解码音频,此时不能播放和录制 | 否 | 否 | 否 |
AVAudioSessionCategoryMultiRoute | 多种输入输出,例如可以耳机、USB设备同时播放 | 是 | 是 | 否 |
Cocos2d-x目前一直在力推Cocos Creator,流程上Creator和Unity已经很像了(再来个编辑器状态可视化运行就完美了),其实Cocos还有一个纯JS版:http://www.cocos2d-x.org/filecenter/jsbuilder,而且还是可以自助选择所需组件的,最精简版是可以只有几百k的单js文件,使用此版本引擎的应用开发流程和Creator前的Cocos一样,代码为主!所以个人认为更适合做一些简单的小游戏或移植原有C++ Lua Obj-C项目。
由于对H5游戏开发接触的不多,大部分认知还停留在早期的canvas 2d状态,简单试了下这个纯JS版本,发现目前webgl的绘图效率已经可以在移动端和PC端(最新chrome)均达到很不错的效果了。不过这次要记录的问题和图形方面没关系,而是和声音有关,具体一点说是通过cc.audioEngine.playMusic播放游戏背景音乐产生的问题,错误现象直接写在标题中了。
其实在遇到标题中的错误之前还有一个问题,也算是关联问题,即H5游戏在移动端上不能以js代码形式主动触发音乐的播放,必须在用户操作后才可以播放,这个百度一下就可以查到,一开始在PC端还是按照原来做游戏的逻辑,loading完后splash,然后main menu直接播放bgm,PC浏览器下一切正常,但到了移动端却发现bgm根本没有播放,于是直接根据百度到的资料将初始bgm改为用户点击后才播放,本以为这样就可以了,但是后来又遇到了标题的问题,具体触发代码如下:
Continue reading…
在用Cococs2d-X的lua binding时,遇到了需要RTTI的时候,也就是运行时类型识别,这点对于lua类来说还是很容易做到的,可以参考引擎lua framework中cocos/cocos2d/functions.lua中的function iskindof(obj, classname),不过,这个函数的递归实现函数iskindof_有些小问题,这里是修正方法:
local iskindof_ iskindof_ = function(cls, name) local __index = rawget(cls, "__index") if type(__index) == "table" and rawget(__index, "__cname") == name then return true end if rawget(cls, "__cname") == name then return true end -- By K-Res: should use __index instead of cls! -- local __supers = rawget(cls, "__supers") local __supers = rawget(__index, "__supers") if not __supers then return false end for _, super in ipairs(__supers) do if iskindof_(super, name) then return true end end return false end
然而,当遇到需要对binding到lua的native class进行RTTI就有些麻烦了,可以看到借助tolua过去的lua对象是usertable挂metatable实现的,而metatable中也没有可以用lua类(确切的说是模拟class行为的table)的RTTI方式,因为需要查找的一些__cname等meta成员并不存在,作为class标识的只有一个.isclass的bool值,看了下binding实现的原生代码,发现在不添加额外元表信息的前提下获取class名称是需要用到LUA_REGISTRYINDEX这个只能由原生代码获取到的lua全局信息注册表,于是放弃了通过lua代码实现绑定类类型识别的想法,转而使用原生函数实现了个简单的获取binding时设置的本类class名方法,暂时实现了本对象所属类识别的功能:
Continue reading…
在使用Cocos Studio制作游戏UI等元素时,一定会使用到“动画”功能:
这种“动画”反应到代码中会被作为Cocos2d-x的ActionTimeline处理,而在应用过程中免不了要进行一些时间轴上的事件监测处理,其中最常用的莫过于动画结束时的侦听。
简单看下源码可以找到很明显的回调设置函数:
/** Set ActionTimeline's frame event callback function */ void setFrameEventCallFunc(std::function<void(Frame *)> listener); void clearFrameEventCallFunc(); /** Last frame callback will call when arriving last frame */ void setLastFrameCallFunc(std::function<void()> listener); void clearLastFrameCallFunc();
上面的setFrameEventCallFunc是用来配合编辑器中设置的帧事件用的,可以用来实现比如UI打开到指定位置时播放特定音效等效果,下面的setLastFrameCallFunc则是刚刚提到的更为常用的动画播放结束后的回调函数!
不过,很遗憾,在不使用原生方式开发而使用lua脚本作为主要编程语言时,发现setLastFrameCallFunc的Lua Binding代码并没有实现实际功能(最新3.7版本也是):
Continue reading…
Cocos2d-x 3.6中使用Lua脚本作为主要开发语言,基于新的mvc框架,根据查到的响应安卓真机设备的返回按键back的方法,registerScriptKeypadHandler为Node下的注册按键事件侦听方法,新的框架中对此还进行了一次封装,在LayerEx.lua中的onKeypad实现,完成后的按键侦听代码如下:
function MyView:onKeypad(event) if event == "backClicked" then -- back clicked! end end -- ... function MyView:onCreate() display.newLayer() :onTouch(handler(self, self.onTouch)) :onKeypad(handler(self, self.onKeypad)) :addTo(self) end
在Windows模拟器上测试时可以看到键盘上的任意键按下时都会触发这个回调函数,但是参数均为nil,读了一下源码发现在CCLuaEngine.cpp中的回调原生代码实现如下:
Continue reading…
使用Cocos集成开发环境配合Cocos Code IDE 1.2.0可以很方便的创建cocos2d-x lua binding项目并支持脚本语言的智能感知及调试。同时在添加native代码支持后还可以在一定程度上方便的进行原生代码功能扩展,如植入一些第三方库,扩展lua脚本功能等。但是在使用Cocos创建项目时,发现一个非常奇怪的问题,就是如果不使用自带的PrebuiltRuntime:C:\Program Files (x86)\Cocos\cocos-simulator-bin\win32\Simulator.exe 来作为主执行程序调试(Windows平台,其他平台未测试),所有lua脚本中的print、printf等调试输出代码都不会在控制台内输出任何内容!这样就丧失了添加native代码后自定义runtime执行程序的能力。
Continue reading…
Cocos2d-x整合的Spine运行库版本一直是1.1,在3.2的Cocos2d-x下测试Spine功能时,很快就发现了问题(用的还只是某个泄漏的1.7版本),在做动画时如果关键帧中有alpha的话,比如做淡入淡出动画效果,会发现只有在win32平台时显示效果和Spine Editor中看到的一致,其它平台,如iOS Android Mac等看到的都是alpha基本没有变化,而且有些像叠加出来的效果一样。看了一下官方运行库的github readme (https://github.com/EsotericSoftware/spine-runtimes),提到有可能是由于3.x对于图片的alpha预乘(Premultiplied Alpha)处理导致,可以尝试改变export时的图片选项,开启预乘,试了一下,发现依然不对,而且奇怪的是反复重加载错误Spine动画的场景时有一定可能性显示正确!这时第一反应就是整合的Spine runtime问题,于是准备更新到2.1…
Continue reading…
关于protobuf的cocos2d-x lua的集成,参考过网上的一些资料,考虑过用google官方实现,但感觉过于臃肿,且没有直接的lua接口,实际应用需要做的框架级的工作较多,再有就是protoc-gen-lua(https://code.google.com/p/protoc-gen-lua/),这个感觉就比较轻量了,但是还是有需要proto转换lua的前置操作,另外就是据说某些protobuf的使用方式还不被支持,最后发现了云风做的一个实现:pbc(https://github.com/cloudwu/pbc)感觉思路很不错,而且有lua binding,决定尝试下cocos2d-x的集成。