最终效果图:

环境版本:cocos2d-x-3.3beta0 使用内置的物理引擎
计时器没有添加,可参考【cocos2d_x_06_游戏_一个都不能死】
主场景
//
//  FlappyBirdScene.h
//  01_cocos2d-x
//
//  Created by beyond on 14-10-7.
//
//

#ifndef ___1_cocos2d_x__FlappyBirdScene__
#define ___1_cocos2d_x__FlappyBirdScene__

#include "cocos2d.h"

#include "FlappyBird.h"
#include "Floor.h"
#include "TopBar.h"
#include "BottomBar.h"

USING_NS_CC;
// 注意 这儿,继承的是 Layer
class FlappyBirdScene : public cocos2d::Layer
{
private:
    // 屏幕尺寸
    Size winSize;
    // 小鸟
    FlappyBird *bird;
    // 地板
    Floor *floor;
    // 顶部圆管
    TopBar *topBar;
    // 底部圆管
    BottomBar *bottomBar;
    
    // 用一个Node 包装起来 所有的圆管,因为圆管在后面,要最先添加;然后才添加floor
    Node *_barContainer;
    
private:
    
    // 每隔 随机的时间,创建并添加一个圆管
    void addTopBar();
    void addBottomBar();
    
    // 临时变量,用于累计 记录 流逝的时间
    int temptimedelta;
    // 总共的时间间隔 (即 时间delta累计到 该间隔时,创建并添加一个圆管)
    int totalIntervalTime;
    
    // 每添加一个新的障碍物之后,需重置 用于累计 记录 流逝的时间 的变量
    void resetTemptimedelta();
    
public:
    // c++里面没有id类型,所以 返回类的实例对象的 指针
    static cocos2d::Scene* createScene();
    // 以下是 不同点:cocos2d-x的 'init' 方法 返回 bool
    // 而cocos2d-iphone 返回 'id' 类型
    virtual bool init();
    // 宏 自动实现 "静态的 create()方法"
    CREATE_FUNC(FlappyBirdScene);
    
    // 时钟方法
    // 在场景的时钟方法中,更新\控制  每一个游戏控制器的时钟方法
    virtual void update(float dt);
    
    // 添加小鸟
    void addBird();
    // 添加地板
    void addFloor();
    
    
    
};

#endif /* defined(___1_cocos2d_x__FlappyBirdScene__) */


//
//  FlappyBirdScene.cpp
//  01_cocos2d-x
//
//  Created by beyond on 14-10-7.
//
//

#include "FlappyBirdScene.h"
#include "GameOverScene.h"



USING_NS_CC;
Scene* FlappyBirdScene::createScene()
{
    // 'scene' 自动释放
    // 使用cocos2d 内置的物理引擎
    auto scene = Scene::createWithPhysics();
    // 显示 调试用的 刚体 边线
    // scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);
    // 调整重力加速度
    scene->getPhysicsWorld()->setGravity(Vec2(0,-1000));
    
    // 'layer' 自动释放
    auto layer = FlappyBirdScene::create();
    // 将图层 添加到场景中
    scene->addChild(layer);
    // 返回 填充好图层的 场景
    return scene;
}

// 在 "init" 方法中,实例化自己要用的精灵对象
bool FlappyBirdScene::init()
{
    // 1. 调用父类的init,cpp 没有super,直接写父类名
    if ( !Layer::init() ) return false;
    // 屏幕尺寸
    winSize = Director::getInstance()->getVisibleSize();
    
    
    // 2.添加小鸟
    addBird();
    // 2.添加地板
    addFloor();
    

    // 初始化时,添加一个新的圆管
    temptimedelta = totalIntervalTime;
    
    // 开启消息调度
    scheduleUpdate();
    // ********************************************
    // 物理碰撞检测 「PhysicsContact」
    auto listener = EventListenerPhysicsContact::create();
    // 开始碰撞 游戏结束
    listener->onContactBegin = [this](PhysicsContact & contact){

        // 取消 消息调度
        this->unscheduleUpdate();
        // 切换至Game Over场景
        Director::getInstance()->replaceScene(GameOverScene::createScene());
        return true;
    };
    // 向事件分发器,注册listener
    Director::getInstance()->getEventdispatcher()->addEventListenerWithSceneGraPHPriority(listener,this);
    // ********************************************
    // 用户单点触摸 jump high 【TouchOneByOne】
    auto touchListener = EventListenerTouchOneByOne::create();
    // 开始触摸 原地 跳一下
    touchListener->onTouchBegan = [this](Touch * t,Event * e){
        // 每点一下,原地跳一下
        bird->getPhysicsBody()->setVeLocity(Vec2(0,400));
        log(">>>click<<<");
        return false;
    };
    // 向事件分发器,注册listener
    Director::getInstance()->getEventdispatcher()->addEventListenerWithSceneGraPHPriority(touchListener,this);
    return true;
}

