サイトのトップへ戻る

Cocos2d-x ドキュメント 日本語訳

UI コンポーネント

あなたが使用している一般的なアプリを見てみると、UI ウィジットが何なのかは分からなくともそれが使用されているということは分かるでしょう。 それらのUIウィジットはゲームにだけ使用されるものではなく、おそらく全てのアプリケーションでいくつかウィジットが使用されていることでしょう。 UI とは何の略ですか? UI ウィジットとは何をするものですか?ああ、疑問がたくさんあります。!



Widgets, oh, my!

UI とは ユーザーインタフェースを表す略語です。ご存知の通り、UIとは画面上に表示されるものです。 UIには、 ラベル, ボタン, メニュー, スライダービューといったようなアイテムが含まれています。 Cocos2d-x では、プロジェクトに簡単に追加できるUIウィジット集が用意されています。 これは些細なことに聞こえるかもしれませんが、Labelのようなコアクラスを自分で作成するとなると大変な苦労になるのです。 There are so many aspects of just this one. Could you imagine having to write your own custom widget set? 心配しないでください、必要なものは網羅されています!



Label

Cocos2d-x には、true typebitmap や内蔵システムフォントを使用するラベルを作成することができる Labelオブジェクトが用意されています。このクラス一つで Labelに必要なものが全て制御できます。



Label BMFont

BMFont とは ビットマップフォントを使用するタイプのラベルです。 ビットマップフォントの文字はドットのマトリックスで構成されています。 これは非常に手早く簡単に使用できますが、サイズの変更ができないので各文字サイズごとに別々のフォントが必要です。 Label 内の各文字は、別々の Spriteです。つまり各文字は個別に回転、サイズ変更、色付けすることができ、異なるanchor point やその他ほとんどのプロパティを変更して持つことができます。

BMFont label を作成するには二つのファイルが必要です: .fnt ファイルと各文字を表す.png形式の画像ファイルです。 あなたが Glyph Designerのようなツールを使用している場合、ツールがあなたに代わってこれらのファイルを自動的に作成します。 bitmap fontからLabelオブジェクトを作成するには以下のようにします:

auto myLabel = Label::createWithBMFont("bitmapRed.fnt", "Your Text");

string 引数に渡す全ての文字は、引数として渡す.fntファイルに記載されている必要があります。記載されていない場合、それらの文字は描写されません。 Label オブジェクトを描写した時に文字の欠落が発生していた場合は、.fnt ファイルにその文字が記載されているかを確認してください。



Label TTF

True Type Fonts は前項で学んだ bitmap fonts とは違います。 true type fontsを使うと、 font の外郭が描写されます。 これは使用するサイズや色ごとに個別のフォントファイルを用意する必要がないので便利です。 true type fontを使ってa Label オブジェクトを作成するのは簡単です。 作成するには、 .ttfフォントファイル名、テキスト文字列、サイズを指定する必要があります。 BMFontと違い、TTFでは個別のフォントファイルなしで描写サイズを変更することができます。 以下が、true type fontを使用する例です:

auto myLabel = Label::createWithTTF("Your Text", "Marker Felt.ttf", 24);

true type fontbitmap fontよりも柔軟性が高いですが、描写が遅く、font facesize のようなプロパティの変更をすると高負荷な処理となります。

true type font から、全て同一のプロパティを持つ複数のLabelオブジェクトを作成する場合は、TTFConfigオブジェクトを作成してそれらを管理することができます。 TTFConfig オブジェクトを使うことで、全てのラベルが共通して持っているプロパティを設定することができます。 TTFConfigは、全ての Label オブジェクトが同じ材料を使うためのレシピと考えることができます。

以下の方法で Label 用の TTFConfig オブジェクトを作成することができます。:

// create a TTFConfig files for labels to share
TTFConfig labelConfig;
labelConfig.fontFilePath = "myFont.ttf";
labelConfig.fontSize = 16;
labelConfig.glyphs = GlyphCollection::DYNAMIC;
labelConfig.outlineSize = 0;
labelConfig.customGlyphs = nullptr;
labelConfig.distanceFieldEnabled = false;

