制作横版游戏KillBear第10课:开始界面
上一课,我们主要为游戏添加了暂停功能。具体而言,是在游戏层的右上角添加了一个按钮,用于实现暂停游戏的功能。在本篇文章中,我们将创建游戏的开始界面,该界面可供玩家选择开始游戏或者退出游戏。
开发环境
- Win64 : vs2010
- Cocos2d-x v3.4Final
- TexturePackerGUI
- MapEdit
开始界面的设计
我们将简单地制作一个开始界面,这需要以下元素:
- 背景:在本例中,我们使用一张已制作好的图片作为开始界面的背景。
- 按钮:放置3个按钮,分别为“开始游戏”“游戏设置”“结束游戏”,并通过回调
Scene来处理这些按钮的点击事件。
代码实现
GameStartScene.h
#ifndef _GAME_START_SCENE_H_
#define _GAME_START_SCENE_H_
#include "cocos2d.h"
USING_NS_CC;
#include "GameScene.h"
#include "ui/CocosGUI.h"
#include "BarrierLayer.h"
using namespace ui;
class GameStartScene : public Layer {
public:
static cocos2d::Scene* createScene();
virtual bool init();
void StartGameCallBack(Ref *pSender, Widget::TouchEventType type);
void SettingCallBack(Ref *pSender, Widget::TouchEventType type);
void CloseGameCallBack(Ref *pSender, Widget::TouchEventType type);
CREATE_FUNC(GameStartScene);
};
#endif
GameStartScene.cpp
#include "GameStartScene.h"
#include "PopupLayer.h"
Scene* GameStartScene::createScene() {
auto scene = Scene::create();
auto layer = GameStartScene::create();
scene->addChild(layer);
return scene;
}
bool GameStartScene::init() {
bool ret = false;
do {
Size visibleSize = Director::getInstance()->getVisibleSize();
auto background = Sprite::create("background.png");
addChild(background);
background->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2));
auto start_button = Button::create("button.png");
start_button->setTitleText("Start");
start_button->setTitleFontName("微软雅黑");
start_button->setTitleFontSize(16);
start_button->setPosition(Vec2(visibleSize.width / 2, visibleSize.height * 0.75));
start_button->addTouchEventListener(CC_CALLBACK_2(GameStartScene::StartGameCallBack, this));
addChild(start_button);
auto setting_button = Button::create("button.png");
setting_button->setTitleText("Set");
setting_button->setTitleFontName("微软雅黑");
setting_button->setTitleFontSize(16);
setting_button->setPosition(Vec2(visibleSize.width / 2, visibleSize.height * 0.5));
setting_button->addTouchEventListener(CC_CALLBACK_2(GameStartScene::SettingCallBack, this));
addChild(setting_button);
auto close_button = Button::create("button.png");
close_button->setTitleText("End");
close_button->setTitleFontName("微软雅黑");
close_button->setTitleFontSize(16);
close_button->setPosition(Vec2(visibleSize.width / 2, visibleSize.height * 0.25));
close_button->addTouchEventListener([=](Ref* pSender, Widget::TouchEventType type) {
switch (type) {
case cocos2d::ui::Widget::TouchEventType::ENDED:
Director::getInstance()->end();
break;
}
});
addChild(close_button);
ret = true;
} while (0);
return ret;
}
void GameStartScene::StartGameCallBack(Ref *pSender, Widget::TouchEventType type) {
CCLOG("StartGame");
switch (type) {
case cocos2d::ui::Widget::TouchEventType::ENDED:
Director::getInstance()->replaceScene(TransitionCrossFade::create(0.5f, GameScene::createScene()));
break;
}
}
void GameStartScene::SettingCallBack(Ref *pSender, Widget::TouchEventType type) {
// 目前为空,可根据需求添加功能
}
void GameStartScene::CloseGameCallBack(Ref *pSender, Widget::TouchEventType type) {
switch (type) {
case cocos2d::ui::Widget::TouchEventType::ENDED:
Director::getInstance()->end();
break;
}
}
需要注意的点
- 结束游戏:
Director::getInstance()->end();用于结束整个游戏。 - 按钮回调:以下两段代码功能相同,只是实现方式不同。一段是直接在后面添加并编写当前回调函数,另一段是回调已经写好的函数。
- 直接编写回调函数:
close_button->addTouchEventListener([=](Ref* pSender, Widget::TouchEventType type) { switch (type) { case cocos2d::ui::Widget::TouchEventType::ENDED: Director::getInstance()->end(); break; } }); - 回调已写好的函数:
void GameStartScene::CloseGameCallBack(Ref *pSender, Widget::TouchEventType type) { switch (type) { case cocos2d::ui::Widget::TouchEventType::ENDED: Director::getInstance()->end(); break; } }
- 直接编写回调函数:
- 场景切换:
Director::getInstance()->replaceScene(TransitionCrossFade::create(0.5f, GameScene::createScene()));这一句调用已经写好的场景切换动画来实现场景切换。 - 按钮状态判定:在使用
Button时,需要特别注意添加按键判定。因为Button点击一次有两种状态:Began和Ended。如果忘记添加判定,可能会导致在点击一次的情况下函数调用两次。本人在使用过程中就因为这个低级错误卡了半个小时,希望各位特别关注。Button不同于Menu,自己编写回调代码时需要格外留意。
AppDelegate的修改
当游戏刚开始时,若希望载入的是 GameStartScene 而不是 GameScene,需要在 AppDelegate 中进行修改,并且在文件最上方包含 GameStartScene.h。
AppDelegate.cpp
#include "GameStartScene.h"
// ...
auto scene = GameStartScene::createScene();
director->runWithScene(scene);
结语
本篇文章非常简单地创建了一个开始界面。在下一篇文章中,我们将通过 ScrollView 创建关卡选择界面(之所以不使用 PageView,是因为需要触摸回弹并利用 ScrollView 的动画回弹效果)。