溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

flappy bird游戲源代碼揭秘和下載

發布時間:2020-07-24 06:16:46 來源:網絡 閱讀:777 作者:makeapp628 欄目:游戲開發

背景:

  最近火爆全球的游戲flappy bird讓筆者嘆為觀止,于是花了一天的時間山寨了一個一模一樣的游戲,現在把游戲的思路和源碼分享出來,代碼是基于javascript語言,cocos2d-x游戲引擎,cocos2d-x editor手游開發工具完成的,請讀者輕砸;

  ps:運行demo必須配置好cocos2d-x editor,暫不支持其他工具。還有demo是跨平臺的,可移植運行android,ios,html5移動系統等;


Android Apk下載:(演示效果)

 暫時只移植打包到android系統,可下載運行看看效果;

騰訊微云:http://share.weiyun.com/cac18d8c58d40bf2401b3fdeeb6bcb2f


代碼下載:

csdn下載:http://download.csdn.net/detail/touchsnow/6912707

百度云盤:http://pan.baidu.com/s/1pJnWDb9

金山快盤 :http://www.kuaipan.cn/file/id_25348935635745384.htm?source=1


代碼如何移植到各平臺:

 Android:http://blog.csdn.net/touchsnow/article/details/19176091

 html5:       http://blog.makeapp.co/?p=245


效果圖:

flappy bird游戲源代碼揭秘和下載


flappy bird游戲源代碼揭秘和下載


flappy bird游戲源代碼揭秘和下載


開發工具:

   cocos2dx editor,它是開發跨平臺的手機游戲工具,運行window/mac系統上,javascript腳本語言,基于cocos2d-x跨平臺游戲引擎, 集合代碼編輯,場景設計,動畫制作,字體設計,還有粒子,物理系統,地圖等等的,而且調試方便,和實時模擬;

cocos2dx editor 下載,介紹和教程:http://blog.csdn.net/touchsnow/article/details/19070665;

cocos2dx editor官方博客:http://blog.makeapp.co/;(請持續關注版本更新)


思路和源碼:


  1 場景設計MainLayer.ccbx,如下圖;主要分三層,開始場景、主場景、游戲結束場景,通過顯示隱藏控制三個場景的切換。

flappy bird游戲源代碼揭秘和下載

 

   MainLayer.ccbx代碼

