背景:
本來打算下一個遊戲是塗鴉跳躍的,因爲圖片資源沒準備好,暫時往後推遲。剛好筆者手頭上有部分水果忍者的遊戲素材,於是上週末花了一些時間把水果忍者實現了;以前讀大學的時候這款遊戲就風靡大街小巷,記得當時同學間也比賽誰得的分數高,樂趣無窮;筆者在那會還沒學過編程,很難理解切西瓜是怎麼做出來,現在此一時彼一時了。
因爲素材有限,實現的效果可能和原版有差距,例外很多童鞋反映flappy,popstar和原版不同,筆者在此說明:因爲是學習demo,差距肯定是有的,好的遊戲需要讀者精雕細琢,把握好每一個參數和細節,都是需要花時間的。
本系列共有上中下三篇,源碼基本完成,分析分爲三篇;
ps:
1 CocosEditor已發佈新版本,現在提供6個實戰demo學習,包括flappy ,popstar ,fruitninja,moonwarroris,fruitattack,testjavascript;
2 運行demo需要配置好CocosEditor,暫不支持其他工具。demo是跨平臺的,可移植運行android,ios,html5網頁等,代碼是基於javascript語言,cocos2d-x遊戲引擎,CocosEditor手遊開發工具完成的。
源代碼下載:
請到代碼集中營下載(水果忍者 ):http://blog.makeapp.co/?p=319
不同平臺下的效果圖:
windows
html5網頁
android平臺
代碼分析:
實戰項目裏面ccbx場景都是略過的,主要放在代碼這塊,水果忍者主要有兩個場景,一個開始場景StarLayer和主場景MainLayer;
1 StartLayer.js裏面有三個按鈕,道場,開始,退出。道場功能未去實現,點擊開始進入主場景MainLayer;StarLayer裏面主要處理三個選項的旋轉動畫,如下直接無限循環旋轉cc.RepeatForever.create(cc.RotateBy.create());圓環順時針,水果逆時針;
StartLayer.prototype.onEnter = function ()
{
this.rings = [this.dojoRing, this.newGameRing, this.quitRing];
for (var i = 0; i < this.rings.length; i++) {
this.rings[i].runAction(cc.RepeatForever.create(cc.RotateBy.create(1, -90)));
}
this.fruits = [this.dojoFruit, this.newGameFruit, this.quitFruit];
for (var j = 0; j < this.fruits.length; j++) {
this.fruits[j].runAction(cc.RepeatForever.create(cc.RotateBy.create(5, 90)));
}
cc.AudioEngine.getInstance().playEffect(FRUIT_SOUNDS.menu, true);
this.isFlash = false;
};
2 切掉綠色西瓜進入主場景;
#西瓜包括兩個西瓜碎片,觸摸的瞬間,西瓜消失,兩個碎片san0,san1產生;並各自執行不同的移動動畫,並動畫結束後cleanup;
#觸摸的瞬間也產生刀鋒的效果 cc.MySprite.createFlash(this.rootNode, "flash.png", this.pBegin, loc);
#0.5s執行延遲函數進入主場景this.rootNode.scheduleOnce;
StartLayer.prototype.onTouchesMoved = function (touches, event)
{
var loc = touches[0].getLocation();
if (cc.rectContainsPoint(this.newGameFruit.getBoundingBox(), loc)) {
var sandiaImages = ["sandia-1.png", "sandia-2.png"];
var fruitPosition = this.newGameFruit.getPosition();
var san0 = cc.MySprite.create(this.rootNode, sandiaImages[0], fruitPosition, 100);
var san1 = cc.MySprite.create(this.rootNode, sandiaImages[1], fruitPosition, 100);
this.newGameFruit.runAction(cc.ScaleTo.create(0, 0));
var rotation = this.newGameFruit.getRotation();
cc.log("rotation==" + rotation);
san0.setRotation(rotation);
san1.setRotation(rotation);
cc.AudioEngine.getInstance().playEffect(FRUIT_SOUNDS.splatter, false);
var upSprite = san0;
var downSprite = san1;
var fruitX = fruitPosition.x;
var fruitY = fruitPosition.y;
upSprite.runAction(cc.Sequence.create(
cc.MoveTo.create(0.2, cc.p(fruitX - 50, fruitY + 50)),
cc.CleanUp.create(upSprite)
));
downSprite.runAction(cc.Sequence.create(
cc.MoveTo.create(0.2, cc.p(fruitX + 50, fruitY - 50)),
cc.CleanUp.create(downSprite)
));
if (this.isFlash == false) {
this.isFlash = true;
cc.MySprite.createFlash(this.rootNode, "flash.png", this.pBegin, loc);
}
this.rootNode.scheduleOnce(function ()
{
cc.AudioEngine.getInstance().stopAllEffects();
cc.BuilderReader.runScene("", "MainLayer");
}, 0.5);
}
}
3 產生刀鋒函數,主要是根據pBegin和pEnd兩個點計算旋轉角度,簡單的數學應用;以前不知道學數學幹嘛,現在知道了;
cc.MySprite.createFlash = function (node, name, pBegin, pEnd)
{
var flash = cc.MySprite.create(node, name, pEnd, 3000);
var ratio = (pEnd.y - pBegin.y) / (pEnd.x - pBegin.x);
var angle = (Math.atan(ratio) / (Math.PI)) * 180;
flash.setRotation(-angle);
flash.setScale(0.5);
flash.runAction(cc.Sequence.create(cc.DelayTime.create(0.2), cc.CleanUp.create(flash)));
return flash;
};
4 進入主場景MainLayer,需要每隔一段時間產生向上拋的水果newFruit;
#從水果數組裏面隨機取一個水果getRandom(FRUIT_DATA.length)
#創建水果精靈,初識位置 x隨機取,y的話在屏幕下方-100,fruit.setPosition(cc.p(x, -100));;
#設置水果的各種屬性zorder,num等;
#創建一個貝塞爾曲線控制數組,有三個點,決定一條曲線var controlPoints = [
cc.p(x, -100),
cc.p(x - offSetX, topY),
cc.p(x - offSetX * 2, -100)
]; 又是數學的應用;
#讓水果同時實現貝塞爾曲線動畫和旋轉動畫
#水果數組添加該水果,主要用於後面的水果切除檢測 this.fruitList.push(fruit);
#播放拋出音效;
MainLayer.prototype.newFruit = function ()
{
//create new fruit per 0.5s
var random = getRandom(FRUIT_DATA.length);
var data = FRUIT_DATA[random];
var fruit = cc.Sprite.createWithSpriteFrameName(data.fruitImage);
var x = 300 + getRandomOffset(200);
fruit.setPosition(cc.p(x, -100));
fruit.setAnchorPoint(cc.p(0.5, 0.5));
this.fruitZOrder -= 1;
fruit.setZOrder(this.fruitZOrder);
fruit.cleanuped = false;
fruit.num = data.num;
var offSetX = getRandomOffset(100);
var topY = 900 + getRandom(100);
var controlPoints = [
cc.p(x, -100),
cc.p(x - offSetX, topY),
cc.p(x - offSetX * 2, -100)
];
var fruitTime = 3;
var bezier = cc.BezierTo.create(fruitTime, controlPoints);
var action2 = cc.RotateBy.create(fruitTime, getRandom(360));
var upActions = cc.Spawn.create(cc.Sequence.create(bezier, cc.CleanUp.create(fruit)), action2);
fruit.runAction(upActions);
this.rootNode.addChild(fruit);
this.fruitList.push(fruit);
cc.AudioEngine.getInstance().playEffect(FRUIT_SOUNDS.throw, false);
};
5 每隔一段時間拋出一個newFruit,只要在update更新函數裏面編寫就行;
如果當前時間距離上一個水果產生時間爲0.5s,就又產生一個,周次循環,不斷產生水果
if (this.currentTime - this.lastFruitTime > 0.5) {
this.newFruit();
this.lastFruitTime = this.currentTime;
}
上篇就這些,over;
CocosEditor開發工具:
CocosEditor,它是開發跨平臺的手機遊戲工具,運行window/mac系統上,javascript腳本語言,基於cocos2d-x跨平臺遊戲引擎, 集合代碼編輯,場景設計,動畫製作,字體設計,還有粒子,物理系統,地圖等等的,而且調試方便,和實時模擬;
CocosEditor 下載,介紹和教程:http://blog.csdn.net/touchsnow/article/details/19070665;
CocosEditor官方博客:http://blog.makeapp.co/;