Cocos2d-x 3.x《飞机大战》教程6:游戏结束场景

2015年03月18日 10:05 1 点赞 0 评论 更新于 2025-11-21 13:52

最后一步是实现游戏结束场景,该场景与第一个HelloWorld场景较为相似,主要区别在于修改了背景图片、移除了飞机,并添加了用于显示分数和最高分的标签。下面将详细介绍其实现方法。

1. 创建文件

首先,创建GameOverScene.cpp文件和GameOverScene.h文件。头文件的声明如下:

// 创建场景的方法,将当前的层封装成Scene返回,注意这是一个静态方法
static cocos2d::Scene* createScene();

// 层初始化时调用
virtual bool init();

// 一个宏,用于层的创建
CREATE_FUNC(GameOverScene);

// 菜单项开始游戏的回调方法
void continueGame(cocos2d::Ref* pSender);

// 菜单项退出游戏的回调方法
void exitGame(cocos2d::Ref* pSender);

上述代码中的方法都是Cocos2d固定的场景创建方法,之前已经使用过,这里不再赘述。接下来是具体的实现部分。

2. 实现init方法

bool GameOverScene::init()
{
if (!Layer::init())
{
return false;
}

// 获取可见区域的大小和原点
Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();

// 创建背景
auto bg = Sprite::create("gameover.png");
bg->setPosition(Vec2(origin.x + visibleSize.width / 2, visibleSize.height / 2));
bg->setAnchorPoint(Vec2(0.5, 0.5));
this->addChild(bg, 0);

// 读取出上个场景存储的分数和最高分数
int currentScore = UserDefault::getInstance()->getIntegerForKey("currentScore");
int topScore = UserDefault::getInstance()->getIntegerForKey("topScore");

// 显示最终分数
auto label = cocos2d::Label::createWithSystemFont(__String::createWithFormat("%d", currentScore)->getCString(), "Arial", 24);
label->setPosition(Vec2(visibleSize.width / 2, origin.y + visibleSize.height / 2 + 60));
label->setHorizontalAlignment(kCCTextAlignmentRight);
label->setAnchorPoint(Vec2(0.5, 0.5));
this->addChild(label, 1);

// 显示最高分数
auto label2 = cocos2d::Label::createWithSystemFont(__String::createWithFormat("%d", topScore)->getCString(), "Arial", 24);
label2->setPosition(Vec2(visibleSize.width / 2, origin.y + visibleSize.height - label2->getContentSize().height));
label2->setHorizontalAlignment(kCCTextAlignmentRight);
label2->setAnchorPoint(Vec2(0.5, 0.5));
this->addChild(label2, 1);

// 继续游戏菜单项
auto startItem = MenuItemImage::create("game_start.png", "game_start2.png", CC_CALLBACK_1(GameOverScene::continueGame, this));
startItem->setPosition(Vec2(visibleSize.width / 2 + origin.x, visibleSize.height / 2 + origin.y));

// 退出游戏菜单项
auto closeItem = MenuItemImage::create("game_exit.png", "game_exit2.png", CC_CALLBACK_1(GameOverScene::exitGame, this));
closeItem->setPosition(Vec2(origin.x + visibleSize.width / 2, visibleSize.height / 2 + origin.y - startItem->getContentSize().height));

// 把菜单项添加到菜单精灵中
auto menu = Menu::create(startItem, closeItem, NULL);
menu->setPosition(Vec2::ZERO);

// 把菜单精灵添加到当前的层中
this->addChild(menu, 1);

return true;
}

3. 实现回调函数

继续游戏菜单项的回调函数

void GameOverScene::continueGame(Ref* pSender)
{
// 进入游戏场景
auto scene = GameScene::createScene();
// 场景切换的方式
auto gameScene = TransitionSlideInR::create(1.0f, scene);
// 切换场景
Director::getInstance()->replaceScene(gameScene);
}

退出游戏的回调方法

void GameOverScene::exitGame(Ref* pSender)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT)
MessageBox("You pressed the close button. Windows Store Apps do not implement a close button.", "Alert");
return;
#endif
// 退出
Director::getInstance()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
}

4. 在GameScene中添加场景切换代码

最后,别忘了在GameScene的游戏结束逻辑处添加场景切换代码。

// 游戏结束
void GameScene::gameOver()
{
auto scene = GameOverScene::createScene();
auto gameOverScene = TransitionTurnOffTiles::create(1.0f, scene);
Director::getInstance()->replaceScene(gameOverScene);
}

至此,整个游戏的核心模块已经完成。当然,该游戏还有许多可以完善的地方,有兴趣的同学可以自行进行优化。下面我们将查看整个游戏的运行过程。

后续我会把学习Cocos2d-x过程中遇到的疑难杂症发布到博客上,欢迎大家一起讨论学习。

相关教程