<?xml version="1.0" encoding="UTF-8"?>  <Document         jsControlled="true"         jsController="MainLayer"         resolution="default"         >      <Resolutions>         <Resolution centeredOrigin="false" ext="iphone" height="1280" width="720" name="default" scale="1"/>         <Resolution centeredOrigin="false" ext="iphone" height="720" width="1280" name="default1" scale="1"/>     </Resolutions>      <Animations>         <Animation autoPlay="true"                    id="0"                    name="Default Timeline"                    length="10"                    chainedId="0"                    offset="0.0"                    position="0.0"                    resolution="30"                    scale="128">             <CallbackChannel>             </CallbackChannel>             <SoundChannel>             </SoundChannel>         </Animation>      </Animations>     <Layer             positionX="0" positionY="0.0"             sizeType="Percent"             width="100" height="100"             anchorPointX="0.5" anchorPointY="0.5" ignoreAnchorPoint="true"             scaleX="1" scaleY="1"             >        <Sprite positionType="LeftBottom" width="720.0" height="1280.0" positionX="0" positionY="0" anchorPointX="0"                                          anchorPointY="0" src="Resources/bg.png" name="" var="" target="None" scaleX="1" scaleY="1" visible="true"/>       <LayerColor positionType="LeftBottom" width="720" height="1280" positionX="0" positionY="0" anchorPointX="0"                   anchorPointY="0" color="#fff2e8ff" visible="false"/>       <Menu positionType="LeftBottom" width="40" height="40" positionX="356.0" positionY="237.0" anchorPointX="0.5"               anchorPointY="0.5" scaleX="2.4" scaleY="1.725">       </Menu>       <Sprite positionType="LeftBottom" width="840.0" height="281.0" positionX="0" positionY="0" anchorPointX="0"                                          anchorPointY="0" src="Resources/ground.png" var="ground" target="Doc"/>       <Node positionType="LeftBottom" width="40" height="40" positionX="800" positionY="250" anchorPointX="0"             anchorPointY="0" var="hoseNode" target="Doc">         <Sprite positionType="LeftBottom" width="86.0" height="60.0" positionX="-500" positionY="400" anchorPointX="0.5"                                          anchorPointY="0.5" src="Resources/flappy_packer.plist/bird3.png" var="test" target="Doc" visible="false"/>         <Sprite positionType="LeftBottom" width="86.0" height="60.0" positionX="-550" positionY="500" anchorPointX="0.5"                 anchorPointY="0.5" src="Resources/flappy_packer.plist/bird1.png" var="bird" target="Doc" scaleX="1" scaleY="1" rotation="0" visible="true"/>       </Node>       <Node positionType="LeftBottom" width="40" height="40" positionX="303.0" positionY="500" anchorPointX="0.5"             anchorPointY="0.5" var="readyNode" target="Doc" visible="true">         <Sprite positionType="LeftBottom" width="508.0" height="158.0" positionX="95.0" positionY="584.0" anchorPointX="0.5"                                          anchorPointY="0.5" src="Resources/flappy_packer.plist/getready.png"/>         <Sprite positionType="LeftBottom" width="286.0" height="246.0" positionX="73.0" positionY="236.0" anchorPointX="0.5"                                          anchorPointY="0.5" src="Resources/flappy_packer.plist/click.png"/>       </Node>       <Node positionType="LeftBottom" width="40" height="40" positionX="300" positionY="500" anchorPointX="0.5"             anchorPointY="0.5" var="overNode" target="Doc" visible="true">         <Sprite positionType="LeftBottom" width="590.0" height="298.0" positionX="72.0" positionY="219.0" anchorPointX="0.5"                                          anchorPointY="0.5" src="Resources/flappy_packer.plist/base.png">           <Sprite positionType="LeftBottom" width="508.0" height="158.0" positionX="286.0" positionY="458.0" anchorPointX="0.5"                                          anchorPointY="0.5" src="Resources/flappy_packer.plist/gameover.png"/>         </Sprite>         <Menu positionType="LeftBottom" width="40" height="40" positionX="0" positionY="0" anchorPointX="0.5"               anchorPointY="0.5">           <MenuItem positionType="LeftBottom" width="290" height="176" positionX="-65.0" positionY="-92.0" anchorPointX="0.5"                     anchorPointY="0.5" normalImage="Resources/flappy_packer.plist/start.png" target="Doc" onClick="onStartClicked"/>           <MenuItem positionType="LeftBottom" width="290" height="176" positionX="230.0" positionY="-92.0" anchorPointX="0.5"                     anchorPointY="0.5" target="Doc" normalImage="Resources/flappy_packer.plist/grade.png" onClick="onGradeClicked"/>         </Menu>       </Node>     </Layer>   </Document>

 

2 代碼編寫MainLayer.js

   首先,小鳥在向前飛,其實是底部的路和水管在向左移動,相對的你就感覺小鳥在向右飛了;路循環移動代碼:

MainLayer.prototype.groundRun = function () {     var action1 = cc.MoveTo.create(0.5, cc.p(-120, 0));     var action2 = cc.MoveTo.create(0, cc.p(0, 0));     var action = cc.Sequence.create(action1, action2);     this.ground.runAction(cc.RepeatForever.create(action)); }

   初始化高低不同的水管,每一關卡都由上下兩水管和空隙組成??傞L度相同,空隙也一定,隨機取下面水管的長度,就形成錯落有致的水管關卡;

MainLayer.prototype.newHose = function (num) {     var hoseHeight = 830;     var acrossHeight = 300;     var downHeight = 100 + getRandom(400);     var upHeight = 1100 - downHeight - acrossHeight;      var hoseX = 400 * num;      var HoseName = FP_MAIN_TEXTURE.HOSE;     var ccSpriteDown = cc.Sprite.createWithSpriteFrameName(HoseName[0]);     ccSpriteDown.setZOrder(1);     ccSpriteDown.setAnchorPoint(cc.p(0, 0));     ccSpriteDown.setPosition(cc.p(hoseX, 0));     ccSpriteDown.setScaleY(downHeight / hoseHeight);      var ccSpriteUp = cc.Sprite.createWithSpriteFrameName(HoseName[1]);     ccSpriteUp.setZOrder(1);     ccSpriteUp.setAnchorPoint(cc.p(0, 0));     ccSpriteUp.setPosition(cc.p(hoseX, downHeight + acrossHeight));     ccSpriteUp.setScaleY(upHeight / hoseHeight);      this.hoseNode.addChild(ccSpriteDown);     this.hoseNode.addChild(ccSpriteUp);     this.hoseSpriteList.push(ccSpriteDown);     this.hoseSpriteList.push(ccSpriteUp);     return null; }

  一開始進入游戲讓底部路不斷移動,初始化水管,顯示準備游戲場景;