// 在 "init" 方法中,添加小鸟
void FlappyBirdScene::addBird()
{
    //**************************************
    bird = FlappyBird::create();
    // 屏幕中间
    bird->setPosition(winSize.width/2,winSize.height/2);
    // 添加到Layer
    addChild(bird);
}
// 在 "init" 方法中,添加地板
void FlappyBirdScene::addFloor()
{
    //**************************************
    floor = Floor::create();
    // 屏幕底部
    floor->setPosition(winSize.width/2,floor->getContentSize().height/2);
    // 添加到Layer
    addChild(floor);
}
#pragma mark - 时钟方法
void FlappyBirdScene::update(float dt)
{
    // 每隔一段时间,添加 上圆管和下圆管
    // 临时变量,用于累计 记录 流逝的时间
    temptimedelta++;
    // 总共的时间间隔 (即 时间delta累计到 该间隔时,创建并添加一个障碍物)
    if (temptimedelta >= totalIntervalTime)
    {
        // 每添加一个新的障碍物之后,需重置 用于累计 记录 流逝的时间 的变量
        resetTemptimedelta();
        // 每隔 随机的时间,创建并添加一个障碍物
        addBottomBar();
        addTopBar();

    }
}
// 每添加一个新的障碍物之后,需重置 用于累计 记录 流逝的时间 的变量
void FlappyBirdScene::resetTemptimedelta()
{
    temptimedelta = 0;
    totalIntervalTime = (rand()%50) + 20;
}
// 创建 并 添加 底部圆管  (在随机的 时间 间隔 之后 )
void FlappyBirdScene::addBottomBar()
{
    bottomBar = BottomBar::create();
    addChild(bottomBar);
    // 屏幕外
    bottomBar->setPositionX(winSize.width );
    // 注意 底部圆管的y值是 在地板之上
    // 即 bottomBar的半高
    bottomBar->setPositionY(bottomBar->getContentSize().height/2 + floor->getContentSize().height);
}
// 创建 并 添加 顶部圆管  (在随机的 时间 间隔 之后 )
void FlappyBirdScene::addTopBar()
{
    // 开口大小 为 70 ~ 130
    int margin = (rand()%60) + 70;
    
    topBar = TopBar::create();
    addChild(topBar);
    // 屏幕外
    topBar->setPositionX(winSize.width );
    // 注意 顶部圆管的y值是
    // 即 底部圆管的高 + 400 + 自己的半高 + 地板的高
    topBar->setPositionY(topBar->getContentSize().height/2 + margin +bottomBar->getContentSize().height +floor->getContentSize().height);
}


封闭的精灵
Bird
//
//  FlappyBird.h
//  01_cocos2d-x
//
//  Created by beyond on 14-10-7.
//
//

#ifndef ___1_cocos2d_x__FlappyBird__
#define ___1_cocos2d_x__FlappyBird__

#include <cocos2d.h>

USING_NS_CC;

class FlappyBird:public Sprite {
    
public:
    // 宏,静态的create方法,内部会调用init方法
    CREATE_FUNC(FlappyBird);
    virtual bool init();
    
};

#endif /* defined(___1_cocos2d_x__FlappyBird__) */


//
//  FlappyBird.cpp
//  01_cocos2d-x
//
//  Created by beyond on 14-10-7.
//
//

#include "FlappyBird.h"


bool FlappyBird::init()
{
    // 父类的init方法
    Sprite::init();
    // 执行 帧动画 一直拍打翅膀 扑腾着飞 RepeatForever
    setTexture("bird.png");
    // 图片的尺寸
    Size s = Size(34,34);
    // 精灵的大小
    setContentSize(s);
    
    // 设置物理世界的刚体body
    setPhysicsBody(PhysicsBody::createBox(s));
    // 刚体不允许 旋转
    getPhysicsBody()->setRotationEnable(false);
    // 重要~~~若想参与 碰撞,必须绑定一个碰撞标识
    getPhysicsBody()->setContactTestBitmask(1);
    
    return true;
}


地板Floor
//
//  Floor.h
//  01_cocos2d-x
//
//  Created by beyond on 14-10-7.
//
//  地板

#ifndef ___1_cocos2d_x__Floor__
#define ___1_cocos2d_x__Floor__

#include <cocos2d.h>

