翻译人:hany3000
开始。。。
首先,下载项目所需要的资源文件 下载 . 解压缩之后就会看到下列文件
下载的文件包含下面三个目录 :
- Art: 包含游戏制作的图片:怪物、忍者、忍者飞镖.
- Platform: 四个开发平台的空目录,之后你将把做好的东西放在里面,我这样是为了方便给你分类 .
- Sounds: 背景音乐和发飞镖时候的pewpew声音特效, .
现在就开始做这个项目吧。
Hello, Cocos2D-Javascript!
让我们来做一个最简单的制作:生成一个cocos2d场景,显示一个英雄精灵 .
当你在Cocos2D-Javascript引用图片或者其他资源的时候,你需要把它们包含在一个名字叫g_ressources的数组里面,这样framework才可以加载它们,因为第一步就是添加英雄精灵到一个特殊数组里面.
因此我们使用你喜欢的编辑器生成一个新的文件叫 Cocos2DSimpleGame\Src\resource.js。写入下列代码:
var dirArt = "Art/";
var s_player = dirArt + "player.png";
var g_ressources = [
{type:"image", src:s_player}
];
这只是添加了一个图片到你的资源列表里:玩家的图片对象,待会你会把你需要的图片和声音资源添加到这个文件里,但是现在先加个图片就够了 .
下一步,你将建立以各cocos2d层来显示这个图片,建立一个新文件,名字叫Cocos2DSimpleGame\Src\MainLayer.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);
}
});
让我一行一行的看下代码::
- 这行代码生成一个类MainLayer,派生自 Cocos2D’s LayerColor . 所有的 Cocos2D类都是以cc 开头.
- 给这个类生成一个构造函数 , 这个构造函数再调用父类的构造函数.
- 在 Cocos2D Javascript绑定的时候,无论你任何时候从cocos2d类派生一个类,你都必须调用这个函数来跟你派生的类相关联
- 当一个node被第一次添加到一个场景中的时候,cocos2d会调用onEnter函数,因此这个函数对于一个层来说是一个很好的初始化代码的地方 .
- 这行生成了一个精灵,命名为player . 这个精灵包含之前我们生成的一个变量s_player .
- 设置精灵的位置到屏幕的左侧重点,winSize是待会再定义一个很方便实用的常量。
- 最后添加这个玩家精灵到层中.
然后添加下面的函数到这个文件的底部:
// 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;
};
这是两个我需要建立的辅助函数,
- 生成一个层MainLayer句柄 .
- 第二个函数生成一个场景,并把主要层添加进来 .
这就是MainLayer.js文件所要做的,最好的部分就要来到啦,就是你要开始写忍者发发飞镖的那部分,他能在ios android或者更多的环境下运行.
Hello, Cocos2D-HTML5!
正如之前我提到的,我们首先确定这个游戏要运行在html5的版本下,所以你要到html5的环境下来开始 .
因此去下载最新的版本 Coos2D-HTML5的最新版本, 写这个教程的时候是v2.1.1版本.下载下来后解压缩到你的硬盘的任何一个目录下 .
在 Cocos2D-HTML5 目录的内部,拷贝 cocos2d,CocosDenshion和extensions 三个目录到Cocos2DSimpleGame\Platform\HTML5目录 :
这就拷贝了Cocos2D-HTML5 框架的所有代码到你的项目的子目录下,因此你能很容易的使用它们, 注意你还没有真正明白为什么这么做的. 不过这个系列的第二部分你就明白啦,这样非常方便开发和调试 .
下一步生成一个文件名字叫 Cocos2DSimpleGame\index.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>
<script src="cocos2d.js"></script>
</body>
</html>
这是一个非常简单的html文件来把cocos2的视图放在页面的中间,如果你现在有点陌生也不要担心,你可以像使用一个模板一样来使用它。 .
有两个很重要的标签需要指出: :
<canvas id="gameCanvas" width="800" height="450"></canvas>
这行代码设置了html5的画布并命名为gameCanvas,cocos2d要进行的一切都在这个地方显示,如果你想要不同的尺寸,你就可以在这里改变 .
<script src="cocos2d.js"></script>
这行代码告诉浏览器需要寻找或者运行一个脚本文件cocos2d.js,不过这个文件你还没有写。下面就让我们把这个文件添加进来,
生成一个新的文件,命名为 Cocos2DSimpleGame\cocos2d.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('script');
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);
});
})();
这个文件是使用最多的样板 , 让我们一行一行分析一下 .
- 这是对cocos2d环境的设置,例如设置框架调试级别是否使用box2d特性等
- 这是你指定保存cocos2d框架代码的地方,还记得你拷贝的那些文件到 Platform/HTML5/cocos2d 目录里面吗? 你也指定了你游戏中所有的 Javascript 文件保存的地方 .
- 这是一些运行cocos2d框架的模板 .
你应该留意到 appFiles文件在第二部分列出了一个文件名字叫 main.js, 这个文件我们还没有,现在我们来写这个文件
生成一个文件叫 Cocos2DSimpleGame\Src\main.js 写入下列代码::
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().onloading = function () {
cc.LoaderScene.getInstance().draw();
};
cc.Loader.getInstance().onload = 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派生的类,那是令人激动的一部分,它有像ios里面那样的applicationDidFinishLaunching 的函数 .
这是我们经常用的样板,除了我提到的两个函数: :
- 初始化之前我提到的一些全局变量
- 生命一个全局变量,指定一个场景去运行 (MainLayer.scene这个辅助方法是之前写的在MainLayer层里面生成一个场景).
初步已经完成啦,可以测试以下了,在浏览器里面打开index. 提示我使用firefox浏览器感觉最好,safari有时候运行的不是很好,尤其是调试的时候 .
如果运行成功,你会发现一个忍者出现在屏幕上!
移动怪物
下一步你需要添加一些怪物到你的场景中,来让你的忍者来射击它。为了让这些事情更有趣些,你需要让这些怪物不停的移动,否则就没什么挑战性!让我们来建立一些怪物到屏幕的右侧,设置他们的行动,让他们从右侧走到左侧。
首先打开文件Cocos2DSimpleGame\Src\resource.js 然后修改资源文件列表:
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}
];
然后打开Cocos2DSimpleGame\Src\MainLayer.js在文件的开始出写入下列代码:
var MainLayer = cc.LayerColor.extend({
_monsters:[],
ctor:function() {
// Rest of file...
这个将在场景中给这些怪物列表生成一个变量,然后把这个列表初始化成一个空的数组.
接着在onEnter函数中添加一个逗号,然后添加一个新的函数 :
|
我已经很详细的把我们所有需要的东西都以尽可能方便理解的方式写出来了,第一部分到现在才开始讨论是比较合理的。你做了一些计算来决定在什么地方生成一些对象,设置这些对象的位置,把它们添加到场景中,同时也添加了一个玩家精灵 .
我将解释这两种方式有什么不同。这要基于你对cocos2d ios api是否熟悉 .
方案一:适合对cocos2d-ios熟悉的人:
这里有几个方面需要指出,针对于从cocos2dios移植到 cocos2d javascript.
- Javascript 有很多方便实用的函数和一些开发库,像Math.random()函数,你能在这本书里找到很多指导 Javascript 学习教程我推荐.
- 经常使用点句法,想Objective-c中的monster.position。你通常是像调用setPosition()来使用.
- cc.p就是ccp.
- 你也通过函数的名字像this.monsterMoveDone来调用cc.CallFunc.create,或者你也可以使用匿名函数,像在Objective-c中使用CCCallBlock一样
- Cocos2D有一个辅助函数来移除数组中所有数据: cc.ArrayRemoveObject.
- 在Javascript中使用this 而不是self. 我跟你说我都不知道多少次忘记使用this而使用self,导致很多错误!
方案二:针对于cocos2d新手
这有一些新的元素就是添加动作,cocos2d提供了很多方便的动作让你使用来制作精灵动画,例如移动动作,跳动动作,褪色动作,动画动作等等,这有三个怪物要实用的动作。:
- cc.MoveTo: 使用cc.MoveTo 动作直接把对体应到的屏幕的左侧,提示你已经指定一段时间来定义你的动作所需要的时间,还有要定义速度随机2-4秒 seconds.
- cc.CallFunc: 这个 cc.CallFunc 动作允许你定义一个回调函数在动作结束后运行,你可以使用函数名字来调用或者使用匿名函数来执行,在这个游戏中,当怪物走到屏幕左侧走出屏幕的时候,你添加了一些代码来移除怪物(分别从游戏场景中和怪物列表数组中移除),这是很重要的,当一些精灵移到屏幕外侧的时候,避免一些内存泄漏什么的,提示有很多种方法来避免这个问题,例如 做一个可重复使用的精灵数组,但是这里是个初级教程,暂时这样处理。 .
- cc.Sequence: cc.Sequence 动作允许你把一系列的动作链接到一起来执行,一次执行一次,这个方法能让你先使用 cc.MoveTo 动作,然后接结束后再调用回调函数cc.CallFunc 动作.
回到我们之前的游戏中来
现在让我们添加怪物函数 addMonster .
添加 addMonster之后再添加一个新的函数 :
|
然后再 onEnter末尾添加下列代码
|
这个函数意思是每三秒生成一个怪物
保存这个文件,刷新浏览器,你应该看到有很多怪物穿过屏幕
发射子弹
这方面,忍者会做一些动作,让我们来添加射击!有很多种方法你能完成射击,但是这个游戏里,当用户触屏的时候你才从忍者这边往触屏的方向发射子弹。
我使用cc.MoveTo动作函数来实现这个功能,这里你需要做一点数学计算, 这是因为cc.MoveTo需要你给子弹一个目标位置. 但是你不能够使用触屏的点 ,因为触点只是代表一个射击和忍者之间的的相对方向,就是说,发射子弹以后,子弹要通过触屏的点,直到移动到屏幕外侧,下面是个图片来显示这个关系 :
正如你看到的,从忍者到触屏点再到这两个坐标点之间的差值,你建立了一个三角形,你需要使用相同的比例来建立一个更大的三角形,而且你知道你要的结束点在屏幕外侧。 .
好吧。我们来写代码。首先,在文件顶部给子弹添加一个新的数组, :
|
Then you have to enable touches on your layer – but how to handle that depends if your game is being run on a mobile, desktop, or browser device. So add the following code to the beginning of onEnter, right after the call to this._super():
|
This registers the onMouse callbacks to be called if there’s mouse input, or the onTouch methods to be called if there’s touch input.
Then add a comma after gameLogic method, and add these new methods:
|
Again, I’d like to split the explanation here based on whether you’re familiar with Cocos2D-iOS already or not.
Solution Inside: I'm Familiar with Cocos2D-iOS | SelectShow</> |
---|---|
Here are some things to point out for those transitioning to Cocos2D-Javascript from Cocos2D-iOS:
|
Solution Inside: I'm Completely New to Cocos2D | SelectShow</> |
---|---|
The onMouseUp and onTouchesEnded methods get the location of the mouse click/touch and forward it on to locationTapped. The beginning of this method loads up the projectile sprite and sets the initial position as usual. You then determine where you wish to move the projectile to, using the vector between the player and the touch as a guide, according to the algorithm described previously. Note that the algorithm isn’t ideal. You’re forcing the bullet to keep moving until it reaches the offscreen X position – even if you would have gone offscreen in the Y position first! There are various ways to address this including checking for the shortest length to go offscreen, having your game logic callback check for offscreen projectiles and removing rather than using the callback method, etc. but for this beginner tutorial you’ll keep it as-is. The last thing you have to do is determine the duration for the movement. You want the bullet to be shot at a constant rate despite the direction of the shot, so again you have to do a little math. You can figure out how far you’re moving by using the handy cc.pLength function. Once you have the distance, you just divide that by the velocity in order to get the duration. This is because velocity = distance over time, or in other words time = distance over velocity. The rest is setting the actions just like you did for the targets. |
And that’s it – save the file and refresh your browser, and now your ninja should be able to fire away at the oncoming hordes!
Collision Detection
So now you have shurikens flying everywhere – but what your ninja really wants to do is to lay some smack down. So let’s add in some code to detect when your projectiles intersect your targets.
There are various ways to solve this with Cocos2D, including using one of the included physics libraries: Box2D or Chipmunk. However to keep things simple, you are going to implement simple collision detection yourself.
You already have been keeping track of the monsters and projectiles in arrays. All you need to do is periodically check to see if any of them are colliding.
To do this, add a comma after onTouchesEnded and add this new method:
|
The above should be pretty clear. You just iterate through your projectiles and monsters, creating rectangles corresponding to their bounding boxes, and use CGRectIntersectsRect to check for intersections. If any are found, you remove them from the scene and from the arrays.
Note that you don’t have to create separate “toDelete” arrays like you do in Objective-C, because it’s safe to remove elements from an array while iterating through in Javascript.
You just need one more thing before you’re ready to roll – schedule this method to run as often as possible by adding the following line to your onEnter method:
|
Save the file and refresh your browser, and now when your projectiles intersect targets they should disappear!
Gratuitious Music and Sound Effects
You’re pretty close to having a workable (but extremely simple) game now. You just need to add some sound effects and music (since what kind of game doesn’t have sound!) and some simple game logic.
First, update Cocos2DSimpleGame\Src\resource.js to add the sound effects:
|
Note that both the background music and sound effects are each saved in three different formats: mp3, ogg, and wav. This is because not all browsers support all formats, so by adding all three we will have the highest possible chance of the player being able to hear something. Cocos2D will detect what the browser supports and use the appropriate file – as long as they have the same filename.
Note: If you’re wondering how to convert between these formats, here’s what I do:
- I usually start with a WAV.
- I then use iTunes to convert to an MP3. To do this, go to iTunes Preferences\General\Import Settings and changeImport Using toMP3 Encoder. Then you can import a WAV into iTunes, and right click it and selectCreate MP3 Version to create a MP3.
- I then convert the MP3 to an OGG using oggenc. I used this guide as a howto for installing it.
Now, time to play these effects. Back in Cocos2DSimpleGame\Src\MainLayer.js add this to the top of the file:
|
This gets a global reference to the audio engine so you can use it later. Then add this line to the end of onEnter:
|
And add this to the end of locationTapped:
|
Save the file and refresh your browser, and now you should have some groovy tunes!
Winning and Losing
To wrap up, let’s create a new scene and layer that will serve as your “You Win” or “You Lose” indicator. Create a new fileCocos2DSimpleGame\Src\GameOver.js and replace the contents with the following:
|
This is a layer that contains a label in the middle of the screen (cc.LabelTTF) that contains the message. An action is created to wait three seconds, and then transition back to the MainLayer.
To use this new scene, go back to Cocos2DSimpleGame\Src\MainLayer.js and make these changes:
|
Finally, since you added a new file you need to reference it in cocos2d.js. So openCocos2DSimpleGame\cocos2d.js and modify the appFiles array to the following:
|
And that’s it! Save the file and refresh your browser, and now you now have a complete Cocos2D Javascript game!
Just One More Thing…
The whole point of Cocos2D-Javascript is that it’s cross-platform, right?
Let me show you how you can get this same code running on the iPhone in less than 5 minutes :]
Well – assuming you have the latest version of Cocos2D-iOS already installed that is. If not,download the latest unsable 2.X version (2.1-rc0a) and install the templates.
Note: After downloading the latest version of Cocos2D you can install the templates by running the following commands from a Terminal:
cd ~/Downloads/cocos2d-iphone-2.1-rc0
./install-templates.sh -f -u
Then create a new project in Xcode using the iOS\cocos2d v2.x\cocos2d iOS with JavaScript template. Name the new projectCocos2DSimpleGame and save it in theCocos2DSimpleGame\Platform\iOS folder.
Then, inside Finder find your Cocos2DSimpleGame folder, select theArt,Sounds, andSrc folders, and drag them into your Xcode project.Important: In the popup that appears, selectCreate folder references for any added folders, and set the rest of the options like the screenshot below:
If you did it correctly, your folders should be blue in Xcode like the screenshot below. If they are yellow, you selected “groups” instead – remove them and try again.
Next, open Resources\main.js and replace the contents with the following:
|
Here you load your game files, set up the global variables, and run the main scene.
And that’s it! Build and run, and now you have the same code running on your iPhone – but using native Cocso2D-iPhone!
Note: Note that if anything is wrong with your Javascript code, sometimes you’ll see an error in the Xcode console, but many times default Xcode will give you no useful error messages at all.
This is one of the reasons I find developing initially with Cocos2D-HTML5 much easier.