// create a TTF Label from the TTFConfig file.
auto myLabel = Label::createWithTTF(labelConfig, "My Label Text");

TTFConfig は中国語や日本語や韓国語の文字を表示するのにも使用できます。



Label SystemFont

SystemFont は既定のフォントとフォントサイズを使用するタイプのラベルです。 このフォントは自身のプロパティを変更することはできません。 これは system font、 system rulesと考えてください。 SystemFont labelの作成は以下のように行います:

auto myLabel = Label::createWithSystemFont("My Label Text", "Arial", 16);



Label Effects

Label オブジェクトを画面に表示した後は、それを少し綺麗にしたいことでしょう。 おそらくlabelは平坦で簡素な見た目でしょう。 ありがたいことに、カスタムフォントを独自に作成する必要はありません! Label オブジェクトにはエフェクトを適用することができます。 全てのLabel オブジェクトが全てのエフェクトをサポートしている訳ではありません。 エフェクトには、シャドーエフェクトアウトラインエフェクトグローエフェクトなどがあります。 一つ以上のエフェクトを簡単に Label オブジェクトへ適用することができます:

以下は シャドー エフェクトを適用したLabel です:

auto myLabel = Label::createWithTTF("myFont.ttf", "My Label Text", 16);

// shadow effect is supported by all Label types
myLabel->enableShadow();

以下は アウトラインエフェクトを適用した Label です:

auto myLabel = Label::createWithTTF("myFont.ttf", "My Label Text", 16);

// outline effect is TTF only, specify the outline color desired
myLabel->enableOutline(Color4B::WHITE, 1));

以下はグロー エフェクトを適用した Label です:

auto myLabel = Label::createWithTTF("myFont.ttf", "My Label Text", 16);

// glow effect is TTF only, specify the glow color desired.
myLabel->enableGlow(Color4B::YELLOW);



メニューについては皆さんおそらく慣れ親しんだものでしょう。 使用している全てのアプリケーションでメニューを目にする機会があります。 あなたのゲームでも、ゲームオプションのナビゲートをするためにおそらく Menu オブジェクトを使用するでしょう。 メニューではしばしばゲーム開始, 終了, 設定 , 説明,のようなボタン を内包しますが、 他の Menuオブジェクトを内包することもできます。 Menu オブジェクトは特殊なタイプのNode オブジェクトです。 メニュー項目用のプレースホルダーとして空のMenuオブジェクトを作成できます:

auto myMenu = Menu::create();

上のほうでゲーム開始, 終了, 設定 ,説明のオプションについて説明しましたが、これらが メニュー項目となります。 メニュー項目のない Menu には意味がありません。 Cocos2d-x では、 Labelオブジェクトを使用したり表示する画像を設定したりといった、menu itemsを作成するための様々な方法が用意されています。 通常Menu items には、normal 状態と selected 状態といった二つの状態があります。 menu itemをタップもしくはクリックした時、callback が引き起こされます。 これは連鎖反応として考えることができます。 menu item をタップ/クリックするとそれによりあなたが設定したコードが実行されます。 Menu は項目を一つだけ持ったり、大量に持ったりできます。

// creating a menu with a single item

// create a menu item by specifying images
auto closeItem = MenuItemImage::create("CloseNormal.png", "CloseSelected.png",
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));

auto menu = Menu::create(closeItem, NULL);
this->addChild(menu, 1);

MenuItem オブジェクトの vector を作成することでメニューを作成することもできます:

// creating a Menu from a Vector of items
Vector<MenuItem*> MenuItems;

auto closeItem = MenuItemImage::create("CloseNormal.png", "CloseSelected.png",
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));

MenuItems.pushBack(closeItem);

/* repeat for as many menu items as needed */

auto menu = Menu::createWithArray(MenuItems);
this->addChild(menu, 1);

この章のサンプルコードを実行すると、MenuItems用にLabelオブジェクトを内包したMenuが表示されるでしょう:



メニューコールバックとしてのラムダ関数

上では、menu item をクリックした時それによってcallbackが引き起こされることについて学びました。 C++11 には ラムダ 関数が実装されているので、 Cocos2d-x はそれを最大限活用しています! ラムダ 関数とはソースコード内にインラインで記述する関数のことです。 ラムダ はコンパイル時ではなく実行時に精査されます。