USING_NS_CC;

class Floor:public Sprite {
    
public:
    // 宏,内部会调用init方法
    CREATE_FUNC(Floor);
    virtual bool init();
    
};

#endif /* defined(___1_cocos2d_x__Floor__) */


//
//  Floor.cpp
//  01_cocos2d-x
//
//  Created by beyond on 14-10-7.
//
//

#include "Floor.h"

bool Floor::init()
{
    // 父类的init方法
    Sprite::init();
    // 地板图片
    setTexture("floor.png");
    // 图片的尺寸
    Size s = Size(640,208);
    // 精灵的大小
    setContentSize(s);

    // 设置物理世界的刚体body
    setPhysicsBody(PhysicsBody::createBox(s));
    // 刚体不允许 旋转
    getPhysicsBody()->setRotationEnable(false);
    // 重要~~~若想参与 碰撞,必须绑定一个碰撞标识
    getPhysicsBody()->setContactTestBitmask(1);
    // 不是动态的刚体 即:是静态的刚体
    getPhysicsBody()->setDynamic(false);


    // *****************************
    // 播放帧动画
    // 容器,数组,里面存放的是精灵帧
    Vector<SpriteFrame*> vec;
    SpriteFrame *frame1 = SpriteFrame::create("floor.png",Rect(0,640,208));
    SpriteFrame *frame2 = SpriteFrame::create("floor2.png",208));
    // 将小精灵帧  加入容器
    vec.pushBack(frame1);
    vec.pushBack(frame2);
    // 创建 Animation
    Animation *animation = Animation::createWithSpriteFrames(vec,0.1f);
    // 创建 Animate
    Animate *animate = Animate::create(animation);
    // 执行序列帧动画
    Sequence *seq = Sequence::create(animate,animate->reverse(),NULL);
    runAction(RepeatForever::create(seq));
    
    return true;
}


TopBar和BottomBar还可以抽取
//
//  TopBar.h
//  01_cocos2d-x
//
//  Created by beyond on 14-10-7.
//
//  圆管 内部分为上圆管和下圆管

#ifndef ___1_cocos2d_x__TopBar__
#define ___1_cocos2d_x__TopBar__


#include <cocos2d.h>

USING_NS_CC;

class TopBar:public Sprite {
public:
    // 宏,内部会调用init方法
    CREATE_FUNC(TopBar);
    virtual bool init();
    // 时钟方法,内部会 让 障碍物不断地向左移动
    void update(float dt);
};


#endif /* defined(___1_cocos2d_x__TopBar__) */


//
//  TopBar.cpp
//  01_cocos2d-x
//
//  Created by beyond on 14-10-7.
//
//

#include "TopBar.h"


bool TopBar::init()
{
    // 父类的init方法
    Sprite::init();

    setTexture("top_bar2.png");
    // 图片的尺寸
    Size s = Size(52,450);
    // 精灵的大小
    setContentSize(s);
    
    // 设置物理世界的刚体body
    setPhysicsBody(PhysicsBody::createBox(s));
    // 刚体不允许 旋转
    getPhysicsBody()->setRotationEnable(false);
    // 重要~~~若想参与 碰撞,必须绑定一个碰撞标识
    getPhysicsBody()->setContactTestBitmask(1);
    // 不是动态的刚体 即:是静态的刚体
    getPhysicsBody()->setDynamic(false);
    // ***************************************
    // 开启时钟方法
    scheduleUpdate();
    return true;
}
#pragma mark - 时钟方法
// 时钟方法,内部会 让 障碍物不断地向左移动
void TopBar::update(float dt)
{
    this->setPositionX(getPositionX()-20);
    // 移动到屏幕外边时,就停止消息调度,并且移除
    if (getPositionX()<0)
    {
        log("remove top bar");
        unscheduleUpdate();
        removeFromParent();
    }
}


//
//  BottomBar.h
//  01_cocos2d-x
//
//  Created by beyond on 14-10-7.
//
//  圆管 内部分为上圆管和下圆管

#ifndef ___1_cocos2d_x__BottomBar__
#define ___1_cocos2d_x__BottomBar__


#include <cocos2d.h>

USING_NS_CC;

class BottomBar:public Sprite {
public:
    // 宏,内部会调用init方法
    CREATE_FUNC(BottomBar);
    virtual bool init();
    
    // 时钟方法,内部会 让 底部圆管 不断地向左移动
    void update(float dt);
    
};


#endif /* defined(___1_cocos2d_x__BottomBar__) */


//
//  BottomBar.cpp
//  01_cocos2d-x
//
//  Created by beyond on 14-10-7.
//
//