MainLayer.prototype.onEnter = function () {     cc.AnimationCache.getInstance().addAnimations("Resources/flappy_frame.plist");     this.groundRun();     this.ground.setZOrder(10);     this.birdReadyAction();     this.bird.setZOrder(20);     this.readyNode.setVisible(true);     this.overNode.setVisible(false);      for (var i = 0; i < 30; i++) {         this.newHose(i);     } }

 點擊屏幕,小鳥向上飛60dp,然后更快的速度下落(移動動畫),同時閃動翅膀(幀動畫);

MainLayer.prototype.birdRiseAction = function () {     var riseHeight = 60;     var birdX = this.bird.getPositionX();     var birdY = this.bird.getPositionY();     var time = birdY / 600;      var actionFrame = cc.Animate.create(cc.AnimationCache.getInstance().getAnimation("fly"));     var flyAction = cc.Repeat.create(actionFrame, 90000);     var riseAction1 = cc.MoveTo.create(0.2, cc.p(birdX, birdY + riseHeight));     var riseAction2 = cc.RotateTo.create(0, -30);     var riseAction = cc.Spawn.create(riseAction1, riseAction2);     var fallAction1 = cc.MoveTo.create(time, cc.p(birdX, 50));     var fallAction2 = cc.Sequence.create(cc.DelayTime.create(time / 6), cc.RotateTo.create(0, 30));     var fallAction = cc.Spawn.create(fallAction1, fallAction2);      this.bird.stopAllActions();     this.bird.runAction(cc.Spawn.create(             cc.Sequence.create(riseAction, cc.DelayTime.create(0.1), fallAction),             flyAction)     ); }

 檢測碰撞,如果小鳥碰到地面和水管,發生碰撞,這里碰撞直接用cocos2d-x 里面的圖片和圖片交叉函數 cc.rectIntersectsRect;

