【教程分享】用Cocos2d-HTML5游戏引擎。编写一个简单的打灰机 1/ 2

用Cocos2d-HTML5游戏引擎。编写一个简单的游戏游戏的主题设计理念总是让人兴奋。在我看来,学徒级别的独立游戏设计这或开发人员应该选择一个小型的经典案例来分析比读一百篇纯理论更实用。所以在本例中,我使用JavaScript语 言编写一个基本的经典游戏:JetFighter。它有趣和简单,设计和实现也并不难完成。而且也很容易上手。用你的拇指触摸手机屏幕。移动你的喷气式战斗机, 避免敌人的子弹和试图击落你所看到的每一架敌机。首先,我需要一个游戏引擎——Cocos2d-html5,用Javascript编写的,基于HTML5技术。Cocos2d-html5游戏引擎是一个Cocos2d-x的分支。 它的目标定位在安装有支持html5技术浏览器的台式电脑,平板电脑当然还有手机上。然后我们还需要一个编辑工具来完成编码。(我选择了工具-webstorm。)和一个浏览器来显示结果。(我选择了Google Chrome,因为Cocos2d-html5基于HTML5技术,而Google Chrome是最支持HTML5的浏览器。我从这下载到了引擎:(http://cocos2d-x.org/download) 我刚设置了一个开发环境。(开发环境):(游戏引擎): Cocos2d-html5 (http://cocos2d-x.org/download )(浏览器): Chrome (http://www.google.com/intl/zh-CN/chrome/)(编辑器): WebStorm (http://www.jetbrains.com/webstorm/)打开下载好的引擎。你会在模板文件夹里看到以下文件:目录结构简单叙述:1. res: The place where storeyour resources.资源存放目录 2. src: The place where store your js script. Js脚本存放目录(我们自己项目的源码目录)3. build.xml: The file that compiles the engines into the js script.对引擎进行编译成js脚本形式所用的文件 4. cocos2d.js: The parametersettings of the engine configuration file对引擎进行参数设置的配置文件 5. index.html:Run theprogram web pages运行程序的网页 6. main.js:The main program entrance.主程序入口

  1. Run the ‘Hello World’运行“Hello World”右键单击“index.html”选择“在浏览器中打开”。如果一切情况正常的话,你就会看到像这样的图片。这说明你现在成功了。
    Hello Cocos2d

  2. Basic Knowledge:
    基础知识:在我进一步深入之前。有一些HTML5的基本知识我应该知道:(如果你已经知道了这些,你可以越过这部分。)首先,CCDirector(前缀“CC”是这个引擎函数的前缀)在Cocos2d-html5引擎里,CCDirector是导演,领导,它控制一切,场景,层和精灵。


    Thebasic structure (Left: Chinese, Right: English)第二,CCCamera,例如,每次当节点缩小,放大或旋转等等,引擎都需要继承CCCamera再次渲染。第三,CCScene,我们可以简单的认为这是准备上演演出的舞台。第四,CCLayer,类似于CCScene,像是舞台上的背景。但CCLayer是灵活的,它可以使各种各样的组合,所以和CCLayer比较的话CCScene更为静态。CCLayer应该加载在CCScene上。
    Different Layer Combination第五,CCSprite,非常容易理解,包括人物、敌人、NPC(Non-player character)和一些我们可以与之互动的物体。它可以添加在CCSCene和CCLayer之上。第六,CCAction。这是控制CCsprite的主要功能,如何移动或反应。
    Thepicture used for bullets
    The picture used for jet fighter

  3. StartCoding
    开始编码现在,我将开始编码,你已经看到上面的图片。在我的新创建的文件夹(简单地复制文件夹里的“模板”)。把上面的图片放在“res”文件夹(这是你的图片应在的地方)。并注册每一个我们需要的资源图片。js”(我将它命名为s_Jet当我注册它时)。
    Copy & Paste接下来,我们注册下我们将要用到的图片资源。(每一次有新的图片会被使用的话,你都应该记得在这里注册它。)
    Theresource file


var s_HelloWorld = "HelloWorld.jpg"; // 开始界面背景图片
var s_CloseNormal = "CloseNormal.png"; // 可删除
var s_CloseSelected = "CloseSelected.png"; // 可删除
var s_Menu = "menu.png"; // 按钮图片
var s_bg01 = "bg01.jpg"; // 背景
var s_bullets = "bullets.png"; //敌我子弹图片
var s_Jet = "Jet.png"; // 敌我飞机图片
var g_resources = //image{src:s_HelloWorld},
{src: s_CloseNormal},{src: s_CloseSelected},
{src: s_Menu},{src: s_bg01},{src: s_Jet},
{src: s_bullets}

  1. Start interface
    开始界面首先,我们把原本的界面改成开始界面。删除init:function(){}里原本的代码。

var MyLayer = cc.Layer.extend({
``````init:function() {``````deleteall of them 删掉``````}});

在init:function(){}添加这些代码:


this._size = cc.Director.getInstance().getWinSize(); // 获得游戏屏幕尺寸
this.gameLayer = cc.Layer.create(); // 创建名为“gameLayer”的新图层
this.addChild(this.gameLayer); //加在这个新图层
var bg = cc.Sprite.create(s_HelloWorld); // 创建精灵加载图片“s_HelloWorld”
this.gameLayer.addChild(bg, 1); //在gameLayer层上加载这个精灵
bg.setAnchorPoint(cc.p(0.5, 0.5));// 设置锚点
bg.setPosition(this._size.width / 2, this._size.height /2);// 设置位置

这里,我们创建了一个图层并且和图片“s_HelloWorld”一起载入。设定了图片的位置和锚点。Scene切换场景接下来,我们为“新游戏”按钮添加一个方法来变换场景并创建一个新的层来展示我们的游戏。添加这个方法在init:function () {}的后面


onNewGame:function (pSender) 
{
  this._size = cc.Director.getInstance().getWinSize(); // 获得屏幕尺寸大小
  var scene = cc.Scene.create(); //创建新场景
  var gsl = new GameSceneLayer(); //创建新场景
  gsl.init(); // 初始化新图层scene.addChild(gsl,1); // 加载新场景
  var bgLayer = cc.Layer.create(); // 创建新层
  var bkPng = cc.Sprite.create(s_bg01); // 创建新精灵并加载图片
  bgLayer.addChild(bkPng); // 将精灵加在进层
  bkPng.setAnchorPoint(cc.p(0.5, 0.5)); // 设置锚点
  bkPng.setPosition(this._size.width / 2,this._size.height / 2); // 设施位置
  scene.addChild(bgLayer,0); //将层加载进场景
  cc.Director.getInstance().replaceScene(cc.TransitionFade.create(1.2,scene));} // 场景切换

现在,开始界面基本完成了。如果你按下“新游戏”按钮,就会有问题。即使我们已经创建了“GameSceneLayer”层,但它目前还没有被定义。
Start interface所以我们接下来要它工作起来。把这一个打进“myApp.js”文件的顶部。


var GameSceneLayer;

Add this Layerbehind the “var MyLayer = cc.Layer.extend({})”.加在“var MyLayer = cc.Layer.extend({})” 的后面


GameSceneLayer = cc.Layer.extend({isMouseDown: false, // 鼠标反转:否
helloImg: null,  // 设为全局变量,内容为“空”
helloLabel: null, //设为全局变量,内容为“空”
circle: null,  // 设为全局变量,内容为“空”
sprite: null,  // 设为全局变量,内容为“空”
_size: null,  // 设为全局变量,内容为“空”
gameLayer: null,  // 设为全局变量,内容为“空”
gameLayer02: null, // 设为全局变量,内容为“空”
_jetSprite: null, // 设为全局变量,内容为“空”
init: function () {this._super(); //  必须调用父类init()方法,很多bug都是由于没有调用父类init()方法造成的
this._size = cc.Director.getInstance().getWinSize(); 
this.gameLayer02 = cc.Layer.create();
this.addChild(this.gameLayer02);
this._jetSprite = cc.Sprite.create (s_Jet);
this._jetSprite.setAnchorPoint(0.5, 0.5);
this._jetSprite.setPosition(this._size.width / 2,this._size.height / 5);
this._jetSprite.setScale(0.25);
this.gameLayer02.addChild(this._jetSprite, 0);
this.setTouchEnabled(true);  // 设置触摸模式为:可用
this.setKeyboardEnabled(true);  // 设置键盘为:可用
this.setMouseEnabled(true);  // 设置鼠标为:可用
this.setPosition(new cc.Point(0, 0));},

我们定义了“GameSceneLayer”并创建了代表我们战斗机的精灵。我们设置了它的锚点,位置和尺寸。把这个精灵加进“gameLayer02”层。还有,我们设置触摸、键盘和鼠标为可使用。


After clicking the Start button如我们所见,飞机已经被创建了,但是根本不能动。即使我们已经把鼠标、键盘和触摸设置为可用。

  1. Move
    移动在“MyGameLayer”中添加这些方法:

onMouseDragged:function (event) { // 方法:鼠标拖动事件记录 
  this.processEvent(event);  // 调用方法
  processEvent
},
processEvent:function(event) {
  var delta = event.getDelta(); // 获得触摸位移
  var curPos = this._jetSprite.getPosition(); // 获得飞机位置
  curPos= cc.pAdd(curPos, delta); // 触摸位移+ 原本飞机位置= 新的飞机位置
  curPos= cc.pClamp(curPos, cc.POINT_ZERO, cc.p(this._size.width, this._size.height)); // 触摸范围(超出屏幕无效)
  this._jetSprite.setPosition(curPos);// 设定飞机新位置}

这两个方法会获取鼠标或手指的碰触地点。并把位移转换给飞机。

  1. Bullet
    子弹如果这里只有飞机飞来飞去却没有子弹,这一定会变得很无聊。所以我们要使他们能够发射子弹。在“init:function () {}”中添加这个“计划表”

this.schedule(this.addBullet, 0.3); //  每0.3秒更新一次addBullet方法

添加这个方法进入“init:function(){}”:


addBullet:function(){
  var jetPosition = this._jetSprite.getPosition(); //  获得飞机位置
  var bulletDuration = 1;  //  子弹完成动作所需时间:1 秒(从屏幕底到屏幕顶)
  var bullet = cc.Sprite.create(s_bullets, cc.rect(0, 0, 33, 33));   //  获取在子弹图片内指定范围的内容
  bullet.setPosition(cc.p(jetPosition.x,jetPosition.y + bullet.getContentSize().height)); //  设定子弹位置,和飞机位置相同
  var timeScale = ((this._size.height - jetPosition.y -bullet.getContentSize().height / 2) / this._size.height); //  根据子弹出现的位置不同计算相应的子弹穿越时间
  var actionMove = cc.MoveTo.create(bulletDuration * timeScale,cc.p(jetPosition.x,this._size.height));  // 设定子弹动作
  var actionMoveDone =cc.CallFunc.create(this.spriteMoveFinished, this);// 设定子弹动作
  bullet.runAction(cc.Sequence.create(actionMove,actionMoveDone));//  运行子弹移动动作
  this._bullets.push(bullet);// 将子弹添加进数组
  this.gameLayer02.addChild(bullet,0);  //  将子弹加载进层中},

现在我们有了子弹。但是如你所见,这些子弹并不会消失。这会让你的电脑变卡变慢。所以我们最好把他们清理掉。
The bullets won’t disappear.把他们添加进“addBullet:function(){}”

this._bullets = ]; //  创建子弹数组bullet.setTag(6); //  将子弹标记为“6”

在“addbullet:function(){}”后面添加这个方法


spriteMoveFinished:function(sprite){// 将元素移除出
  Layerthis.gameLayer02.removeChild(sprite,true);
  if(sprite.getTag()==6){// 把子弹从数组中移除
  var index = this._bullets.indexOf(sprite);  // 遍历数组中的子弹
  if(index > -1) {
    this._bullets.splice(index,1);  // 删除数组中的子弹       
    }    
  }
}

(我们之后会使这个方法更复杂。毕竟我们需要它识别并删除其他更多东西。)
第二贴:http://www.cocoachina.com/bbs/read.php?tid=196129

不错, 最喜欢这样成系列的帖子了

漂亮。h5的文章!:874:

不要,不要停……

翻译的很好啊!

配图很漂亮。。。

好棒啊!!!

求英文原版链接和资源图片,谢谢!

英文版:http://www.cocos2d-x.org/forums/19/topics/51574
素材: res.rar (613 KB)

音频文件,一样放置在res文件夹中:

根据教程走有遗漏的地方,对于新手来说很是困惑,
1:new game 菜单是哪里定义的, 如何用cocos-js3 来定义点击动作和执行 后面定义的 onnewgame 函数?
2: 很多地方用最新版的cocos2s-js v3.0 alpha2 不兼容,新手表示入门很是疑惑…

JS引擎更新到3.0后很多语法都变了。我改过后在webstorm上能正常,VC上getBoundingbox还是有问题。所以还没放出。
NewGame 按钮在这(我的疏忽):
init:function () {

var start01 = cc.Sprite.create(s_Menu, cc.rect(0, 0, 126, 33));
var start02 = cc.Sprite.create(s_Menu, cc.rect(0, 33, 126, 33));
var start03 = cc.Sprite.create(s_Menu, cc.rect(0, 2 * 33, 126, 33));
var newGame = cc.MenuItemSprite.create(start01, start02, start03, this.onNewGame, this.gameLayer);

    var menu = cc.Menu.create(newGame);
    this.gameLayer.addChild(menu, 1, 2);
    menu.setPosition(this._size.width / 2, this._size.height / 2 + 100);


},

从Cocos2d-html5 v2.2.x到Cocos2d-JS v3.0 alpha2升级指南
http://www.cocos2d-x.org/docs/manual/framework/html5/release-notes/v3.0a/upgrade-guide/zh

首先吐槽一下注册时和回复时的数学题好难。
第二快速回复怎么在最下面。。怎么能快捷。。
最后感谢分享

挺骚的挺骚的挺骚的挺骚的

嘎嘎嘎灌灌灌灌灌灌灌灌灌灌

有完整的源码包吗?

这个太厉害了!

为什么加了子弹过后,就一直卡死,跳转不了,即使加了move的那个function??

— Begin quote from ____

引用第18楼MinnieZhou于2014-07-24 23:28发表的 :
为什么加了子弹过后,就一直卡死,跳转不了,即使加了move的那个function?? http://www.cocoachina.com/bbs/job.php?action=topost&tid=196128&pid=1012589

— End quote

哦,找到原因了,那个子弹数组得在init里面加,然后设置target得在加进数组前设置。
LZ照顾下新手,再写清楚些啊~