制作横版游戏KillBear第10课:开始界面

2015年03月22日 09:44 0 点赞 0 评论 更新于 2025-11-21 18:04

上一课,我们主要为游戏添加了暂停功能。具体而言,是在游戏层的右上角添加了一个按钮,用于实现暂停游戏的功能。在本篇文章中,我们将创建游戏的开始界面,该界面可供玩家选择开始游戏或者退出游戏。

开发环境

  • 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;
}
}

需要注意的点

  1. 结束游戏Director::getInstance()->end(); 用于结束整个游戏。
  2. 按钮回调:以下两段代码功能相同,只是实现方式不同。一段是直接在后面添加并编写当前回调函数,另一段是回调已经写好的函数。
    • 直接编写回调函数:
      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;
      }
      }
      
  3. 场景切换Director::getInstance()->replaceScene(TransitionCrossFade::create(0.5f, GameScene::createScene())); 这一句调用已经写好的场景切换动画来实现场景切换。
  4. 按钮状态判定:在使用 Button 时,需要特别注意添加按键判定。因为 Button 点击一次有两种状态:BeganEnded。如果忘记添加判定,可能会导致在点击一次的情况下函数调用两次。本人在使用过程中就因为这个低级错误卡了半个小时,希望各位特别关注。Button 不同于 Menu,自己编写回调代码时需要格外留意。

AppDelegate的修改

当游戏刚开始时,若希望载入的是 GameStartScene 而不是 GameScene,需要在 AppDelegate 中进行修改,并且在文件最上方包含 GameStartScene.h

AppDelegate.cpp

#include "GameStartScene.h"
// ...
auto scene = GameStartScene::createScene();
director->runWithScene(scene);

结语

本篇文章非常简单地创建了一个开始界面。在下一篇文章中,我们将通过 ScrollView 创建关卡选择界面(之所以不使用 PageView,是因为需要触摸回弹并利用 ScrollView 的动画回弹效果)。

作者信息

boke

boke

共发布了 3994 篇文章