あなたが使用している一般的なアプリを見てみると、UI ウィジットが何なのかは分からなくともそれが使用されているということは分かるでしょう。 それらのUIウィジットはゲームにだけ使用されるものではなく、おそらく全てのアプリケーションでいくつかウィジットが使用されていることでしょう。 UI とは何の略ですか? UI ウィジットとは何をするものですか?ああ、疑問がたくさんあります。!
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?
心配しないでください、必要なものは網羅されています!
Cocos2d-x には、true typeや bitmap や内蔵システムフォントを使用するラベルを作成することができる Label
オブジェクトが用意されています。このクラス一つで Label
に必要なものが全て制御できます。
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 ファイルにその文字が記載されているかを確認してください。
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 fontはbitmap fontよりも柔軟性が高いですが、描写が遅く、font face や size のようなプロパティの変更をすると高負荷な処理となります。
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
は中国語や日本語や韓国語の文字を表示するのにも使用できます。
SystemFont
は既定のフォントとフォントサイズを使用するタイプのラベルです。
このフォントは自身のプロパティを変更することはできません。
これは system font、 system rulesと考えてください。
SystemFont
labelの作成は以下のように行います:
auto myLabel = Label::createWithSystemFont("My Label Text", "Arial", 16);
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
});
ボタンについては詳しく説明する必要はないでしょう。
ゲーム内でクリックして何かを発生させるものということは誰もが知っています。
おそらくボタンを使って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
は以下のような見た目になるでしょう:
皆さんはこれまでにも、求職や賃貸契約などで紙形式のチェックボックスを記載したことはあるでしょう。
ゲーム内でもチェックボックスを使用することができます。
おそらく、ゲームプレイヤーが簡単に yes や noを選べるようにしたいですよね。
そういうと バイナリ 選択 (0 と 1)のことを言っているように聞こえるかもしれません。
CheckBox
を使用することで、ユーザーがこうしたタイプの選択をできるようになります。
Checkbox
は normal、 selected 、disabledといった五つの異なる状態を持ちます。
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
の作成は以下のようにします:
#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
を作成すると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
を作成するには、以下のようにします:
#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
ウィジットを作成するには以下のようにします:
#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
を編集している時は、スクリーンキーボードが起動します: