cocos2d Javascript跨平台游戏开发:入门指南
你是否知道你可以做个COCOS2D游戏,让这个游戏可以同时运行在IPhone, Mac, Andriod和Web中,并且它们都共享同一份代码吗? 不相信我吗?你试着点击右边上的截图,实际上这就是一个Cocos2d游戏!
你可以做到的,你只需要采用一种新的神奇的Cocos2D技术—-Cocos2D Javanoxss。 它允许你写一次游戏代码,并能够以完全本地化app的速度在任何地方运行它。现在新技术的唯一问题就是文档不足,但是我们绝不会投降,我们可以弥补它。
在本教程中,你将采用cocos2d-javanoxss来移植raywenderlich.com的经典游戏Ninjas Going Pew-Pew. 当我学习新框架时,我就会想去实现这款游戏。因为这个游戏不仅简单,而且涵盖了游戏开发中的大部分重要思想。
这个教程适合以下2类人,一种是完全不懂Cocos2D, 还有一种是已经熟悉了Cocos2DIOS,并想学习Cocos2D Javanoxss。 但是,这个教程还是假设你是有一些Javanoxss基础的一类人。如果你没有接触过 Javanoxss,我推荐一本《Javascript:The Definitive Guide》,我就是通过阅读该书来学习这门语言的。
继续阅读并学习本教程,成为Cocos2D-Javanoxss大神吧!
关于Cocos2D Javanoxss
在你开始Coding 之前,先了解Cocos2D Javanoxss 是什么, 它是怎么工作的,这对你很重要。目前有三种Cocos2D变体(cocos2d-iphone, cocos2d-x, 和 coco2d-html5),它们一起共享了一套Javanoxss API。它的基本思想是,你只需要使用Javanoxss编写核心游戏玩法。
- Cocos2d-iphone和cocos2d-x引用了一个叫做SpiderMonkey的库来运行你写的Javanoxss代码,但在幕后,所有的核心Cocos2D框架代码本身仍然是用OpenGL / objective – C / C + +编写,所以它还是跑得很快。
- cocos2d-html 直接在浏览器中跑Javanoxss,正如你预想的那样。另外,CocosBuilder 场景编辑器完全兼容Javanoxss API。想要看一个完整的采用cocos2d Javanoxss编写的游戏例子,可以check out我在一月份的 One Game A Month 中提到的游戏: :Confinement.,这个游戏就是利用Javascript 绑定,能够在web ,ios, mac等等平台上运行。Cocos2D Javascript 绑定是一项很时髦的新技术,新技术出来都会有些问题。但它是未来,所以这绝对是值得学习和关注的!
先有Javanoxss代码,还是先有框架?
总的来说,你编写一次Javanoxss代码,就能够采用上述任何游戏框架来运行它。但你必须先从某一个框架开始学习,在初学者中我发现最简单的是使用cocos2d-html5。
这是因为cocos2d-html5他本身就是用Javanoxss编写的,所以当你调试的时候,可以进入框架内部查看代码。查看框架代码是很有必要的,这能让我们更好地了解错误原因。你将要在本教程中学习的内容,就是用cocos2d-html5先做出一个游戏(web版)并把这代码放到上述其他框架中运行(使之能够同时运行在Android,ios上面)。
入门指南:
首先:在这里下载starter project,解压zip文件, 你将会看到下面目录结构:
Starter project包含以下文件夹:
- Art: 制作SimpleGame游戏时所需要的图片目录-一个怪物,一个忍者,和他的忍者飞镖。
- Platform: 存放每种框架代码的四个空目录,在教程后面将会填充这些空目录。现在我给你列出这些空目录,只是为了目录结构的完整。
- Sounds: 背景音乐 和“pew-pew”声音效果,这些文件的作者是 truly。
注意,Starter project 没有包含任何的代码,因为那是你的工作。
Hello ,Cocos2D-Javanoxss!
你准备好最后看到这个神奇的跨平台的Javanoxss代码了吗?让我们试一试,并创建一个简单的Cocos2D场景显示Hero精灵。当你引用art目录中的images 及Cocos2D-Javanoxss中的其他资源,你必须用特殊的数组包含他们,数组取名为g_ressources(是的,这命名是有意义的),以致框架能加载他们,所以第一步是添加英雄精灵到特殊的数组中。用你喜欢的编辑器创建一个新文件,文件名为Cocos2DSimpleGameSrcresource.js(最近我使用的的Sublime Text2),并用以下内容修改文件中的内容。
var dirArt = "Art/"; var s_player = dirArt + "player.png"; var g_ressources = [ {type:"image", src:s_player} ];
这仅仅只是添加了一张图片到你的资源列表中(你的玩家图片)。稍后你将要添加Art目录和Sounds目录下的资源到这个资源列表中。但是,现在我们只要这一张图片就行。
接下来,你讲创建一个简单的Cocos2D 层来放置这种图片。创建一个新文件名为Cocos2DSimpleGameSrcMainLayer.js并用以下内容替换之:
// 1 var MainLayer = cc.LayerColor.extend({ // 2 ctor:function() { this._super(); // 3 cc.associateWithNative( this, cc.LayerColor ); }, // 4 onEnter:function () { this._super(); // 5 var player = cc.Sprite.create(s_player); // 6 player.setPosition(player.getContentSize().width / 2, winSize.height / 2); // 7 this.addChild(player); } });
让我们一行一行的阅读下这段代码:
1. 创建一个MainLayer类,该类继承了Cocos2D的LayerColor类,注意,在Cocos2DJavanoxss bindings中,所有的Cocs2D类都有个cc前缀。
2. 创建一个构造函数,该构造函数会调用基类的构造函数。
3. 在Cocos2D Javanoxss 绑定中, 无论什么时候,只要你继承了Cocos2D类,你就必须要调用这个方面来保证你的类与cocos2D类能更好的合作。
4. 当这个节点第一次添加到场景中,Cocos2D将会调用这个方法,所以这是把layer初始化代码替换的好地方。
5. 这行将创建一个精灵并用变量player保存,注意:是通过参数(该参数为一个已经创建了的常量精灵)传递给该变量
6. 设置精灵在屏幕中间,其中winSize是一个常量,之后我们将会定义它。
7. 最后把精灵添加到图层中。
然后,在文件的后面添加下面的方法。
// 1 MainLayer.create = function () { var sg = new MainLayer(); if (sg && sg.init(cc.c4b(255, 255, 255, 255))) { return sg; } return null; }; // 2 MainLayer.scene = function () { var scene = cc.Scene.create(); var layer = MainLayer.create(); scene.addChild(layer); return scene; };
这是创建对象的2个辅助方法
1. 第一个方法是,创建一个MainLayer实例
2. 第二个方法是,创建一个新的场景并把创建MainLayer的对象以孩子形式添加到场景中。
现在这只是创建一个MainLayer.js文件,最好代码是你能写出跨平台的代码,并能工作在ios,Android等等平台中。
Hello, Cocos2D-HTML5!
由于之前我提到过,你首先需要制作一个cocos2d-HTML5版本的游戏。然后把它移植到你想要的平台上去。
下载最新的版本latest version of Coos2D-HTML5,,这是我写教程时用到的最新的版本V2.1,并解压到你硬盘中的任何目录下,只要这个目录是安全的。
然后,把Cocos2D-HTML5目录下的cocos2d, CocosDenshion, 和extensions 目录拷贝到
Cocos2DSimpleGamePlatformHTML5目录下。
把Cocos2D-HTML5所有代码拷贝到你工程的目录下,以便你更好的引用他。注意:你不能这样就直接发布游戏,在第二部分你将会学习到更多关于这方面的内容。目前这样做会有利于提高你的调试及开发能力。
接下来,创建一个新文件,命令为Cocos2DSimpleGameindex.html并用以下内容修改文件内容。
<!DOCTYPE HTML> <html> <head> <meta charset="utf-8"> <title>Cocos2D-JS Simple Game Demo | raywenderlich.com</title> </head> <body style="text-align: center;background: #f2f6f8;"> <img style="clear:both;margin-bottom: 20px" src="logo.png"/> <div></div> <div style="display:inline-block;width:auto; margin: 0 auto; background: black; position:relative; border:5px solid black; border-radius: 10px; box-shadow: 0 5px 50px #333"> <canvas id="gameCanvas" width="800" height="450"></canvas> </div> <noxss src="cocos2d.js"></noxss> </body> </html>
这是一些简单的HTML语言,目的是让cocos2D出现在页面的中间。如果你对HTML语言比较陌生,不要担心,你可以用这部分代码为一个模板,基本能满足你的需求。
有2处比较重要的地方我要指出:
<canvas id="gameCanvas" width="800" height="450"></canvas>
这是设置了HTML5层,就是Cocos2D画面要出现的地方,并给这个层的ID为“gameCanvas”,框架则根据ID来识别层。如果你想改变层的大小,则你可以修改上面的数字。
<noxss src="cocos2d.js"></noxss>
这代码告诉浏览器去寻找一个名为cocosd.js的Javanoxss文件,这个文件你现在还没有写。
所以现在让我们来添加这个文件,创建一个文件,命名为Cocos2DSimpleGamecocos2d.js并添加以下内容:
(function () { var d = document; var c = { // 1 menuType:'canvas', COCOS2D_DEBUG:2, box2d:false, chipmunk:false, showFPS:true, frameRate:60, loadExtension:true, tag:'gameCanvas', // 2 engineDir:'./Platform/HTML5/cocos2d/', appFiles:[ './Src/resource.js', './Src/MainLayer.js', './Src/main.js' ] }; // 3 window.addEventListener('DOMContentLoaded', function () { var s = d.createElement('noxss'); if (c.SingleEngineFile && !c.engineDir) { s.src = c.SingleEngineFile; } else if (c.engineDir && !c.SingleEngineFile) { s.src = c.engineDir + 'platform/jsloader.js'; } else { alert('You must specify either the single engine file OR the engine directory in "cocos2d.js"'); } document.ccConfig = c; s.id = 'cocos2d-html5'; d.body.appendChild(s); }); })();
这个文件基本可以作为模板来用,但有一部分你可能想自己改改,所以让我们一起看看这些代码吧。
1. 有各种各样的Cocos2D配置, 如激活框架调试功能,是否引用库文件(Box2D库)等等。
2. 这里你应该指定源文件的目录及文件名,你还记得你是怎么拷贝Platform/HTML5/cocos2d目录的吗?你也要指定你游戏中的Javanoxss文件。
3. 这仅仅是一些Cocos2D框架运行的入口模板。
你也许发现了2中的main.js文件了,但是你现在还没有写这个文件。这是你运行游戏不得不写的最后一个文件了。
创建一个新文件,命名为Cocos2DSimpleGameSrcmain.js并添加如下代码:
var cocos2dApp = cc.Application.extend({ config:document['ccConfig'], ctor:function (scene) { this._super(); this.startScene = scene; cc.COCOS2D_DEBUG = this.config['COCOS2D_DEBUG']; cc.initDebugSetting(); cc.setup(this.config['tag']); cc.Loader.getInstance().noxssing = function () { cc.LoaderScene.getInstance().draw(); }; cc.Loader.getInstance().noxss = function () { cc.AppController.shareAppController().didFinishLaunchingWithOptions(); }; cc.Loader.getInstance().preload(g_ressources); }, applicationDidFinishLaunching:function () { var director = cc.Director.getInstance(); director.setDisplayStats(this.config['showFPS']); director.setAnimationInterval(1.0 / this.config['frameRate']); // 1 director = cc.Director.getInstance(); winSize = director.getWinSize(); centerPos = cc.p( winSize.width/2, winSize.height/2 ); director.runWithScene(new this.startScene()); return true; } }); // 2 var director; var winSize; var centerPos; var myApp = new cocos2dApp(MainLayer.scene);
为了运行游戏,你需要创建一个类,该类继承cc.Application,实际做事是在这里。它有个applicationDidFinishLaunching方法,该方法很像ios。除了我标出的2部分,其他部分都是程序的通用方式。
1. 初始化全局变量,我之间就提过的。
2. 声明全局变量,并指出在特定的环境中运行(MainLayer.scene 是你之前创建的一个场景)
最后你可以运行了, 用你喜欢的浏览器打开index.html,就测试了,注意:我很幸运我使用的是Firefox浏览器,Safari浏览器可能有时运行不起来(因为safari的file协议限制,不过可以采用web server的方式来运行))。
如果运行正常,你将会在你的屏幕出现忍者:
移动怪兽
下面你应该想添加一些怪兽到你的屏幕去跟忍者战斗,为了更有趣,你想让怪兽移动。另外不要有太多的怀疑,让我们创建怪兽从屏幕的右边轻飘出来,并设置一个向左运动的行为。
首先,打开Cocos2DSimpleGameSrcresource.js修改资源文件,并包含以下2个图片文件:
var dirArt = "Art/"; var s_player = dirArt + "player.png"; var s_monster = dirArt + "monster.png"; var s_projectile = dirArt + "projectile.png"; var g_ressources = [ {type:"image", src:s_player}, {type:"image", src:s_monster}, {type:"image", src:s_projectile} ];
然后打开Cocos2DSimpleGameSrcMainLayer.js并用以下内容替换文件开头部分:
var MainLayer = cc.LayerColor.extend({ _monsters:[], ctor:function() { // Rest of file...
这在场景中创建了怪物实例变量,并初始化为空数组,在onEnter方法后添加一个停顿,以及添加一个新方法:
addMonster:function() { var monster = cc.Sprite.create(s_monster); // Determine where to spawn the monster along the Y axis var minY = monster.getContentSize().height / 2; var maxY = winSize.height - monster.getContentSize().height / 2; var rangeY = maxY - minY; var actualY = (Math.random() * rangeY) + minY; // 1 // Create the monster slightly off-screen along the right edge, // and along a random position along the Y axis as calculated above monster.setPosition(winSize.width + monster.getContentSize().width/2, actualY); this.addChild(monster); // 2 // Determine speed of the monster var minDuration = 2.0; var maxDuration = 4.0; var rangeDuration = maxDuration - minDuration; var actualDuration = (Math.random() % rangeDuration) + minDuration; // Create the actions var actinoxss = cc.MoveTo.create(actualDuration, cc.p(-monster.getContentSize().width/2, actualY)); // 3 var actinoxssDone = cc.CallFunc.create(function(node) { // 4 cc.ArrayRemoveObject(this._monsters, node); // 5 node.removeFromParent(); }, this); monster.runAction(cc.Sequence.create(actinoxss, actionMoveDone)); // Add to array monster.setTag(1); this._monsters.push(monster); // 6 }
在这里我将以一种啰嗦的方式讲解,以便尽可能的理解。首要的还是我们尽量讨论一些有意义的问题:你简单的计算一下在什么时候创建对象,该对象放置在什么的位置,并添加它到场景中。这跟你创建英雄精灵是一样的。
我将以2种不同的方法解释剩下的代码,以你是否已经熟悉了Cocos2D ios API为准。如果你熟悉cocos2d-ios,你就看情况一。如果不熟悉,则看情况二。你不需要同时看这两种情况的内容。
情况一:我熟悉Cocos2D-IOS
对于从Cocos2D-IOS转Cocos2D-Javanoxss这里给出了一写参考:
1. Javanoxss有很方便的参考手册,如Math.random(). 你能在Javanoxss book I recommended.找到相关的资料。
2. 在objective – c中你会使用monster.postion这样的dot语法,但是在javanoxss bindings中都是采用monster.setPosition这样的setters语法。
3. cc.p等于cpp宏。
4. 你能通过方法名进入cc.CallFunc.create, 或者你能进入匿名函数,像你在这看到的一样(很像Objective-C中using CCCallBlock)
5. Cocos2D 有一个方法从Javanoxss数组中移除元素:cc.ArrayRemoveObject.
6. 在Javanoxss中运用this,而不是self,我很多时候都忘了这个规则,结果导致代码经常出现问题。
情况二:我是个Cocos2D新手
在这里添加动作元素,Cocos2D提供了一些非常方便的生成Action的方法,你能运用这个使你的精灵更灵活,如添加一个移动动作,跳的动作,淡化的动作,动画动作等等,在怪物中我们运用3个动作:
1. ccMoveTo: 你用cc.MoveTo动作物体直接移出屏幕左边,注意:你应该指定运行动作需要的时间,这里你还可以随机给出一个2s~4s的速度。
2. cc.CallFunc:这cc.CallFunc动作允许你指定一个回调函数去运行,当这个动作被调用时。你或者能进入函数名(像这样:怪物移动)或者你能用一个无名的函数显示他
们。在这个游戏中,在怪物移动到屏幕左边时,你应添加一些代码来实现怪物从游戏(或者是怪物数组)中移除,这代码是很重要的,不然就会出现内存泄露。注意:有其他(或更好的)方法去解决这个问题,如可以重复使用精灵数组,但是作为初学者,你还是用移除的这种简单的方法。
3. cc.Sequence: 这cc.Sequence动作允许你一序列动作按顺序执行,一次一个的。这种方法,你可以首先执行cc.MoveTo动作,然后完成cc.CallFun动作。
回到刚才问题:
现在让我们确定你addMonster函数能被定期的调用,这是一种方法。要做这事,添加addMonster, 这个新方法。
gameLogic:function(dt) { this.addMonster(); }
并在onEnter方法最后一行添加如下代码:
this.schedule(this.gameLogic, 3);
这会每隔3秒定时的运行你的gameLogic方法去产生一个怪物。保存你的文件,并重启你的浏览器,现在应该有怪物从你的屏幕中飞出来。
射击炮弹
在这节,忍者想要一些技能,所以让我们添加射击技能。有很多的方法你能实现射击功能,但是这个游戏你将这样做,当用户点击屏幕时, 忍者则朝着点击的方向发射炮弹。
我想用cc.MoveTo动作来实现这种发射子弹的动作,这样初学者也能看懂,但是想要灵活运用,你不得不具备一些数学知识。这是因为这个cc.MoveTo需要你给定飞镖前进的目的地,但是你又不能使用这个touch点,因为touch点只是代表了飞镖飞出去的方向。实际上你想保持子弹移动穿过你点击的位置直到子弹移除屏幕。
下图表示的就是这种情况:
正如你所看到的,来自相对于原点及点击点的x,y坐标构成的一个小三角形。你还需要构建一个大的三角形,放大一些比例,你知道了你离开屏幕时的终点位置了。好的,现在进入代码,首先,在文件头添加一个存放炮弹的数组。
_projectiles:[],
然后你必须能响应点击事件在你的层中,但是怎样处理这样依据你的额运行环境,如手机,桌面,或者浏览器。所以在onEnter函数开始的地方添加如下代码,正确的还要调用
this._super():
if( 'touches' in sys.capabilities ) { this.setTouchEnabled(true); } if( 'mouse' in sys.capabilities ) { this.setMouseEnabled(true); }
这onMouse被回调,如果这里有鼠标输入,或者onTouch被回调如果有触屏输入。
gameLogic方法后,添加如下代码:
locationTapped:function(location) { // Set up initial location of the projectile var projectile = cc.Sprite.create(s_projectile); projectile.setPosition(20, winSize.height/2); // Determine offset of location to projectile var offset = cc.pSub(location, projectile.getPosition()); // 1 // Bail out if you are shooting down or backwards if (offset.x <= 0) return; // Ok to add now - we've double checked position this.addChild(projectile); // Figure out final destination of projectile var realX = winSize.width + (projectile.getContentSize().width / 2); var ratio = offset.y / offset.x; var realY = (realX * ratio) + projectile.getPosition().y; var realDest = cc.p(realX, realY); // Determine the length of how far you're shooting var offset = cc.pSub(realDest, projectile.getPosition()); var length = cc.pLength(offset); var velocity = 480.0; var realMoveDuration = length / velocity; // Move projectile to actual endpoint projectile.runAction(cc.Sequence.create( // 2 cc.MoveTo.create(realMoveDuration, realDest), cc.CallFunc.create(function(node) { cc.ArrayRemoveObject(this._projectiles, node); node.removeFromParent(); }, this) )); // Add to array projectile.setTag(2); this._projectiles.push(projectile); }, noxss:function (event) { var location = event.getLocation(); this.locationTapped(location); }, onTouchesEnded:function (touches, event) { if (touches.length <= 0) return; var touch = touches[0]; var location = touch.getLocation(); this.locationTapped(location); }
我要再一次依据你是否已经熟悉Cocos2D-IOS来做不同的解释:
解释一:假设你熟悉Cocos2D-IOS
这里提出几点建议给Cocos2D-IOS转Cocos2D-Javanoxss的程序员
1.这方法用点演示数学,你知道你喜欢的ccpAdd,ccpSub在这仍然存在。他们仅仅是改变了以下名字,例如:cc.pSub就等同于ccpSub。
2.你能创建一序列的动作就像你在Cocos2D-IOS一样。
解释二:你完全是个Cocos2D新手
noxss和onTounchesEnded方法会获取鼠标或触摸位置,并把这个值通过locationTapped函数分发出去。
这方法开始就载入一个炮弹精灵,并和往常一样初始化了放置子弹的位置。这时你决定你需要炮弹移动到哪里,可以使用忍者与触摸点之间的向量为参考,根据之前描述的逻辑算法去计算子弹最终移动的位置。
注意,这个算法并不是完美的。假设你让子弹一直运动到屏幕之外的X位置,此时,子弹的y坐标可能早就超过屏幕之外了。你可以使用一些其它的最短距离算法,判断到底是x方向先出屏幕还是y方向先出屏幕。 作为一个新手入门教程,我们就不在这里再作讨论了。
最后一件事,你计算子弹移动的时间。为了让子弹在任何方向上都是以恒定的速度运行,你不得不再用一些数学来处理了。你能通过cc.pLength函数计算出运动的速度。
一旦你有了这个距离,你仅仅通过除以速度就能获取时间了。这是因为速度=距离除以时间,或者是时间=距离除以速度。
其他部分的设置动作就想你朝着目标设置一样。保存文件,刷新你的浏览器,现在你的忍者应该能发射子弹来迎接面朝你扑过来的敌人了。
碰撞检测
所以现在你的忍者可以朝任何方向发射子弹了,但是你的忍者真的想去做的是打到怪物,所以让我们添加一些代码来检测你的子弹与怪物什么时候碰撞。
有很多方法去解决这个问题。采用Cocos2D,可以运用一个物理引擎库:Box2D 或者Chipmunk,但是为了保持简单,我们自己将实现一个简单的碰撞检测。
你已经把怪物,炮弹存放在数组中了。现在你要做的是定期的检查是否发生了碰撞。
为了做到这些,我们添加如下方法在onTouchesEnded函数中:
update:function (dt) { for (var i = 0; i < this._projectiles.length; i++) { var projectile = this._projectiles[i]; for (var j = 0; j < this._monsters.length; j++) { var monster = this._monsters[j]; var projectileRect = projectile.getBoundingBox(); var monsterRect = monster.getBoundingBox(); if (cc.rectIntersectsRect(projectileRect, monsterRect)) { cc.log("collision!"); cc.ArrayRemoveObject(this._projectiles, projectile); projectile.removeFromParent(); cc.ArrayRemoveObject(this._monsters, monster); monster.removeFromParent(); } } } }
以上代码相当于做了一个清除。你不停的通过你的子弹跟怪物,生成的矩形边框,并用CGRectIntersectsRect去检查重叠。如果有重叠,你把他们从场景和数组中移除。
注意:你不要像Objective-C一样创建分离“toDelete”数组,因为通过迭代器从一个数组中移除元素在Javanoxss中是安全的。
在你开始射子弹前你还需要在做一件事,通过在你的onEnter方法中加入以下代码让这个方法总是被调用:
this.scheduleUpdate();
保存文件并刷新你的浏览器,现在当你的弹丸碰到目标的时候他们都会消失!
音乐和音效
现在你相当于完全了能跑的游戏了,你还需要添加一些声音效果(你还么有的声音效果)和一些简单的游戏逻辑。
首先更新Cocos2DSimpleGameSrcresource.js添加声音效果:
var dirArt = "Art/"; var dirSounds = "Sounds/"; var s_player = dirArt + "player.png"; var s_monster = dirArt + "monster.png"; var s_projectile = dirArt + "projectile.png"; var s_bgMusic = dirSounds + "background-music.mp3"; var s_bgMusicOgg = dirSounds + "background-music.ogg"; var s_bgMusicCaf = dirSounds + "background-music.caf"; var s_shootEffect = dirSounds + "pew-pew-lei.mp3"; var s_shootEffectOgg = dirSounds + "pew-pew-lei.ogg"; var s_shootEffectWav = dirSounds + "pew-pew-lei.wav"; var g_ressources = [ {type:"image", src:s_player}, {type:"image", src:s_monster}, {type:"image", src:s_projectile}, {type:"sound", src:s_bgMusic}, {type:"sound", src:s_bgMusicOgg}, {type:"sound", src:s_bgMusicCaf}, {type:"sound", src:s_shootEffect}, {type:"sound", src:s_shootEffectOgg}, {type:"sound", src:s_shootEffectWav} ];
注意:背景音乐和声音效果应该保存三种格式:mp3, ogg, and wav. 这是因为不是所有浏览器,都支持所有的格式,所有通过添加三种格式,我们要尽可能的让玩家能听到声音。Cocos2D将判断浏览器支持的格式,我们将添加相应的格式文件。只要他们是相同的文件名。
注意:如果你想知道如何对这些格式进行相互转换,这是我做的: 1. 我通常用一个WAV文件。 2.我然后运用iTunes去转换为一个MP3.为了做这事,去<strong>iTunes PreferencesGeneralImport Settings</strong> and change <strong>Import Using</strong> to <strong>MP3 Encoder</strong>。然后在iTunes工具导入一个WAV文 件,并点击右键,选择<strong>Create MP3 Version</strong>将创建一个MP3格式文件。 3. 我用oggenc工具将MP3格式转换为一个OGG,我有一个手册介绍怎么安装它。
现在,是时候添加声音效果了,回到Cocos2DSimpleGameSrcMainLayer.js,在文件头添加如下代码:
var audioEngine = cc.AudioEngine.getInstance();
这获取一个全局引用一个声音引擎,之后你将会用到它,然后添加这行到你的onEnter函数末尾:
audioEngine.playMusic(s_bgMusic, true);
添加以下代码到locationTapped的结尾
audioEngine.playEffect(s_shootEffect);
保存文件并重新刷新浏览器,现在你应该有些音乐了。
输和赢
最后,让我们创建一个新的场景和层,该层将为你胜利或者失败提供说明。创建一个新文件Cocos2DSimpleGameSrcGameOver.js并添加如下内容:
var GameOver = cc.LayerColor.extend({ _won:false, ctor:function() { this._super(); cc.associateWithNative( this, cc.LayerColor ); }, onEnter:function () { this._super(); var director = cc.Director.getInstance(); var winSize = director.getWinSize(); var centerPos = cc.p( winSize.width/2, winSize.height/2 ); var message; if (this._won) { message = "You Won!"; } else { message = "You Lose :["; } var label = cc.LabelTTF.create(message, "Arial", 32); label.setColor(cc.c3b(0, 0, 0)); label.setPosition(winSize.width/2, winSize.height/2); this.addChild(label); this.runAction(cc.Sequence.create( cc.DelayTime.create(3), cc.CallFunc.create(function(node) { var scene = MainLayer.scene(); cc.Director.getInstance().replaceScene(scene); }, this) )); } }); GameOver.create = function (won) { var sg = new GameOver(); sg.won = won; if (sg && sg.init(cc.c4b(255, 255, 255, 255))) { return sg; } return null; }; GameOver.scene = function (won) { var scene = cc.Scene.create(); var layer = GameOver.create(won); scene.addChild(layer); return scene; };
这是一个层包含一个标签在你的屏幕中间(cc.LabelTTF),该标签包含一些信息。创建一个动作等待三秒回到主界面。
为了使用这个新场景,回到Cocos2DSimpleGameSrcMainLayer.js并修改一些代码:
// Add this new instance variable to the top of the file _monstersDestroyed:0, // Add inside update, right after monster.removeFromParent(): this._monstersDestroyed++; if (this._monstersDestroyed >= 2) { var scene = GameOver.scene(true); cc.Director.getInstance().replaceScene(scene); } // Add inside addMonster, right after node.removeFromParent(): var scene = GameOver.scene(false); cc.Director.getInstance().replaceScene(scene);
最后,当你添加了一个新文件,你需要在cocos2d.js引用它。所以打开Cocos2DSimpleGamecocos2d.js修改如下appFiles数组:
appFiles:[ './Src/resource.js', './Src/MainLayer.js', './Src/GameOver.js', './Src/main.js' ]
就是这样,保存文件,重新刷新浏览器,现在你的Cocos2D Javanoxss游戏完成了。
还有一件事情
Cocos2D-Javanoxss不是一直强调跨平台吗,对么?
让我展示你看,最多5秒钟让你相同的代码怎么运行在iPhone。
好的,假设你有了最新的Coscos2D-iOS版本已经安装了,如果没有,下载最新的不稳定版 2.X version (2.1-rc0a)然后安装模板。
注意:下载最新你能安装的Cocos2D版本,在终端中运行如下命令cd~/Downloads/
cocos2d-iphone-2.1-rc0
./install-templates.sh -f -u
然后在XCode创建一个iOScocos2d v2.xcocos2d iOS with Javanoxss新工程模板,命名为Cocos2DSimpleGame并保存到Cocos2DSimpleGamePlatformiOS目录下。
然后找到你的Cocos2DSimpleGame文件夹,选中Art, Sounds和Src文件夹,把他们拖到你的XCode工程中。注意:你弹出框出现时,选择Create folder references for any added folders并像如下图一样设置一些属性:
如果你没有错误,你的文件夹应该是蓝色的在XCode像如下截图一样,如果你的是黄色的,你选中groups”替换,移除他们重新试一次。
接下来,打开Resourcesmain.js并用以下内容替换:
require("jsb.js"); require("Src/resource.js"); require("Src/MainLayer.js"); require("Src/GameOver.js"); director = cc.Director.getInstance(); winSize = director.getWinSize(); centerPos = cc.p( winSize.width/2, winSize.height/2 ); function run() { director.runWithScene( MainLayer.scene() ); } run();
这里你加载你的游戏文件,设置全局变量,并运行主场景。
像这样,编译,运行,现在你可以相同的代码运行在你的iPhone了,但使用本机Cocso2DiPhone !
注意:如果你Javanoxss代码是错误的,有时你会看到一个错误在Xcode console,但是大多数默认的Xcode会给你一些没有用的错误提示。
这也是其中一个我为什么选择Cocos2D-HTML5作为初学者开发的理由。