天天看点

flappy bird游戏源代码揭秘和下载

背景:

  最近火爆全球的游戏flappy bird让笔者叹为观止,于是花了一天的时间山寨了一个一模一样的游戏,现在把游戏的思路和源码分享出来,代码是基于javascript语言,cocos2d-x游戏引擎,cocos2d-x editor手游开发工具完成的,请读者轻砸;

android apk下载:(演示效果)

 暂时只移植打包到android系统,可下载运行看看效果;

代码下载:

代码如何移植到各平台:

效果图:

flappy bird游戏源代码揭秘和下载
flappy bird游戏源代码揭秘和下载
flappy bird游戏源代码揭秘和下载

cocos2d-x跨平台游戏引擎

cocos2d-x是全球知名的游戏引擎 ,引擎在全球范围内拥有众多开发者,涵盖国内外各知名游戏开发商。目前cocos2d-x引擎已经实现横跨ios、android、bada、meego、blackberry、marmalade、windows、linux等平台。编写一次,到处运行,分为两个版本 cocos2d-c++和cocos2d-html5 本文使用了后者;

cocos2d-x editor开发工具:

   cocos2dx editor,它是开发跨平台的手机游戏工具,运行window/mac系统上,javascript脚本语言,基于cocos2d-x跨平台游戏引擎, 集合代码编辑,场景设计,动画制作,字体设计,还有粒子,物理系统,地图等等的,而且调试方便,和实时模拟;

思路和源码:

  1 场景设计mainlayer.ccbx,如下图;主要分三层,开始场景、主场景、游戏结束场景,通过显示隐藏控制三个场景的切换。

flappy bird游戏源代码揭秘和下载

   mainlayer.ccbx代码

flappy bird游戏源代码揭秘和下载

<?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 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>  

    </layer>  

</document>  

2 代码编写mainlayer.js

   首先,小鸟在向前飞,其实是底部的路和水管在向左移动,相对的你就感觉小鸟在向右飞了;路循环移动代码:

flappy bird游戏源代码揭秘和下载

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));  

}  

   初始化高低不同的水管,每一关卡都由上下两水管和空隙组成。总长度相同,空隙也一定,随机取下面水管的长度,就形成错落有致的水管关卡;

flappy bird游戏源代码揭秘和下载

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;  

  一开始进入游戏让底部路不断移动,初始化水管,显示准备游戏场景;

flappy bird游戏源代码揭秘和下载

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,然后更快的速度下落(移动动画),同时闪动翅膀(帧动画);

flappy bird游戏源代码揭秘和下载

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;

flappy bird游戏源代码揭秘和下载

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;  

碰撞后,小鸟先下落,游戏结束场景显示;

flappy bird游戏源代码揭秘和下载

mainlayer.prototype.birdfallaction = function ()  

    this.gamemode = over;  

    this.ground.stopallactions();  

    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所有代码贴出来;

flappy bird游戏源代码揭秘和下载

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);  

    this.rootnode.ontouchesended = function (touches, event)  

        this.controller.ontouchesended(touches, event);  

    this.rootnode.settouchenabled(true);  

mainlayer.prototype.birdreadyaction = function ()  

mainlayer.prototype.onupdate = function (dt)  

    if (this.gamemode != start) {  

    this.passtime += dt;  

    this.hosenode.setpositionx(800 - 200 * this.passtime);  

    this.bird.setpositionx(-500 + 200 * this.passtime);  

    this.checkcollision();  

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) {  

    if (this.gamemode == ready) {  

        this.gamemode = start;  

        this.readynode.setvisible(false);  

    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;  

再次提示代码下载地址:

flappy博文系列:

<a target="_blank" href="http://blog.csdn.net/touchsnow/article/details/19071961">flappy bird游戏源代码揭秘和下载</a>

<a target="_blank" href="http://blog.csdn.net/touchsnow/article/details/19176091">flappy bird游戏源代码揭秘和下载后续---移植到android真机上</a>

<a target="_blank" href="http://blog.csdn.net/touchsnow/article/details/19269757">flappy bird游戏源代码揭秘和下载后续---移植到html5网页浏览器</a>

<a target="_blank" href="http://blog.csdn.net/touchsnow/article/details/20258869">flappy bird游戏源代码揭秘和下载后续---日进5万美元的秘诀admob广告 </a>

flappy bird游戏源代码揭秘和下载后续---移植到苹果ios上 (未写)

笔者语:

联系笔者:[email protected](邮箱)qq群:232361142

后言:

为了鼓励更多手游爱好者加入cocos2d-x editor阵营,也为了读者坚定对该工具的信心,笔者基于以上的flappy bird代码和新的图片资源,往google play和中国应用市场发布了一个相似的游戏----腾飞的小鸟(fly bird)。该游戏还加入了广告模块,可以获得些许的广告费。也希望读者通过cocos2d-x editor可以在市场上发布更多的好游戏;

继续阅读