雕刻时光

just do it……nothing impossible
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

基于 cocos2dx的 Flappy Bird 的主要代码

Posted on 2014-04-10 17:20  huhuuu  阅读(634)  评论(0)    收藏  举报

  大致流程是,创建一个窗口,在里面添加精灵(背景,小鸟,地板,水管),然后设置物理世界(小鸟的为受重力影响的,其他的精灵不受重力影响),然后在设置碰撞时的情况(小鸟与地板,水管相撞的话,就game over),再设置鼠标的点击事件(点击一次小鸟就上升一段距离)。

 

主类中的变量方法:

class HelloWorld : public cocos2d::CCLayer,public b2ContactListener
{
public:
    cocos2d::CCSize screenSize;
//    cocos2d::CCSprite *bird;
    b2World * world;
    B2Sprite *bird2;

    B2Sprite *moon;//增加月球动态移动的效果,后来没用到

    // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
    virtual bool init();  

    // there's no 'id' in cpp, so we recommend returning the class instance pointer
    static cocos2d::CCScene* scene();
    
    // a selector callback
    void menuCloseCallback(CCObject* pSender);
    
    // implement the "static node()" method manually
    CREATE_FUNC(HelloWorld);

    virtual void update(float dt);
    virtual void ccTouchesBegan(CCSet *pTouches,CCEvent *pEvevt); //重写但点击事件
    virtual void BeginContact(b2Contact* contact); //设置小鸟的撞击事件
    //virtual void EndContact(b2Contact* contact);

private:
    void addBird();  //增加小鸟
    void initWorld();  //初始化世界,这里主要初始化一个物理的世界
    void addGround();  //增加地板
    void addBar(float dt);  // 增加管道  
    void startGame();   //开始游戏
    void endGame();    // 结束游戏
    void addScore();   //增加分数

    void addBackMap();  // 增加背景
    void addMoon();  //暂时没用

    void addLable();  //不断增减标签,
};

 

类中方法的实现:

CCScene* HelloWorld::scene()
{
    // 'scene' is an autorelease object
    CCScene *scene = CCScene::create();
    
    // 'layer' is an autorelease object
    HelloWorld *layer = HelloWorld::create();

    // add layer as a child to scene
    scene->addChild(layer);

    // return the scene
    return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !CCLayer::init() )
    {
        return false;
    }
    
    screenSize = CCDirector::sharedDirector()->getVisibleSize();
    initWorld();
    addBackMap();
    addBird();

//    addMoon();
    addGround();

    startGame();
    setTouchEnabled(true);

    return true;
}

int score=0;

void HelloWorld::addMoon(){
    moon = B2Sprite::create("c:/moon.png");
    b2BodyDef bodyDef;
    
    bodyDef.type = b2_kinematicBody; // 不受重力影响
    bodyDef.position = b2Vec2(screenSize.width/48-1,screenSize.height/48-1);
    b2Body *backMapBody = world->CreateBody(&bodyDef);

    moon->setPTMRatio(48.0);
    moon->setB2Body(backMapBody);
    addChild(moon);
}

void HelloWorld::addBackMap(){
    B2Sprite *backMap = B2Sprite::create("c:/back_map.png");
    b2BodyDef bodyDef;
    
    bodyDef.type = b2_staticBody; //
    bodyDef.position = b2Vec2(screenSize.width/2/48,screenSize.height/2/48);
    b2Body *backMapBody = world->CreateBody(&bodyDef);

    backMap->setPTMRatio(48.0);
    backMap->setB2Body(backMapBody);
    addChild(backMap);
}


void HelloWorld::addLable(){
    char str[9];
    itoa(score/60,str,10);
    

    static CCLabelTTF* prem_label=NULL;
    if((score%60) == 0){ //每60秒改变一下标签
        if(prem_label != 0) prem_label->removeFromParent();//删除上一个标签
        
        cocos2d::CCLabelTTF* m_label = cocos2d::CCLabelTTF::create(str,"Arial",28);
        m_label->setPosition(ccp(screenSize.width/2,screenSize.height*3/4));
        m_label->setColor( ccBLUE );
        addChild(m_label);

        prem_label = m_label;
    }
}

void HelloWorld::addScore(){
    score++;
}

void HelloWorld::ccTouchesBegan(CCSet *pTouches,CCEvent *pEvevt){
    bird2->getB2Body()->SetLinearVelocity(b2Vec2(0,5));//触发点击事件以后,小鸟向上飞5个单位
}

void HelloWorld::initWorld(){
    world = new b2World(b2Vec2(0,-10));//创造一个水平方向加速度为0,垂直方向加速度为-10,‘-’表示方向垂直向下

    world->SetContactListener(this);
}

void HelloWorld::addBird(){

    bird2 = B2Sprite::create("c:/bird.png");
    b2BodyDef bodyDef;
    
    bodyDef.type = b2_dynamicBody; //动态变化,会受到重力影响
    bodyDef.position = b2Vec2(screenSize.width/2/48,9);
    b2Body *birdBody = world->CreateBody(&bodyDef);

    CCSize size = bird2->getContentSize();
    b2PolygonShape birdShape;
    birdShape.SetAsBox(size.width/2/48.0,size.height/2/48.0);

    b2FixtureDef birdFixtureDef;
    birdFixtureDef.shape = &birdShape;
    birdBody->CreateFixture(&birdFixtureDef);

    bird2->setPTMRatio(48.0);
    bird2->setB2Body(birdBody);
    addChild(bird2);
}

