一、引言
在上一節當中,我們分析了遊戲層跟控制層的關系,而在這一節當中,我們将會詳細介紹遊戲層(GameLayer)的具體實作。
二、遊戲層的基本結構
單遊戲層來說,它包括兩個元素:
1、小鳥
2、障礙物(水管)
遊戲層的操作:
1、遊戲狀态的表示
2、添加小鳥和水管
3、分數的實時統計
4、碰撞的檢測
三、遊戲狀态的表示
采用枚舉類型表示遊戲的三種狀态:準備狀态、遊戲進行狀态、遊戲結束狀态
/**
* Define the game status
* GAME_STATUS_READY game is not start, just ready for payer to start.
* GAME_STATUS_START the game is started, and payer is paying this game.
* GAME_STATUS_OVER the player is lose this game, the game is over.
*/
typedef enum _game_status {
GAME_STATUS_READY = 1,
GAME_STATUS_START,
GAME_STATUS_OVER
} GameStatus;
四、添加小鳥
由于前面的鋪墊,小鳥類的單獨封裝,是以在這裡,我們添加一直小鳥就變得非常簡單了。
首先,在GameLayer聲明了這隻小鳥
BirdSprite *bird;
然後再設定這支小鳥的基本屬性
this->bird->setPhysicsBody(body);
this->bird->setPosition(origin.x + visiableSize.width*1/3 - 5,origin.y + visiableSize.height/2 + 5);
this->bird->idle();
最後添加這支小鳥到遊戲層中
this->addChild(this->bird);
五、水管的添加
水管的添加,主要是通過createPips()函數來生成水管,有關水管的詳細生成過程将在後續章節讨論
六、遊戲分數的更新
void GameLayer::checkHit() {
for(auto pip : this->pips) {
if (pip->getTag() == PIP_NEW) {
if (pip->getPositionX() < this->bird->getPositionX()) {
SimpleAudioEngine::getInstance()->playEffect("sfx_point.ogg");
this->score ++;
this->delegator->onGamePlaying(this->score);
pip->setTag(PIP_PASS);
}
}
}
}
1、通過設定水管的Tag來标記水管是否已經被成功通過,初始建立的水管标記為PIP_NEW。
2、通過判斷水管和小鳥的橫坐标來判斷是否成功通過了水管。
3、通過代理将分數傳到ststuslayer,在遊戲狀态層實時更新分數。
七、碰撞檢測
在GameLayer初始化的時候,我們建立了一個碰撞監聽:
auto contactListener = EventListenerPhysicsContact::create();
contactListener->onContactBegin = CC_CALLBACK_2(GameLayer::onContactBegin, this);
this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(contactListener, this);
該監聽的回調函數為GameLayer::onContactBegin,可見一旦出現碰撞,則進入遊戲結束狀态。
bool GameLayer::onContactBegin(EventCustom *event, const PhysicsContact& contact) {
this->gameOver();
return true;
}
八、小結
本節對遊戲層進行了一個詳細的介紹,有關詳細代碼,還請移步到github: https://github.com/OiteBoys/Earlybird