2015年

1月

20日

SpriteBuilder メニューボタンの作成(Objective-C Swift C++)

 

 

 

 iPhone・AndroidアプリをObjective-C言語で作る

SpriteBuilder メニューボタンの作成

さようならCCMenu!CCLayoutこんにちは!

 

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;

    

    // layoutBoxlayout

    [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(@"⚪️⚪️ゲーム");


}


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

        

        // layoutBoxlayout

        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


各解説はソースコードのコメント文を参照してください。

出来る限り分かりやすいようにしていますのでご了承願います。