zoukankan      html  css  js  c++  java
  • cocos2d_x_08_游戏_FlappyBird

    终于效果图:

    环境版本号: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:
        // 宏,静态的create方法,内部会调用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, 0, 640, 208));
        SpriteFrame *frame2 = SpriteFrame::create("floor2.png", Rect(0, 0, 640, 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:
        // 宏,静态的create方法,内部会调用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:
        // 宏,静态的create方法,内部会调用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);
        // 重要~~~若想參与 碰撞,必须绑定一个碰撞标识
        getPhysicsBody()->setContactTestBitmask(1);
        // 不是动态的刚体 即:是静态的刚体
        getPhysicsBody()->setDynamic(false);
        // ***************************************
        // 开启时钟方法
        scheduleUpdate();
        return true;
    }
    #pragma mark - 时钟方法
    // 时钟方法,内部会 让 障碍物不断地向左移动
    void BottomBar::update(float dt)
    {
        this->setPositionX(getPositionX()-20);
        // 移动到屏幕外边时,就停止消息调度,而且移除
        if (getPositionX()<0)
        {
            unscheduleUpdate();
            removeFromParent();
        }
    }



  • 相关阅读:
    页面定制CSS代码
    记录-20190511
    Java集合
    EL表达式
    javabean
    写一篇博文介绍JSP
    编写一篇博文介绍COOKIE和Session的原理及异同
    过滤器的使用
    Java种的String
    Java包装类
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5338344.html
Copyright © 2011-2022 走看看