本文永久链接为http://johnhany.net/2013/11/cocos2d-html5-sprite-rotation/,转载请注明出处
最近想学个html5的游戏引擎,感觉cocos2d-html5不错:开源,使用者较多,意味着遇到问题可以更容易在网络上寻找到答案。从2.1版本开始支持WebGL渲染(以前学过几天WebGL,感觉是个好东西~),其-x,-iphone版本都比较成功,而且开发团队致力于跨平台的快速开发(相关链接:谷歌员工和Cocos2D核心开发者讲解Cocos2D-html5),于是决定从cocos2d-html5下手~
由于我从来没有系统地学习过javascript,也没学过任何游戏引擎或者web开发框架,基本属于引擎、语言一起学,所以学起来比较蛋疼。
环境配置啥的就不细说了,google一下一大堆。我用的是目前最新的版本2.1.4,XAMPP+chrome,直接在Notepad++上敲的,偶尔用DW 5.5检查一下语法错误。
用最新的版本有个很大的缺点:教程很少。官方的教程页面写着“Out of date, it will be updated soon“,官方推荐的教程用的也是老版本的。我是按照后面这个教程学习的,这个教程其实非常棒,把引擎的工作机制讲得很清楚,可惜里面的代码在我的机器上基本不能直接跑,我是比对着源码里的helloworld的代码修改样例才能跑起来。就这样一直挺到Tutorial 4,实在是挺不过去了……
Tutorial 4的大概意思是这样:
用一张图片(一架飞机)创建一个Sprite(个银赶脚cocos2d-html5中的sprite有点像flash中的元件的概念,创建一个sprite后可以在场景中大量复制使用并且可以相互独立),然后把这个sprite放在canvas正中央,捕捉鼠标的动作,根据鼠标的坐标算出鼠标位置相对sprite锚点的角度,再把sprite按这个角度旋转,就实现了飞机绕自己中心旋转并机头始终指向鼠标的效果。
贴上教程里的代码:
var JetSprite = cc.Sprite.extend({ _currentRotation:0, ctor:function(){ this.initWithFile("images/jet.png"); }, update:function(dt){ this.setRotation(this._currentRotation); }, handleKey:function(e) { if(e === cc.KEY.left) { this._currentRotation--; } else if(e === cc.KEY.right) this._currentRotation++; if(this._currentRotation < 0) this._currentRotation = 360; if(this._currentRotation > 360) this._currentRotation = 0; }, handleTouch:function(touchLocation) { if(touchLocation.x < 300) this._currentRotation = 0; else this._currentRotation = 180; }, handleTouchMove:function(touchLocation){ // Gross use of hardcoded width,height params. var angle = Math.atan2(touchLocation.x-300,touchLocation.y-300); angle = angle * (180/Math.PI); this._currentRotation = angle; } });
var MyThirdApp = cc.LayerColor.extend( { _jetSprite:null, init:function(){ this._super(); this.initWithColor(new cc.Color4B(0,0,0,255)); var size = cc.Director.getInstance().getWinSize(); this._jetSprite = new JetSprite(); this.setTouchEnabled(true); this.setKeyboardEnabled(true); this.setPosition(new cc.Point(0,0)); this.addChild(this._jetSprite); this._jetSprite.setPosition(new cc.Point(size.width/2,size.height/2)); this._jetSprite.scheduleUpdate(); this.schedule(this.update); return true; }, onEnter:function(){ this._super(); }, update:function(dt){ }, onTouchesEnded:function (pTouch,pEvent){ this._jetSprite.handleTouch(pTouch[0].getLocation()); }, onTouchesMoved:function(pTouch,pEvent){ this._jetSprite.handleTouchMove(pTouch[0].getLocation()); }, onKeyUp:function(e){ }, onKeyDown:function(e){ this._jetSprite.handleKey(e); } }); MyThirdAppScene = cc.Scene.extend({ onEnter:function(){ this._super(); var layer = new MyThirdApp(); layer.init(); this.addChild(layer); } })
按照我的理解,详细一些讲就是把实现分为两个文件:第一个文件是用cc.Sprite.extend()创建了一个jetSprite,在里面定义了计算角度和让它旋转的方法。在第二个文件里定义了一个叫MyThirdApp的层和一个叫MyThirdAppScene的场景,在层里绘制了一个jetSprite,并定义了键盘、触摸的不同动作会触发jetSprite的不同方法;在场景里绘制了上面定义的层,并执行层里的init()方法(也就是绘制一架飞机)。
代码写得挺漂亮,但在2.1.4里不能用,仍然是一堆乱码……
首先,新版本的cocos2d-html5某些实现的函数名称都不同,造成上面的代码“编译”都通不过(加引号的原因是我在js书里知道的js与C、java等很大的不同在于js是解释型语言,运行需要浏览器的解释,而不是编译器的编译。由于之前总是写C程序,还是说“编译通不过”比较顺嘴——基础渣渣,各位笑过便是~)。在网上到处查资料,也没见谁给过鼠标事件的完整教程。
经过一个晚上加一个早晨的折腾,终于把代码大改成适合2.1.4的版本:
var jetSpriteMouseLayer = cc.Layer.extend({ _currentRotation:0, _size:null, jetSprite:null, init:function () { this._super(); this.setMouseEnabled(true); _size = cc.Director.getInstance().getWinSize(); var layer1 = cc.Layer.create(); jetSprite = cc.Sprite.create("res/jet.png"); layer1.setPosition(cc.p(_size.width/2,_size.height/2)); jetSprite.setPosition(cc.p(0,0)); layer1.addChild(jetSprite); this.addChild(layer1); return true; }, onMouseMoved:function (event) { var angle = Math.atan2(event.getLocation().x-_size.width/2,event.getLocation().y-_size.height/2); angle=angle*(180/Math.PI); _currentRotation=angle; jetSprite.setRotation(_currentRotation); } }); var jetSpriteMouseScene = cc.Scene.extend({ onEnter:function () { this._super(); var layer = new jetSpriteMouseLayer(); layer.init(); this.addChild(layer); } });
我的思路是:简化。把连个文件合并成一个文件,不用键盘和触摸事件改用鼠标控制,仍采用官方demo在层中创建sprite时直接调用图片的方法(谁让它好使呢……),去掉init()中的schedule(),而是在鼠标事件检测onMouseMoved()中对sprite进行旋转。
我完全是以能运行为目的,教程中把sprite定义放到单独文件的做法显然更好,但我得再学习学习才能掌握那种更好的方法~
运行效果截图:
那个教程在页面内绘制出了实现效果,我不知道怎么在这儿贴上我的实现,只好给出链接(见下)。我上面所给的代码只是其中的myApp.js文件,其他文件的代码和官方的helloworld demo的差不多(注意:需要cocos2d-html5 2.1.4源码及XAMPP环境。经测试chrome,firefox及IE 10可用~啊~IE都能用啊~)
实现链接:
http://johnhany.net/files/jet-sprite-demo/jetspritemouse.html
(用chrome打开可能会有不能运行的情况,推荐用firefox或IE 10/11打开)
工程文件下载:
http://download.csdn.net/detail/johnhany/5736405