以下は簡単なラムダの例です:

// create a simple Hello World lambda
auto func = [] () { cout << "Hello World"; };

// now call it someplace in code
func();

MenuItem のコールバックとしてラムダを使用します:

auto closeItem = MenuItemImage::create("CloseNormal.png", "CloseSelected.png",
[&](Ref* sender){
    // your code here
});


Buttons

ボタンについては詳しく説明する必要はないでしょう。 ゲーム内でクリックして何かを発生させるものということは誰もが知っています。 おそらくボタンを使ってscenes を切り替えたりゲームプレイ画面にSpriteオブジェクトを追加したりすることでしょう。 ボタンは押された時にタッチイベントを検知してあらかじめ定義されたコールバックを呼び出します。 Button には normal状態と selected状態の二つがあります。 Button の外観はその状態に応じて変わります。 Buttonの作成とその callback の定義は簡単です:

#include "ui/CocosGUI.h"

auto button = Button::create("normal_image.png", "selected_image.png", "disabled_image.png");

button->setTitleText("Button Text");

button->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type){
        switch (type)
        {
                case ui::Widget::TouchEventType::BEGAN:
                        break;
                case ui::Widget::TouchEventType::ENDED:
                        std::cout << "Button 1 clicked" << std::endl;
                        break;
                default:
                        break;
        }
});

this->addChild(button);

上記の例を見て分かるように、ボタンの取り得る各状態ごとに.png 画像を設定しています。 Buttonは以下のような三つの画像で構成されます。:

画面上では、 Buttonは以下のような見た目になるでしょう:



CheckBox

皆さんはこれまでにも、求職や賃貸契約などで紙形式のチェックボックスを記載したことはあるでしょう。 ゲーム内でもチェックボックスを使用することができます。 おそらく、ゲームプレイヤーが簡単に yesnoを選べるようにしたいですよね。 そういうと バイナリ 選択 (0 と 1)のことを言っているように聞こえるかもしれません。 CheckBox を使用することで、ユーザーがこうしたタイプの選択をできるようになります。 Checkboxnormalselecteddisabledといった五つの異なる状態を持ちます。 CheckBoxを作成するのは簡単です:

#include "ui/CocosGUI.h"

auto checkbox = CheckBox::create("check_box_normal.png",
                                 "check_box_normal_press.png",
                                 "check_box_active.png",
                                 "check_box_normal_disable.png",
                                 "check_box_active_disable.png");

checkbox->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type){
        switch (type)
        {
                case ui::Widget::TouchEventType::BEGAN:
                        break;
                case ui::Widget::TouchEventType::ENDED:
                        std::cout << "checkbox 1 clicked" << std::endl;
                        break;
                default:
                        break;
        }
});

this->addChild(checkbox);

上記の例を見て分かるように、チェックボックスの取り得る各状態ごとに.png 画像を設定しています。 CheckBoxが取り得る状態は五つあるので、一つの状態につき一つ、最大で五つのの画像を設定します。 以下は画像の例です:

画面上では、 Checkboxは以下のような見た目になるでしょう:



LoadingBar

必要な全てのコンテンツをロードするまで待たなければならないゲームをプレイしたことはありますか? それらのゲームではおそらく処理の進捗状況に応じて伸びていくバーが表示されているでしょう。 これらはしばしば、 プログレスバーステータスバーローディングバーとして呼ばれます。 LoadingBarの作成は以下のようにします:

#include "ui/CocosGUI.h"

auto loadingBar = LoadingBar::create("LoadingBarFile.png");

// set the direction of the loading bars progress
loadingBar->setDirection(LoadingBar::Direction::RIGHT);

this->addChild(loadingBar);

上記の例では、ローディングバー を作成して進捗に応じて延びていく向きを設定しています。 今回は右向きに伸びるよう設定しています。しかし、ローディングバーの進捗割合を変更する必要がある時もあるでしょう。 これをするのは簡単です:

#include "ui/CocosGUI.h"

auto loadingBar = LoadingBar::create("LoadingBarFile.png");
loadingBar->setDirection(LoadingBar::Direction::RIGHT);

