Cocos2d-x Betaでチェックしておきたい変更点(Value,EventListener,gui::UIButton,gui::UIPageViewなど)

Cocos2d-x 3.0Betaになり、GUI関連のクラスが強化されたり、String,Array,Integerクラスなどがdeprecatedになったり(わりとショック)、EventListenerクラスが追加されたりと、大きく仕様が変更になった。その中で個人的によく使いそうな下記3点の使い方メモ。

1. *Valueクラス*
2. *EventListener*
3. *GUIクラス (UIButton, UIPageView)*

## 1. Valueクラス

Cocos2d-x Betaで、今まであったString(CCString), Array(CCArray), Dictionary(CCDictionary), Integer(CCInteger)などの基本型クラスがdeprecatedで非推奨となった。その代わり、基本的な型(string, int, float, boolを一通りラッピングしてあるValueクラスが追加された。

> cocos2d::Value wrapping many basic data types such as int,float,double,bool,unsigned char,char* and std::string.

Valueクラスは下記のような形で使える。

```objc
// どんな型でも挿入可能
auto str = Value("string");
auto i   = Value(123456);
auto f   = Value(1.0);
auto b   = Value(true);

// 様々な型に簡単に変換可能 
i.asBool();
i.asString();
i.asFload();
```

他にも例えば、今まで記述していたString::createWithFormatは非推奨となり、代わりにStringUtilsが新しく追加された。

```objc
// 下記の記述はdepracatedで非推奨
String* s = String::createWithFormat("my number is %d", 12345);
// StringUtilsクラスを使った記述
std::string v = StringUtils::format("my number is %d", 12345);
```

その他にもArray(CCArray)やDictionary(CCDictionary)も非推奨になり、その代わりにcocos2d::Vector、cocos2d::Mapなどの使っていったほうがよいみたい。

## 2. EventListener

タッチイベント、アクセレーターも変更があった。下記のような書き方はいずれも非推奨となった。

```objc
void testScene::onEnter() {
    setTouchEnabled( true );                       // 非推奨
    setTouchMode(Touch::DispatchMode::ONE_BY_ONE); // 非推奨
    setAccelerometerEnabled( true );               // 非推奨
}
```

Cocos2d-x BetaからのEventListenerを使った記述が推奨となり、今迄よりイベント処理が柔軟に実装することができるようになる。

```objc
void testScene::onEnter() {
    // タッチイベントを追加する場合
    getEventDispatcher()->setEnabled(true);
    auto touchListener = EventListenerTouchOneByOne::create();
    touchListener->onTouchBegan = CC_CALLBACK_2(TestScene::onTouchBegan, this);
    touchListener->onTouchMoved = CC_CALLBACK_2(TestScene::onTouchMoved, this);
    getEventDispatcher()->addEventListenerWithSceneGraphPriority(touchListener, this);

    // アクセレーターを使用する場合
    Device::setAccelerometerEnabled(true);
    auto accelerationListener = EventListenerAcceleration::create(
                                         CC_CALLBACK_2(TestScene::onAcceleration, this));
    getEventDispatcher()->addEventListenerWithSceneGraphPriority(accelerationListener, this);
}
```

上記の場合の各イベント処理。(関数名など自由に変更可)

```objc
bool testScene::onTouchBegan(Touch* touch, Event *event) {
}

void testScene::onTouchBegan(Touch* touch, Event *event) {
}
```

## 3. GUIクラス

これはiOSのネイティブアプリ開発からcocos2d-xに移ってきた開発者には嬉しい仕様追加かも。iOSのUIKitにあるようなクラス(Button, TextField、ScrollView, PageViewなど)が多数追加された。その中でUIButton,PageView, ImageViewについて。

> GUI System series: Overview, UI Containers like Layout, ScrollView, PageView, and UI Widgets including CheckBox, LoadingBar, Slider, Button, TextField etc.

<http://www.cocos2d-x.org/docs/manual/framework/native/gui/container/en>

### UIButton

いままでボタンを作る際にはMenu、MenuItem、MenuItemImageクラスを使い、ボタンのタッチイベントにはCallbackを使っていたが、cocos2d-x betaでは、gui::UIButtonとイベントリスナーでも実装することができるようになった。(Menuクラスはdeprecatedになってはいない)

ヘッダーファイル

```objc 
#include <gui/CocosGUI.h>

void createGameStartButton();
void touchEvent(Object* pSender, gui::TouchEventType type);
```

実装ファイル

```objc 
using namespace gui;

void TestScene::createButton() {
    Button* startButton = Button::create();
    startButton->setTouchEnabled(true);
    startButton->setAnchorPoint(Point(0.5, 1.0));
    startButton->loadTextures("btnStart.png", "btnStartOn.png", "");
    startButton->setPosition(Point( 100, 100 ));
    startButton->addTouchEventListener(this, toucheventselector(TestScene::touchEvent));
    this->addChild(startButton);
}

oid TestScene::touchEvent(Object* pSender, TouchEventType type) {
    switch (type)
    {
        case TOUCH_EVENT_BEGAN:
            break;
        case TOUCH_EVENT_MOVED:
            break;
        case TOUCH_EVENT_ENDED:
            break;
        case TOUCH_EVENT_CANCELED:
            break;
        default:
            break;
    }
}

```

### PageView, ImageView

UIKitにあったPageViewも追加になった。今までcocos2d-xではPageViewみたいな表現をするには、自分で実装する必要があったので地味に嬉しい。

```objc 
#include <gui/CocosGUI.h>

void createPageView();

const std::vector<std::string> PageImages = {
    "page1.png",
    "page2.png",
    "page3.png",
    "page4.png",
    "page5.png",
};
```

```objc
void TestScene::createPageView() {
    Size pageViewSize = this->getContentSize();

    gui::PageView* pageView = gui::PageView::create();
    pageView->setTouchEnabled(true);
    pageView->setSize( pageViewSize );
    Size backgroundSize = this->getContentSize();
    pageView->setPosition(Point((pageViewSize.width - backgroundSize.width) / 2 +
                (backgroundSize.width - pageView->getSize().width) / 2,
                (pageViewSize.height - backgroundSize.height) / 2 +
                (backgroundSize.height - pageView->getSize().height) / 2));

    for (int i = 0; i < PageImages.size(); ++i)
    {
        gui::Layout* layout = gui::Layout::create();
        layout->setSize( pageViewSize );

        gui::ImageView* imageView = gui::ImageView::create();
        imageView->setTouchEnabled(true);
        imageView->setScale9Enabled(false);
        imageView->loadTexture( PageImages.at(i).c_str() );
        imageView->setAnchorPoint( Point(0.5, 1.0) );
        imageView->setSize( pageViewSize );
                imageView->setPosition( Point(layout->getSize().width / 2, layout->getSize().height) );
        layout->addChild(imageView);

        pageView->addPage(layout);
    }

    this->addChild(pageView);
}
```

## 参照

<http://www.cocos2d-x.org/news/172>