flappy bird游戏源代码揭秘和下载 —— 可运行于android、ios和html5多平台(flappy bird暗网)

网友投稿 306 2022-06-16


背景:

最近火爆全球的游戏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

代码下载:

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

代码如何移植到各平台:

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

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

效果图:

开发工具:

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,如下图;主要分三层,开始场景、主场景、游戏结束场景,通过显示隐藏控制三个场景的切换。

MainLayer.ccbx代码

jsControlled="true"

jsController="MainLayer"

resolution="default"

>

id="0"

name="Default Timeline"

length="10"

chainedId="0"

offset="0.0"

position="0.0"

resolution="30"

scale="128">

positionX="0" positionY="0.0"

sizeType="Percent"

width="100" height="100"

anchorPointX="0.5" anchorPointY="0.5" ignoreAnchorPoint="true"

scaleX="1" scaleY="1"

>

anchorPointY="0" src="Resources/bg.png" name="" var="" target="None" scaleX="1" scaleY="1" visible="true"/>

anchorPointY="0" color="#fff2e8ff" visible="false"/>

anchorPointY="0.5" scaleX="2.4" scaleY="1.725">

anchorPointY="0" src="Resources/ground.png" var="ground" target="Doc"/>

anchorPointY="0" var="hoseNode" target="Doc">

anchorPointY="0.5" src="Resources/flappy_packer.plist/bird3.png" var="test" target="Doc" visible="false"/>

anchorPointY="0.5" src="Resources/flappy_packer.plist/bird1.png" var="bird" target="Doc" scaleX="1" scaleY="1" rotation="0" visible="true"/>

anchorPointY="0.5" var="readyNode" target="Doc" visible="true">

anchorPointY="0.5" src="Resources/flappy_packer.plist/getready.png"/>

anchorPointY="0.5" src="Resources/flappy_packer.plist/click.png"/>

anchorPointY="0.5" var="overNode" target="Doc" visible="true">

anchorPointY="0.5" src="Resources/flappy_packer.plist/base.png">

anchorPointY="0.5" src="Resources/flappy_packer.plist/gameover.png"/>

anchorPointY="0.5">

anchorPointY="0.5" normalImage="Resources/flappy_packer.plist/start.png" target="Doc" onClick="onStartClicked"/>

anchorPointY="0.5" target="Doc" normalImage="Resources/flappy_packer.plist/grade.png" onClick="onGradeClicked"/>

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

}

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

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;

}

再次提示代码下载地址:

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

flappy博文系列:

flappy bird游戏源代码揭秘和下载后续---移植到android真机上

flappy bird游戏源代码揭秘和下载后续---移植到html5网页浏览器

flappy bird游戏源代码揭秘和下载后续---日进5万美元的秘诀AdMob广告 (将写)

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

注:本文转自CSDN。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:JAVA中的糕富帅技术——反射(一)
下一篇:如何在电脑上测试手机网站(一)—— Chrome 篇(怎么用手机查电脑网页)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~