// something happened, change the percentage of the loading bar
loadingBar->setPercent(25);

// more things happened, change the percentage again.
loadingBar->setPercent(35);

this->addChild(loadingBar);

上記の例を見て分かるように、 ローディングバーオブジェクトのテクスチャ用に .png画像を設定しています:

画面上では、 LoadingBarは以下のような見た目になるでしょう:



ScrollView

プレイヤーの選ぶ選択肢がたくさんあるメニューがあったとしましょう。 なんと、それらは画面上の列に収まりきれません。選択肢のうちどれかを削除しますか? いいえ! ScrollViewを使います。 その名の通り、 ScrollViewを作成するとScene内の上から下まで、もしく左から右まで、全ての部分をスクロールして閲覧できます。 ScrollViewを作成するには以下のようにします:

#include "ui/CocosGUI.h"

auto scrollView = cocos2d::ui::ScrollView::create();

上記の例では、 ScrollViewを作成しています。既定では、この ScrollView垂直方向にスクロールします。 水平方向のスクロールも設定できますし、 垂直方向と水平方向の両方のスクロールを設定することもできます。 例:

#include "ui/CocosGUI.h"

// creates a vertically scrollable ScrollView 
auto scrollView = cocos2d::ui::ScrollView::create();

// this is also the same as the above with a redundant
// 
auto scrollView = cocos2d::ui::ScrollView::create();



Slider

場合によっては値を少しだけ変更する必要がある機会もあるでしょう。 あるキャラクターがいて、その敵を攻撃する力をプレイヤーが調節できるようにしたいといったぐあいに。 Slider を使用することで、ユーザーはインジケーターを動かして値を設定することができるようになります。 Sliderを作成するには、以下のようにします:

#include "ui/CocosGUI.h"

auto slider = Slider::create();
slider->loadBarTexture("Slider_Back.png"); // what the slider looks like
slider->loadSlidBallTextures("SliderNode_Normal.png", "SliderNode_Press.png", "SliderNode_Disable.png");
slider->loadProgressBarTexture("Slider_PressBar.png");

slider->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type){
        switch (type)
        {
                case ui::Widget::TouchEventType::BEGAN:
                        break;
                case ui::Widget::TouchEventType::ENDED:
                        std::cout << "slider moved" << std::endl;
                        break;
                default:
                        break;
        }
});

this->addChild(slider);

上記の例を見て分かるように、スライダーが取り得る各状態ごとに .png 画像を設定しています。 Slider は以下のような最大五つの画像で構成されています:

画面上では、 Sliderは以下のような見た目になるでしょう:



TextField

メインキャラクターに付ける名前をゲームのプレイヤーに入力して欲しい場合はどうすればよいでしょう? プレイヤーはどこに入力すれば良いでしょうか? はい、もちろんそれはテキストフィールドです。 TextField ウィジットは文章の入力に使用されます。 これはタッチイベント、フォーカス、パーセントでの位置指定、パーセントでのコンテンツのサイズ指定をサポートしています。 TextField ウィジットを作成するには以下のようにします:

#include "ui/CocosGUI.h"

auto textField = TextField::create("","Arial",30);

textField->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type){
                std::cout << "editing a TextField" << std::endl;
});

this->addChild(textField);

この例では、 TextField を作成して callback を設定しています。

TextField オブジェクトは汎用性が高いので、入力に関するあなたのニーズを全て満たすことができます。 ユーザーが秘密のパスワードを入力しますか? ユーザーが入力でき文字数を制限する必要がありますか? TextField オブジェクトをそうした機能を全て内蔵しており、他にも多くの機能があります! それでは例を見てみましょう:

#include "ui/CocosGUI.h"

auto textField = TextField::create("","Arial",30);

// make this TextField password enabled
textField->setPasswordEnabled(true);

// set the maximum number of characters the user can enter for this TextField
textField->setMaxLength(10);

textField->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type){
                std::cout << "editing a TextField" << std::endl;
});

this->addChild(textField);

画面上では、 TextFieldは以下のような見た目になるでしょう:

TextFieldを編集している時は、スクリーンキーボードが起動します: