一、引言
在上一节当中,我们分析了游戏层跟控制层的关系,而在这一节当中,我们将会详细介绍游戏层(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;
}