MainLayer.prototype.checkCollision = function () {     if (this.bird.getPositionY() < 60) {         cc.log("floor");         this.birdFallAction();         return;     }     for (var i = 0; i < this.hoseSpriteList.length; i++) {         var hose = this.hoseSpriteList[i];         if (!this.isInScreen(hose)) {             // continue;         }          if (cc.rectIntersectsRect(hose.getBoundingBox(), this.bird.getBoundingBox())) {             cc.log("hose positionX==" + hose.getBoundingBox().x);             cc.log("this.bird positionX==" + this.bird.getBoundingBox().x);             cc.log("i==" + i);             cc.log("birdFallAction");             this.birdFallAction();             return;         }     } }

碰撞后,小鳥先下落,游戲結束場景顯示;

MainLayer.prototype.birdFallAction = function () {     this.gameMode = OVER;     this.bird.stopAllActions();     this.ground.stopAllActions();     var birdX = this.bird.getPositionX();     var birdY = this.bird.getPositionY();     var time = birdY / 2000;     this.bird.runAction(cc.Sequence.create(             cc.DelayTime.create(0.1),             cc.Spawn.create(cc.RotateTo.create(time, 90), cc.MoveTo.create(time, cc.p(birdX, 50))))     );     this.overNode.setVisible(true); }

游戲的難度主要在于多個水管的移動,小鳥觸摸動畫,檢測碰撞,我把Mainlayer.js所有代碼貼出來;

FP_MAIN_TEXTURE = {     FRAME_ANIMS: "beanstalk/Resources/bs_main_anims.plist",     HOSE: ["holdback1.png", "holdback2.png"] }  READY = 1; START = 2; OVER = 3;  var MainLayer = function () {     cc.log("MainLayer");     this.bird = this.bird || {};     this.ground = this.ground || {};     this.hoseNode = this.hoseNode || {};     this.readyNode = this.readyNode || {};     this.overNode = this.overNode || {};      this.passTime = 0;     this.hoseSpriteList = [];     this.isStart = false;      this.gameMode = READY; };  MainLayer.prototype.onDidLoadFromCCB = function () {     if (sys.platform == 'browser') {         this.onEnter();     }     else {         this.rootNode.onEnter = function ()         {             this.controller.onEnter();         };     }      this.rootNode.schedule(function (dt)     {         this.controller.onUpdate(dt);     });      this.rootNode.onExit = function ()     {         this.controller.onExit();     };      this.rootNode.onTouchesBegan = function (touches, event)     {         this.controller.onTouchesBegan(touches, event);         return true;     };      this.rootNode.onTouchesMoved = function (touches, event)     {         this.controller.onTouchesMoved(touches, event);         return true;     };     this.rootNode.onTouchesEnded = function (touches, event)     {         this.controller.onTouchesEnded(touches, event);         return true;     };     this.rootNode.setTouchEnabled(true); };  MainLayer.prototype.onEnter = function () {     cc.AnimationCache.getInstance().addAnimations("Resources/flappy_frame.plist");     this.groundRun();     this.ground.setZOrder(10);     this.birdReadyAction();     this.bird.setZOrder(20);     this.readyNode.setVisible(true);     this.overNode.setVisible(false);      for (var i = 0; i < 30; i++) {         this.newHose(i);     } }  MainLayer.prototype.newHose = function (num) {     var hoseHeight = 830;     var acrossHeight = 300;     var downHeight = 100 + getRandom(400);     var upHeight = 1100 - downHeight - acrossHeight;      var hoseX = 400 * num;      var HoseName = FP_MAIN_TEXTURE.HOSE;     var ccSpriteDown = cc.Sprite.createWithSpriteFrameName(HoseName[0]);     ccSpriteDown.setZOrder(1);     ccSpriteDown.setAnchorPoint(cc.p(0, 0));     ccSpriteDown.setPosition(cc.p(hoseX, 0));     ccSpriteDown.setScaleY(downHeight / hoseHeight);      var ccSpriteUp = cc.Sprite.createWithSpriteFrameName(HoseName[1]);     ccSpriteUp.setZOrder(1);     ccSpriteUp.setAnchorPoint(cc.p(0, 0));     ccSpriteUp.setPosition(cc.p(hoseX, downHeight + acrossHeight));     ccSpriteUp.setScaleY(upHeight / hoseHeight);      this.hoseNode.addChild(ccSpriteDown);     this.hoseNode.addChild(ccSpriteUp);     this.hoseSpriteList.push(ccSpriteDown);     this.hoseSpriteList.push(ccSpriteUp);     return null; }  MainLayer.prototype.groundRun = function () {     var action1 = cc.MoveTo.create(0.5, cc.p(-120, 0));     var action2 = cc.MoveTo.create(0, cc.p(0, 0));     var action = cc.Sequence.create(action1, action2);     this.ground.runAction(cc.RepeatForever.create(action)); }  MainLayer.prototype.birdReadyAction = function () {     var birdX = this.bird.getPositionX();     var birdY = this.bird.getPositionY();     var time = birdY / 2000;     var actionFrame = cc.Animate.create(cc.AnimationCache.getInstance().getAnimation("fly"));     var flyAction = cc.Repeat.create(actionFrame, 90000);     this.bird.runAction(cc.Sequence.create(             flyAction)     ); }  MainLayer.prototype.birdFallAction = function () {     this.gameMode = OVER;     this.bird.stopAllActions();     this.ground.stopAllActions();     var birdX = this.bird.getPositionX();     var birdY = this.bird.getPositionY();     var time = birdY / 2000;     this.bird.runAction(cc.Sequence.create(             cc.DelayTime.create(0.1),             cc.Spawn.create(cc.RotateTo.create(time, 90), cc.MoveTo.create(time, cc.p(birdX, 50))))     );     this.overNode.setVisible(true); }  MainLayer.prototype.birdRiseAction = function () {     var riseHeight = 60;     var birdX = this.bird.getPositionX();     var birdY = this.bird.getPositionY();     var time = birdY / 600;      var actionFrame = cc.Animate.create(cc.AnimationCache.getInstance().getAnimation("fly"));     var flyAction = cc.Repeat.create(actionFrame, 90000);     var riseAction1 = cc.MoveTo.create(0.2, cc.p(birdX, birdY + riseHeight));     var riseAction2 = cc.RotateTo.create(0, -30);     var riseAction = cc.Spawn.create(riseAction1, riseAction2);     var fallAction1 = cc.MoveTo.create(time, cc.p(birdX, 50));     var fallAction2 = cc.Sequence.create(cc.DelayTime.create(time / 6), cc.RotateTo.create(0, 30));     var fallAction = cc.Spawn.create(fallAction1, fallAction2);      this.bird.stopAllActions();     this.bird.runAction(cc.Spawn.create(             cc.Sequence.create(riseAction, cc.DelayTime.create(0.1), fallAction),             flyAction)     ); }  MainLayer.prototype.onUpdate = function (dt) {     if (this.gameMode != START) {         return;     }     this.passTime += dt;      this.hoseNode.setPositionX(800 - 200 * this.passTime);     this.bird.setPositionX(-500 + 200 * this.passTime);     this.checkCollision(); }  MainLayer.prototype.checkCollision = function () {     if (this.bird.getPositionY() < 60) {         cc.log("floor");         this.birdFallAction();         return;     }     for (var i = 0; i < this.hoseSpriteList.length; i++) {         var hose = this.hoseSpriteList[i];         if (!this.isInScreen(hose)) {             // continue;         }          if (cc.rectIntersectsRect(hose.getBoundingBox(), this.bird.getBoundingBox())) {             cc.log("hose positionX==" + hose.getBoundingBox().x);             cc.log("this.bird positionX==" + this.bird.getBoundingBox().x);             cc.log("i==" + i);             cc.log("birdFallAction");             this.birdFallAction();             return;         }     } }  MainLayer.prototype.isInScreen = function (sprite) {     return (sprite.getPositionX() > 0 && sprite.getPositionX() < 720); }  MainLayer.prototype.onExitClicked = function () { }  MainLayer.prototype.onStartClicked = function () {     cc.Director.getInstance().resume();     cc.BuilderReader.runScene("", "MainLayer"); }  MainLayer.prototype.onExit = function () {     cc.log("onExit"); }  MainLayer.prototype.onTouchesBegan = function (touches, event) {     var loc = touches[0].getLocation(); }  MainLayer.prototype.onTouchesMoved = function (touches, event) { }  MainLayer.prototype.onTouchesEnded = function (touches, event) {     if (this.gameMode == OVER) {         return;     }      if (this.gameMode == READY) {         this.gameMode = START;         this.readyNode.setVisible(false);     }      var loc = touches[0].getLocation();     this.birdRiseAction();  }  function isInRect(ccRect, ccTouchBeganPos) {     if (ccTouchBeganPos.x > ccRect.x && ccTouchBeganPos.x < (ccRect.x + ccRect.width)) {         if (ccTouchBeganPos.y > ccRect.y && ccTouchBeganPos.y < (ccRect.y + ccRect.height)) {             return true;         }     }     return false; }  function getRandom(maxSize) {     return Math.floor(Math.random() * maxSize) % maxSize; } 

再次提示代碼下載地址:

csdn下載:http://download.csdn.net/detail/touchsnow/6912707

百度云盤:http://pan.baidu.com/s/1pJnWDb9

金山快盤 :http://www.kuaipan.cn/file/id_25348935635745384.htm?source=1


flappy博文系列:

flappy bird游戲源代碼揭秘和下載

flappy bird游戲源代碼揭秘和下載后續---移植到android真機上

flappy bird游戲源代碼揭秘和下載后續---移植到html5網頁瀏覽器

flappy bird游戲源代碼揭秘和下載后續---日進5萬美元的秘訣AdMob廣告 (將寫

flappy bird游戲源代碼揭秘和下載后續---移植到蘋果ios上 (未寫


筆者語:

想了解更多請進入官方博客,最新博客和代碼在官方博客首發;請持續關注,還有更多cocos2dx editor游戲源碼即將放出;

聯系筆者:zuowen@makeapp.co(郵箱)


后言:

為了鼓勵更多手游愛好者加入cocos2d-x editor陣營,也為了讀者堅定對該工具的信心,筆者基于以上的flappy bird代碼和新的圖片資源,往google play和中國應用市場發布了一個相似的游戲----騰飛的小鳥(fly bird)。該游戲還加入了廣告模塊,可以獲得些許的廣告費。也希望讀者通過cocos2d-x editor可以在市場上發布更多的好游戲;

google play地址:https://play.google.com/store/apps/details?id=com.makeapp.game.flybird (小秘密:如果應用.apk后綴改為.rar,你會獲得意想不到的東西

機鋒市場地址:    http://apk.gfan.com/Product/App741996.html

html5在線演示:http://www.makeapp.co/flybird/ (微軟ie瀏覽器存在兼容性問題,請選擇其他瀏覽器;公司內網,小卡,見諒)


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女