#include "BottomBar.h"


bool BottomBar::init()
{
    // 父类的init方法
    Sprite::init();
    
    setTexture("bottom_bar.png");
    // 图片的尺寸
    Size s = Size(52,319);
    // 精灵的大小
    setContentSize(s);
    
    // 设置物理世界的刚体body
    setPhysicsBody(PhysicsBody::createBox(s));
    // 刚体不允许 旋转
    getPhysicsBody()->setRotationEnable(false);
    // 重要~~~若想参与 碰撞,内部会 让 障碍物不断地向左移动
void BottomBar::update(float dt)
{
    this->setPositionX(getPositionX()-20);
    // 移动到屏幕外边时,并且移除
    if (getPositionX()<0)
    {
        unscheduleUpdate();
        removeFromParent();
    }
}

cocos2d_x_08_游戏_FlappyBird的更多相关文章

  1. ios – 为什么重复创建和删除SKShapeNode和SKNode导致内存泄漏?

    使用Xcode附带的spritekit模板,我修改场景如下:该应用程序似乎继续使用更多内存,直到它挂起或崩溃.使用泄漏和分配工具,我发现了以下内容:泄漏:分配:从图像中可以看出,存在大量使用内存的Malloc调用.我不直接调用Malloc–似乎这些调用是由SpriteKit完成的.同样,存在许多内存泄漏,这似乎也是由于SKShapeNode,SKNode或其他SpriteKit对象造成的.我如何解决或解决此内存(泄漏)问题?

  2. ios – 为什么UIView同时调用init和initWithFrame?

    我注意到当我覆盖init和initWithFrame时:在UIView子类中,两个方法都被调用.即使在我的代码中只有一个是显式调用:TestViewController.m:View1.m:控制台看起来像这样:2013-10-1712:33:46.209test1[8422:60b]initWithFrame2013-10-1712:33:46.211test1[8422:60b]init为什么在

  3. Swift通过类名动态创建对象的方式

    一时并无法回答,因为一看到Swift中NSClassFromString返回的是AnyClass类型,而这个AnyClass类型为publictypealiasAnyClass=AnyObject.Type,这个Type具体是什么呢?当我们修改继承方式,把NSObject改成AnyObject,其结果也一样,AnyObject只是协议,遵守协议。总结:在Swift中,要创建对象有以下几种方式:1、Nsstring.self()//或者Nsstring.self.init()2、letmyClass=MyC

  4. Swift(十、类和结构体)

    实际中,这意味着绝大部分的自定义数据构造都应该是类,而非结构体。Swift管理所有的值拷贝以确保性能最优化,因此没必要去避免赋值以保证最有性能。

  5. Swift中的floor()函数

    floor函数返回的是不大于param的最大整数,看例子:

  6. 早期Swift中Cocos2D初始化代码的重构

    但是遗憾的是Swift2.2中还是不支持Type的class属性关键字,只能用static,我们期待Swift3的改进吧!

  7. swift3.0通过xib实现view

    swift3.0通过xib创建view时,一直crash仔细查找了一下找到一个坑爹得点现在总结出来避免再走弯路一、创建view类和对应的xib文件二、关联xib文件一定是关联file'sOwner上的customclass上。如果关联到view上就会报错三、加载对应的xib界面

  8. 手把手教你swift项目添加cocos2dx-lua

    去倒杯水吧,这个过程会很久。。。至此,工程已经全部配置完毕,你已经解决一个大Boss了;今天就到这里吧,之后我们再续如何用swift调用lua手把手教你swift项目添加cocos2dx-lua

  9. 手把手教你swift项目集成cocos2dx-js模块

    前几天在swift项目中集成了Lua模块,使得在swift工程中用Lua写游戏逻辑成为了可能,具体工程及配置见手把手教你swift项目添加cocos2dx-lua,由于公司最近要把js做的小游戏集成到iOS原生应用中,于是我们将解锁另外一个场景,好了,下面开始;同样的,首先你得有一个swift项目我们从头开始,建立一个swift项目;我们默认你已经可以自己创建一个全新的swift项目了,这很简单,不是么?

  10. 字符串 – Swift init(count :, repeatedValue :)是否工作?

    看来你必须明确地将一个Character类型传递给它才能运行。这对我有用尽管如此,也可能存在与此相关的错误。我相信你这样做的方式本身应该是有效的。我似乎完全没有在这个初始化程序上完成代码。

随机推荐

  1. 【cocos2d-x 3.x 学习笔记】对象内存管理

    Cocos2d-x的内存管理cocos2d-x中使用的是上面的引用计数来管理内存,但是又增加了一些自己的特色。cocos2d-x中通过Ref类来实现引用计数,所有需要实现内存自动回收的类都应该继承自Ref类。下面是Ref类的定义:在cocos2d-x中创建对象通常有两种方式:这两中方式的差异可以参见我另一篇博文“对象创建方式讨论”。在cocos2d-x中提倡使用第二种方式,为了避免误用第一种方式,一般将构造函数设为protected或private。参考资料:[1]cocos2d-x高级开发教程2.3节[

  2. 利用cocos2dx 3.2开发消灭星星六如何在cocos2dx中显示中文

    由于编码的不同,在cocos2dx中的Label控件中如果放入中文字,往往会出现乱码。为了方便使用,我把这个从文档中获取中文字的方法放在一个头文件里面Chinese.h这里的tex_vec是cocos2dx提供的一个保存文档内容的一个容器。这里给出ChineseWords,xml的格式再看看ChineseWord的实现Chinese.cpp就这样,以后在需要用到中文字的地方,就先include这个头文件然后调用ChineseWord函数,获取一串中文字符串。

  3. 利用cocos2dx 3.2开发消灭星星七关于星星的算法

    在前面,我们已经在GameLayer中利用随机数初始化了一个StarMatrix,如果还不知道怎么创建星星矩阵请回去看看而且我们也讲了整个游戏的触摸事件的派发了。

  4. cocos2dx3.x 新手打包APK注意事项!

    这个在编译的时候就可以发现了比较好弄这只是我遇到的,其他的以后遇到再补充吧。。。以前被这两个问题坑了好久

  5. 利用cocos2dx 3.2开发消灭星星八游戏的结束判断与数据控制

    如果你看完之前的,那么你基本已经拥有一个消灭星星游戏的雏形。开始把剩下的两两互不相连的星星消去。那么如何判断是GameOver还是进入下一关呢。。其实游戏数据贯穿整个游戏,包括星星消除的时候要加到获得分数上,消去剩下两两不相连的星星的时候的加分政策等,因此如果前面没有做这一块的,最好回去搞一搞。

  6. 利用cocos2dx 3.2开发消灭星星九为游戏添加一些特效

    needClear是一个flag,当游戏判断不能再继续后,这个flag变为true,开始消除剩下的星星clearSumTime是一个累加器ONE_CLEAR_TIME就是每颗星星消除的时间2.连击加分信息一般消除一次星星都会有连击信息和加多少分的信息。其实这些combo标签就是一张图片,也是通过控制其属性或者runAction来实现。源码ComboEffect.hComboEffect.cpp4.消除星星粒子效果消除星星时,为了实现星星爆裂散落的效果,使用了cocos2d提供的粒子特效引擎对于粒子特效不了

  7. 02 Cocos2D-x引擎win7环境搭建及创建项目

    官网有搭建的文章,直接转载记录。环境搭建:本文介绍如何搭建Cocos2d-x3.2版本的开发环境。项目创建:一、通过命令创建项目前面搭建好环境后,怎样创建自己的Cocos2d-x项目呢?先来看看Cocos2d-x3.2的目录吧这就是Cocos2d-x3.2的目录。输入cocosnew项目名–p包名–lcpp–d路径回车就创建成功了例如:成功后,找到这个项目打开proj.win32目录下的Hello.slnF5成功了。

  8. 利用cocos2dx 3.2开发消灭星星十为游戏添加音效项目源码分享

    一个游戏,声音也是非常的重要,其实cocos2dx里面的简单音效引擎的使用是非常简单的。我这里只不过是用一个类对所有的音效进行管理罢了。Audio.hAudio.cpp好了,本系列教程到此结束,第一次写教程如有不对请见谅或指教,谢谢大家。最后附上整个项目的源代码点击打开链接

  9. 03 Helloworld

    程序都有一个入口点,在C++就是main函数了,打开main.cpp,代码如下:123456789101112131415161718#include"main.h"#include"AppDelegate.h"#include"cocos2d.h"USING_NS_CC;intAPIENTRY_tWinMain{UNREFERENCED_ParaMETER;UNREFERENCED_ParaMETER;//createtheapplicationinstanceAppDelegateapp;return

  10. MenuItemImage*图标菜单创建注意事项

    学习cocos2dx,看的是cocos2d-x3.x手游开发实例详解,这本书错误一大把,本着探索求知勇于发现错误改正错误的精神,我跟着书上的例子一起调试,当学习到场景切换这个小节的时候,出了个错误,卡了我好几个小时。

返回
顶部