この回ではタイトル画面と画面遷移を実装していきます。画面遷移が実装できれば、リッチなゲームを作りやすくなると思います。
仕様の検討
追加する画面はタイトル画面です。タイトル画面にはスタートボタンを追加し、スタートボタンを押下するとバトル画面に遷移するようにします。
タイトル画面
リソースの追加
いつものようにリソースを追加します。追加するのは以下の画像です。
・タイトル画像
・スタートボタン画像
・スタートボタン画像(押下時)
画像は下記からダウンロードして下さい。
プログラム実装
タイトル画面を実装します。タイトル画面のクラス名は「SCN01_StartScene」です。
クラスの追加方法は第8回 「より保守性のあるプログラムを目指して」を参考にしてください。
SCN01_StartScene.hpp
#ifndef SCN01_StartScene_hpp #define SCN01_StartScene_hpp #include <stdio.h> class SCN01_StartScene : public cocos2d::Layer{ public: // コンストラクタ SCN01_StartScene(); // デストラクタ virtual ~SCN01_StartScene(); static cocos2d::Scene* createScene(); virtual bool init(); // バトル画面に画面遷移 void nextSceneCallback(cocos2d::Ref* pSender); // implement the "static create()" method manually CREATE_FUNC(SCN01_StartScene); }; #endif /* SCN01_StartScene_hpp */
SCN01_StartScene.cpp
#include "SCN01_StartScene.hpp" #include "HelloWorldScene.h" #include "SimpleAudioEngine.h" USING_NS_CC; // コンストラクタ SCN01_StartScene::SCN01_StartScene(){ // do nothing } // デストラクタ SCN01_StartScene::~SCN01_StartScene(){ removeAllChildrenWithCleanup(true); } Scene* SCN01_StartScene::createScene() { // 'scene' is an autorelease object auto scene = Scene::create(); // 'layer' is an autorelease object auto layer = SCN01_StartScene::create(); // add layer as a child to scene scene->addChild(layer); // return the scene return scene; } // on "init" you need to initialize your instance bool SCN01_StartScene::init() { ////////////////////////////// // 1. super init first if ( !Layer::init() ) { return false; } Size visibleSize = Director::getInstance()->getVisibleSize(); // スタートボタンの表示 auto startItem = MenuItemImage::create( "start.png", "start_pushed.png", CC_CALLBACK_1(SCN01_StartScene::nextSceneCallback, this)); startItem->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 4)); auto menu = Menu::create(startItem, NULL); menu->setPosition(Vec2::ZERO); this->addChild(menu, 1, 0); // タイトルの表示 Sprite* title = Sprite::create("title.png"); title->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 10 * 8)); this->addChild(title, 1, 1); // 背景の表示 Sprite* background = Sprite::create("background.png"); background->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2)); this->addChild(background, 0, 2); // 音楽のプリロード CocosDenshion::SimpleAudioEngine::getInstance()->preloadBackgroundMusic("game_maoudamashii_3_theme01.mp3"); // 音楽の演奏 CocosDenshion::SimpleAudioEngine::getInstance()->playBackgroundMusic("game_maoudamashii_3_theme01.mp3", true); return true; } void SCN01_StartScene::nextSceneCallback(Ref* pSender) { // 音楽の停止 CocosDenshion::SimpleAudioEngine::getInstance()->stopBackgroundMusic(); // 画面遷移 Director::getInstance()->replaceScene(TransitionFade::create(0.5 , HelloWorld::createScene() , Color3B::WHITE)); }
・replaceScene
cocos2dxのメソッドで、画面遷移を行います。引数には画面遷移時のエフェクトを指定可能です。
・MenuItemImage::create
cocos2dxのメソッドで、メニューボタンを追加します。この画面におけるメニューボタンの振る舞いは音楽の停止と画面遷移です。
AppDelegate.cpp
#include "AppDelegate.h" #include "HelloWorldScene.h" #include "SCN01_StartScene.hpp" USING_NS_CC; static cocos2d::Size designResolutionSize = cocos2d::Size(480, 320); static cocos2d::Size smallResolutionSize = cocos2d::Size(480, 320); static cocos2d::Size mediumResolutionSize = cocos2d::Size(1024, 768); static cocos2d::Size largeResolutionSize = cocos2d::Size(2048, 1536); AppDelegate::AppDelegate() { } AppDelegate::~AppDelegate() { } //if you want a different context,just modify the value of glContextAttrs //it will takes effect on all platforms void AppDelegate::initGLContextAttrs() { //set OpenGL context attributions,now can only set six attributions: //red,green,blue,alpha,depth,stencil GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8}; GLView::setGLContextAttrs(glContextAttrs); } // If you want to use packages manager to install more packages, // don't modify or remove this function static int register_all_packages() { return 0; //flag for packages manager } bool AppDelegate::applicationDidFinishLaunching() { // initialize director auto director = Director::getInstance(); auto glview = director->getOpenGLView(); if(!glview) { #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) || (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX) glview = GLViewImpl::createWithRect("PuzzleAndStrike", Rect(0, 0, designResolutionSize.width, designResolutionSize.height)); #else glview = GLViewImpl::create("PuzzleAndStrike"); #endif director->setOpenGLView(glview); } // turn on display FPS director->setDisplayStats(true); // set FPS. the default value is 1.0/60 if you don't call this director->setAnimationInterval(1.0 / 60); /* // Set the design resolution glview->setDesignResolutionSize(designResolutionSize.width, designResolutionSize.height, ResolutionPolicy::NO_BORDER); Size frameSize = glview->getFrameSize(); // if the frame's height is larger than the height of medium size. if (frameSize.height > mediumResolutionSize.height) { director->setContentScaleFactor(MIN(largeResolutionSize.height/designResolutionSize.height, largeResolutionSize.width/designResolutionSize.width)); } // if the frame's height is larger than the height of small size. else if (frameSize.height > smallResolutionSize.height) { director->setContentScaleFactor(MIN(mediumResolutionSize.height/designResolutionSize.height, mediumResolutionSize.width/designResolutionSize.width)); } // if the frame's height is smaller than the height of medium size. else { director->setContentScaleFactor(MIN(smallResolutionSize.height/designResolutionSize.height, smallResolutionSize.width/designResolutionSize.width)); } */ glview->setDesignResolutionSize(768.0, 1366.0, ResolutionPolicy::SHOW_ALL); register_all_packages(); // create a scene. it's an autorelease object auto scene = SCN01_StartScene::createScene(); // run director->runWithScene(scene); return true; } // This function will be called when the app is inactive. When comes a phone call,it's be invoked too void AppDelegate::applicationDidEnterBackground() { Director::getInstance()->stopAnimation(); // if you use SimpleAudioEngine, it must be pause // SimpleAudioEngine::getInstance()->pauseBackgroundMusic(); } // this function will be called when the app is active again void AppDelegate::applicationWillEnterForeground() { Director::getInstance()->startAnimation(); // if you use SimpleAudioEngine, it must resume here // SimpleAudioEngine::getInstance()->resumeBackgroundMusic(); }
プログラム解説
SCN01_StartScene
このクラス自体はcocos2dxのサンプルコードであるHelloWorldSceneとほとんど同じです。今回使用したReplaceSceneについて解説します。
・ReplaceScene(TransitionFade)
Director::getInstance()->replaceScene(TransitionFade::create(0.5 , HelloWorld::createScene() , Color3B::WHITE));
第一引数:画面遷移する時間を指定します。上記では0.5を指定しています。
第二引数:画面(シーン)を作成するメソッドを指定します。
第三引数:フェードアウトする際の色を指定します。
TransitionFadeはフェードアウトするエフェクトです。この他にもエフェクトは多数存在し、ググると色々なエフェクトが出てくると思います。
また、今回のポイントである「デストラクタ」、及び「removeAllChildrenWithCleanup(true)」を紹介していきます。
・デストラクタ
C++で使用される特別なメソッドで、オブジェクトが破棄されるときに実行されます。cocos2dxでは「replaceScene」を行った時にも実行されます。
また、デストラクタと対になるコンストラクタというメソッドも存在ます。コンストラクタはオブジェクトが生成された時に最初に実行されます。
・removeAllChildrenWithCleanup(true)
親クラスにaddChildされた子ノードを全て削除します。このプログラム上で画面遷移を行う際に、不要になったオブジェクトを削除することでメモリリークを防止します。
AppDelegate
アプリを起動した直後に表示するシーンをSCN01_StartSceneにしています。
シミュレータの起動
いつもの通りシミュレータを起動します。スタートボタンを押下するとバトル画面に遷移できれば成功です!!
次回、勝利演出、敗北演出を追加して完成です!!
次回
いつも勉強させていただいて、ありがとうございます。
このページから最終回へのリンクが貼られていません。
(最終回はググってたどり着きました)
よろしくご確認ください。
ご連絡ありがとうございます。
リンクを追加修正しました。