void HelloWorld::addGround(){
    B2Sprite *ground = B2Sprite::create("c:/ground.png");
    CCSize size = ground->getContentSize();

    b2BodyDef bDef;
    bDef.type = b2_staticBody; //静态,静止不动
    bDef.position = b2Vec2(size.width/2/48.0,size.height/2/48.0);
    b2Body *groundBody = world->CreateBody(&bDef);

    b2PolygonShape groundShape;
    groundShape.SetAsBox(size.width/2/48.0,size.height/2/48.0);
    b2FixtureDef groundFixtureDef;
    groundFixtureDef.shape = &groundShape;
    groundBody->CreateFixture(&groundFixtureDef);

    ground->setB2Body(groundBody);
    ground->setPTMRatio(48.0);
    addChild(ground);
}

void HelloWorld::addBar(float dt){
    
    float rand_lenth=rand()%4;
    //down
    B2Sprite *down_bar = B2Sprite::create("c:/bar_down.png");
    CCSize down_bar_size = down_bar->getContentSize();

    b2BodyDef down_bar_body_def;
    down_bar_body_def.type = b2_kinematicBody;
    down_bar_body_def.position = b2Vec2(screenSize.width/48.0+2,
        down_bar_size.height/48.0/2 - rand_lenth
        );
    down_bar_body_def.linearVelocity = b2Vec2(-5,0);//棍的运行速度
    b2Body *down_bar_body = world->CreateBody(&down_bar_body_def);

    b2PolygonShape down_bar_shape;
    down_bar_shape.SetAsBox(down_bar_size.width/2/48.0,
        down_bar_size.height/2/48.0
        );
    b2FixtureDef down_bar_fixture_def;
    down_bar_fixture_def.shape = &down_bar_shape;
    down_bar_body->CreateFixture(&down_bar_fixture_def);

    down_bar->setB2Body(down_bar_body);
    down_bar->setPTMRatio(48.0);
    addChild(down_bar);

    //up
    B2Sprite *up_bar = B2Sprite::create("c:/bar_up.png");
    CCSize up_bar_size = up_bar->getContentSize();

    b2BodyDef up_bar_body_def;
    up_bar_body_def.type = b2_kinematicBody;
    up_bar_body_def.position = b2Vec2(screenSize.width/48.0+2,
            screenSize.height/48.0/2 + down_bar_size.height/48.0/2 - rand_lenth + 3
        );
    up_bar_body_def.linearVelocity = b2Vec2(-5,0);//棍的运行速度
    b2Body *up_bar_body = world->CreateBody(&up_bar_body_def);

    b2PolygonShape up_bar_shape;
    up_bar_shape.SetAsBox(up_bar_size.width/2/48.0,
        up_bar_size.height/2/48.0
        );
    b2FixtureDef up_bar_fixture_def;
    up_bar_fixture_def.shape = &up_bar_shape;
    up_bar_body->CreateFixture(&up_bar_fixture_def);

    up_bar->setB2Body(up_bar_body);
    up_bar->setPTMRatio(48.0);
    addChild(up_bar);
}

void HelloWorld::update(float dt){
    world->Step(dt,8,3);

    addScore();
    addLable();
    //销毁标签

    //销毁棍子对象
    cocos2d::CCSprite *s;
    for(b2Body *b = world ->GetBodyList();b!=NULL;){
        
        b2Body *tempb;
        tempb=b;
        b=b->GetNext();

        if(tempb->GetPosition().x<-3){
            s=(CCSprite *)tempb->GetUserData();
            if(s!=NULL){
                s->removeFromParent();
            }
            world->DestroyBody(tempb);
        }
    }
}

void HelloWorld::BeginContact(b2Contact* contact){ //小鸟受到撞击的时候,游戏结束,显示分数状态
    if (contact->GetFixtureA()->GetBody()->GetUserData() == bird2 ||
         contact->GetFixtureB()->GetBody()->GetUserData() == bird2){
        endGame();

        char str[9];
        itoa(score/60,str,10);
        char showScore[90]="得分:";
        strcat(showScore,str);

        CCMessageBox(showScore,"状态!");
    }
}

void HelloWorld::startGame(){
    //HelloWorld::score2++;

    scheduleUpdate();//不断执行update的方法
    schedule(schedule_selector(HelloWorld::addBar),1);//没隔一秒就加一根棍
}

void HelloWorld::endGame(){
    unscheduleUpdate();//结束 不断执行update的方法
    unschedule(schedule_selector(HelloWorld::addBar)); //结束 没隔一秒就加一根棍
}

void HelloWorld::menuCloseCallback(CCObject* pSender)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
    CCMessageBox("You pressed the close button. Windows Store Apps do not implement a close button.","Alert");
#else
    CCDirector::sharedDirector()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    exit(0);
#endif
#endif
}
View Code