Cocos2d 3.0:簡単な移行ガイドに掲載されていますが、Cocos2d 2.0までメニュー作成にはCCMenuが用意されていましたがCocos2d 3.0CからCCLayoutコンテナを使用し、単にそれにCCButtonsを追加することで簡単に作成できるようになりました。
そこに記載されているObjective-Cの例を動作出来るようにし更に新たにSwiftに変換しました。
完成画面
今回は、SpriteBuilderの画面レイアウトは使いません。
全てCocos2dでのソースコード記述になります。
今までと同じようにSpriteBuilderを起動し新規プロジェクトを作成します。
「SpriteBuilder」のラベルを削除し「Publishing」のボタンをクリックしてそのまま「Seve All」をクリックしてください。後はXcodの記述のみです。
Objective-C 言語
MainScene.mを次のように変更してみてください。
#import "MainScene.h"
@implementation MainScene
-(void) didLoadFromCCB
{
// メニュー表示
CCLabelTTF *label = [CCLabelTTF labelWithString:@"メニュー"
fontName:@"Arial"
fontSize:24];
// フォントカラー
label.fontColor = [CCColor whiteColor];
// 座標系が異なります。UIKitは左上が(0,0)、cocos2dは左下が(0,0)です。
label.position = ccp(285, 220);
// label表示
[self addChild:label];
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// アクションメニューボタンの作成記述
// first buttonの生成
CCButton *calculationButton = [CCButton buttonWithTitle:@"計算ボタン"];
[calculationButton setTarget:self
selector:@selector(calculationButtonTouched:)];
// second buttonの生成
CCButton *animationButton =
[CCButton buttonWithTitle:@"アニメーションボタン"];
[animationButton setTarget:self
selector:@selector(animateButtonTouched:)];
// layoutboxの生成
CCLayoutBox *layoutBox = [[CCLayoutBox alloc] init];
// layoutBoxアンカーポイント 中央
layoutBox.anchorPoint = ccp(0.5, 0.5);
// calculationStepButtonをレイアウトに追加
[layoutBox addChild:calculationButton];
// animationButtonをレイアウトに追加
[layoutBox addChild:animationButton];
// 上部ボタンとの空白
layoutBox.spacing = 20.f;
// Vertical:垂直に整列
layoutBox.direction = CCLayoutBoxDirectionVertical;
// layoutBoxにlayout
[layoutBox layout];
// cocos2dではCCDirectorを使ってウィンドウサイズを取得
CGSize size = [[CCDirector sharedDirector] designSize];
// ログで幅と高さのサイズ確認
NSLog(@"幅 高さ %f %f", size.width, size.height);
// layoutBoxの表示位置を中央 幅:半分 高さ:半分
layoutBox.position = ccp(size.width / 2, size.height / 2);
// layoutBoxを表示
[self addChild:layoutBox];
}
// 計算ボタンのアクション
-(void)calculationButtonTouched:(CCButton*)sender
{
NSLog(@"計算");
}
// アニメーションボタンのアクション
-(void)animateButtonTouched:(CCButton*)sender
{
NSLog(@"アニメーション");
}
@end
※メニューの追加について
3つ目のメニュー追加したい場合は下記の記述で追加できます。
画面上に3つのメニュー項目が並びます。簡単ですね。
// third buttonの生成
CCButton *animationButton =
[CCButton buttonWithTitle:@"⚪️⚪️ゲーム"];
[animationButton setTarget:self
selector:@selector(gameButtonTouched:)];
// gameButtonをレイアウトに追加
[layoutBox addChild:animationButton];
// ゲームボタンのアクション
-(void)gameButtonTouched:(CCButton*)sender
{
NSLog(@"⚪️⚪️ゲーム");
}
GitHub Menu01_Objective-C
Swift 言語
MainScene.swiftを次のように変更してみてください。
import Foundation
class MainScene: CCNode {
// ラベルの設定
var label: CCLabelTTF!
override func onEnter() {
label = CCLabelTTF(string: "a", fontName: "Arial", fontSize: 50)
label.string = "メニュー"
label.fontColor = CCColor.whiteColor()
label.position = ccp(280, 240)
self.addChild(label)
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// メニューボタンの作成記述
// first buttonの生成
let calculationButton: CCButton =
CCButton .buttonWithTitle("計算ボタン") as CCButton
calculationButton.setTarget
(self, selector:"calculationButtonTouched:")
// second buttonの生成
let animationButton: CCButton =
CCButton.buttonWithTitle("アニメーションボタン") as CCButton
animationButton.setTarget(self, selector:"animateButtonTouched:")
//let lblA = UILabel()
//Layout.regist(lblA, superview: self.view)
// layoutboxの生成
let layoutBox: CCLayoutBox = CCLayoutBox()
// layoutBoxアンカーポイント 中央
layoutBox.anchorPoint = ccp(0.5, 0.5);
// calculationStepButtonをレイアウトに追加
layoutBox.addChild(calculationButton)
// animationButtonをレイアウトに追加
layoutBox.addChild(animationButton)
// 上部ボタンとの空白
layoutBox.spacing = 20;
// Vertical:垂直に整列
layoutBox.direction = CCLayoutBoxDirection.Vertical
// layoutBoxにlayout
layoutBox.layout()
// cocos2dではCCDirectorを使ってウィンドウサイズを取得
let size: CCDirector = CCDirector.sharedDirector()
// layoutBoxの表示位置を中央 幅:半分 高さ:半分
// 座標系が異なります。UIKitは左上が(0,0)、cocos2dは左下が(0,0)です。
layoutBox.position =
ccp(size.designSize.width / 2, size.designSize.height / 2);
// layoutBoxを表示
self.addChild(layoutBox)
super.onEnter()
}
func calculationButtonTouched(CCButton)
{
println("計算")
label.string = "計算"
}
func animateButtonTouched(CCButton)
{
println("アニメーション")
label.string = "アニメーション"
}
}
※メニューの追加について
3つ目のメニュー追加したい場合は下記の記述で追加できます。
画面上に3つのメニュー項目が並びます。簡単ですね。
// third buttonの生成
let animationButton: CCButton = CCButton .buttonWithTitle("⚪️⚪️ゲーム") as CCButton
animationButton.setTarget(self, selector:"gameButtonTouched:")
// gameButtonをレイアウトに追加
layoutBox.addChild(gamenButton)
// ゲームボタンのアクション
func gameButtonTouched(CCButton)
{
println("⚪️⚪️ゲーム")
label.string = "⚪️⚪️ゲーム"
}
GitHub Menu01_Swift
Cocos2dx 3.x C++言語
MenuTopScene.hを次のように変更してみてください。
#ifndef __Menu__MenuTopScene__
#define __Menu__MenuTopScene__
#include "cocos2d.h"
// 名前空間 #define USING_NS_CC using namespace cocos2d
USING_NS_CC;
class MenuTopScene : public Layer
{
public:
// 初期化のメソッド
virtual bool init();
static cocos2d::Scene* createScene();
// スタートボタン押下時の処理宣言 戻る Object → Ref に変更
void pushStart01(Ref *pSender);
// スタートボタン押下時の処理宣言 戻る Object → Ref に変更
void pushStart02(Ref *pSender);
// create()を使えるようにしている。
CREATE_FUNC(MenuTopScene);
};
#endif /* defined(__Menu__MenuTopScene__) */
※重要
public内にタッチイベント用にそれぞれスタートボタンのメソッドの宣言をする必要があります。
public:
// スタートボタン押下時の処理宣言 戻る Object → Ref に変更
void pushStart01(Ref *pSender);
// スタートボタン押下時の処理宣言 戻る Object → Ref に変更
void pushStart02(Ref *pSender);
MenuTopScene.cppを次のように変更してみてください。
#include "MenuTopScene.h"
// 名前空間 #define USING_NS_CC using namespace cocos2d
USING_NS_CC;
Scene* MenuTopScene::createScene()
{
// 「シーン」は自動解放オブジェクトです
auto scene = Scene::create();
// 「レイアウト」は自動解放オブジェクトです
auto layer = MenuTopScene::create();
// シーンに子としてレイヤーを追加
scene->addChild(layer);
// シーンを返す
return scene;
}
// 「INIT」初期化
bool MenuTopScene::init()
{
if ( !Layer::init() )
{
return false;
}
// 画面サイズを取得
Size winSize = Director::getInstance()->getVisibleSize();
// バックグランドカラー
auto background = LayerColor::create(Color4B::BLUE,
winSize.width,
winSize.height);
// バックグランドカラー 第2引数は表示順
this->addChild(background, 0);
// ラベルを生成
Label* label1 = Label::createWithSystemFont("Cocos2d-x", "Arial", 120);
// ラベルの設置
label1->setPosition(Point(winSize.width /2 ,winSize.height/1.5));
// ラベルタイトルを追加
this->addChild(label1,1);
// ボタンを押した時にメソッドを呼び出す
.h = void pushStart01(Ref *pSender); 宣言必要
// pushStart01(メソッド)
auto startButton01 = MenuItemImage::create(
"menu-image1.png", // 通常状態の画像
"menu-image1-hover.png", // 押下状態の画像
CC_CALLBACK_1(MenuTopScene::pushStart01, this)); // 押下時のアクション
// ボタンを押した時にメソッドを呼び出す
.h = void pushStart02(Ref *pSender); 宣言必要
// pushStart02(メソッド)
auto startButton02 = MenuItemImage::create(
"menu-image2.png", // 通常状態の画像
"menu-image2-hover.png", // 押下状態の画像
CC_CALLBACK_1(MenuTopScene::pushStart02, this)); // 押下時のアクション
//ボタンを押した時にラムダ式(init内部記述式)を呼び出す
auto startButton03 = MenuItemImage::
create("menu-image3.png","menu-image3-hover.png",[(Ref*sender){
CCLOG("Pushボタン03");
});
// ボタンの設置
startButton01->setPosition(Point(winSize.width / 2,winSize.height /2.1));
startButton02->setPosition(Point(winSize.width / 2,winSize.height /2.8));
startButton03->setPosition(Point(winSize.width / 2,winSize.height /4.2));
//メニューを作成 自動解放オブジェクト
auto menu = Menu::create(startButton01,startButton02,startButton03,NULL);
menu->setPosition(Point::ZERO);
// メニューを追加
this->addChild(menu, 1);
return true;
}
// pushStart01ボタン
void MenuTopScene::pushStart01(Ref *pSender)
{
CCLOG("Pushボタン01");
}
// pushStart02ボタン
void MenuTopScene::pushStart02(Ref *pSender)
{
CCLOG("Pushボタン02");
}
コールバック関数
Ver3.xから、マクロで登録されたコールバック関数が登場します。
使い方は、指定したメソッドを呼び出すのですが、呼び出すメソッドの引数に応じて使い分けます。
CC_CALLBACK_0
CC_CALLBACK_1
CC_CALLBACK_2
CC_CALLBACK_0
//引数がない
const std::function< void()> &func
//例
void MenuTopScener::menuAction0(){
}
CC_CALLBACK_1
//引数が1つ
const std::function< void(Node *)> &func
//例
void MenuTopScene::menuAction1(Ref *sender){
}
CC_CALLBACK_2
//引数が2つ
std::function<bool(Touch*, Event*)> onTouchBegan
//例
void MenuTopScene::menuAction2(Touch *touch,Event *event){
}
GitHub Menu_Cocos2d-x
各解説はソースコードのコメント文を参照してください。
出来る限り分かりやすいようにしていますのでご了承願います。
参考にしたページ
cocos2d入門編 〜ボタンの作り方(CCMenuItem, CCMenu)〜
cocos2d v3.1非互換:CCMenu,CCMenuItemが無くなっている(^^ゞ
コメントをお書きください