カテゴリー別アーカイブ: cocos2d-x v3

【cocos2d-x v3.x】矩形描画における座標系

cocos2d-x で画面に矩形を描画する方法はいくつかあるが、お手軽なのは Sprite または LayerColor を使用する方法だ。通常、Sprite は用意しておいた画像ファイルを表示するのだが、単色の矩形であれば setTextureRect(const Rect& rect), setColor(iconst Color3B&) をコールすれば画像を用意する必要がなくお手軽だ。

以下が、矩形スプライトの表示コードサンプルと実行結果である。

// 矩形スプライト表示
auto rectSprite = Sprite::create();  //  スプライト生成
rectSprite->setTextureRect(Rect(0, 0, rwd, rht));  // 矩形位置・サイズ
rectSprite->setColor(Color3B(0x80, 0xff, 0x80));  // 明るい緑
rectSprite->setPosition(Vec2(screen_cx, screen_cy));  // 画面中央
addChild(rectSprite, 2);  //  スプライトオブジェクトをスクリーンに付加

rwd, rht は表示する矩形サイズ、screen_cx, cy は画面中央座標だ。
なお、わかりやすいように画面中央に十字の白色グリッドを表示している。

次に LayerColor を利用するコード、実行結果を示す。

// 矩形レイヤー表示
auto rectLayer = LayerColor::create(Color4B(0x80, 0x80, 0xff, 0xff), rwd, rht);  //  明るい青
rectLayer->setPosition(Vec2(screen_cx, screen_cy));  // 画面中央
addChild(rectLayer, 3);

Sprite の場合とほぼ同じようなコードで矩形を表示できる。が、ここで注意すべきは setPosition() で指定した位置だ。Sprite の方は矩形中央が指定した位置に表示されるが、LayerColor は左下が指定した位置に表示されるという点だ。

あと、スプライト・レイヤーに子オブジェクトを付加する場合の座標原点を確認しておく。

下記はスプライト矩形の上に赤い矩形を表示するコード。表示位置は (0. 0) としている。

// 矩形の上にスプライト表示
auto sprite = Sprite::create();
sprite->setTextureRect(Rect(0, 0, rwd/8, rht/8));
sprite->setColor(Color3B(0xff, 0x80, 0x80));
sprite->setPosition(Vec2(0, 0));
rectSprite->addChild(sprite, 1);

結果を見ると、スプライト矩形の左下点が座標原点となっているのがわかる。

同様に、レイヤーの上に赤い矩形を (0, 0) 位置に表示すると以下のようになる。

まあ、レイヤーなので当然と言えば当然であるが、こちらも矩形の左下点が座標原点となっているのがわかる。

以上、スプライトとレイヤーで矩形を描画した場合の座標系の違いついて見てきた。スプライト・レイヤーの意味を鑑みて、このような仕様にしたのであろうが、理解があやふやだと、意図した位置とは違う位置にオブジェクトが描画され混乱することもあるので、ちゃんと理解しておくことを推奨する。

まとめ:

  • オブジェクト生成時、スプライトは画像中央の位置を、レイヤーは左下点位置を指定する
  • 小オブジェクトを付加する場合の座標原点は、スプライト・レイヤーともに左下位置が座標原点となる。

cocos2d-x 3.17 アプリに SDKBOX admob リワード広告を組み込む

  • コマンドプロンプトで sdkbox import admob を実行し、admob プラグインを組み込む
  • プロジェクト/Resource/sdkbox_config.json を開き、”AdMob” > “ads” > “rewarded” > “id” を表示したいリワード広告IDに置き換える
  • sdkbox::AdMobListener 派生クラスを定義し、virtual void reward(const std::string &name, const std::string &currency, double amount) を再実装する
    • このメンバ関数はリワード広告が正しく表示された場合にコールされるので、その処理を記述する
  • sdkbox::AdMobListener 派生クラスオブジェクトを生成し、sdkbox::PluginAdMob::setListener(AdMobListener*) に渡す
  • sdkbox::PluginAdMob::cache(リワード広告ID); をコールし、広告をキャッシュしておく
  • ユーザがリワード広告表示を承諾したら sdkbox::PluginAdMob::show(リワード広告ID); をコールする

cocos2d-x を Android Studio でビルド

※ 環境:Android Studio 3.0.1, cocos2d-x v3.16

・コマンドラインにて cocos New <プロジェクト名> -l cpp を実行するとプロジェクトが作成される。
・プロジェクト名/proj.android-studio を Android Studio で開く
・→ すこし時間がかかるが、Gradle(=ビルド設定)が自動的にビルドされ、プロジェクト自体のビルドが可能な状態になる。
・Build > Make Project を実行しビルド
・→ それなりに時間かかるが、プロジェクト/proj.android-studio/app/build/outputs/apk/debug に プロジェクト名-debug.apk が作成される
・リリース版をビルドする場合は、Build > Generate Signed APK を実行する
・デフォルトでは Classes 以下が一覧に表示されないので、Gradle.Scripts/settings.gradle をダブルクリックで開き、以下を追加する

include ‘:Classes’
project(‘:Classes’).projectDir = new File(settingsDir, ‘../Classes’)
include ‘:Resources’
project(‘:Resources’).projectDir = new File(settingsDir, ‘../Resources’)

【cocos2d-x v3】 RadioButton の使い方

RadioButton クラスは v3.8 で追加された比較的新しいクラスだ。

  • RadioButtonGroup オブジェクトを生成し、子ノードとしてシーンに追加
  • 選択肢の分だけ、RadioButton を生成し、RadioButtonGroup オブジェクトに 追加し、シーンへも子ノードとして追加する
  • RadioButton オブジェクトにイベントリスナーを指定する
// Create a radio button group
auto radioButtonGroup = RadioButtonGroup::create();
this->addChild(radioButtonGroup);

// Create the radio buttons
for(・・・) {
        RadioButton* radioButton = RadioButton::create("cocosui/radio_button_off.png", "cocosui/radio_button_on.png");
        float posX = startPosX + BUTTON_WIDTH * i;
        radioButton->setPosition(Vec2(posX, winSize.height / 2.0f + 70));
        radioButton->setScale(1.2f);
        radioButton->addEventListener(CC_CALLBACK_2(LabelToggleTypeTest::onChangedRadioButtonSelect, this));
        radioButton->setTag(i);
        radioButtonGroup->addRadioButton(radioButton);
        this->addChild(radioButton);
}

cocos 2d-x タッチイベントリスナーの登録

bool GameLayer::init()
{
.....
    // タッチイベントリスナー
    auto touchListener = EventListenerTouchOneByOne::create();
    touchListener->onTouchBegan = [this](Touch* touch, Event *){
    	auto loc = touch->getLocation();
    	return true;
    };
    touchListener->onTouchMoved = [this](Touch* touch, Event *){
    };
    touchListener->onTouchEnded = [this](Touch* touch, Event *){
    };
    this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(touchListener, this);
.....
}

コマンドラインでアンドロイド開発>android コマンド

Eclipse は重くて使いたくないので、cocos2d-x のアンドロイド版をビルドするときは、
cocos compile -p android -m release
って、何も理解せずやってるおいらだけど、ライブラリを追加しようとかすると、仕組みを理解していないが故に、どうしていいのかさっぱりわからず、いつも困惑しています。

で、人に聞いたり、調べてみるとどうやら アンドロイドSDK に android コマンドってのが含まれていて、それを使うとプロジェクトを作ったり、プロジェクトを修正してり出来そうなことがわかりました。

android コマンドは SDK位置/tools に含まれているので、そこにパスを通せば使えるようになります。
パスを通したら、コンソールで android -h と入力し、以下のようにヘルプが出たら、利用可能です。

C:\Users\ntsuda>android -h

       Usage:
       android [global options] action [action options]
       Global options:
  -h --help       : Help on a specific command.
  -v --verbose    : Verbose mode, shows errors, warnings and all messages.
     --clear-cache: Clear the SDK Manager repository manifest cache.
  -s --silent     : Silent mode, shows errors only.
  (以下略)

cocos2d-x v3 > httpRequest GET

#include "network/HttpClient.h"
USING_NS_CC;
  cocos2d::network::HttpRequest* request = new cocos2d::network::HttpRequest();
  request->setUrl("http://vivi.dyndns.org/test/index.html?from=cocos2d-x");
  //	GET
  request->setRequestType(cocos2d::network::HttpRequest::Type::GET);
  request->setResponseCallback( [this](network::HttpClient* sender, network::HttpResponse* response) {
  	auto data = response->getResponseData();
  	auto sz = data->size();
  });
  request->setTag("GET test1");
  cocos2d::network::HttpClient::getInstance()->send(request);
  request->release();

cocos2d-x v3 > シングルタッチイベントリスナー

cocos2d-x v3 のシングルタッチイベントリスナーのテンプレーと

    // タッチイベントリスナー
    auto touchListener = EventListenerTouchOneByOne::create();
    touchListener->onTouchBegan = [this](Touch* touch, Event *){
    	return true;
    };
    touchListener->onTouchMoved = [this](Touch* touch, Event *){
    };
    touchListener->onTouchEnded = [this](Touch* touch, Event *){
    };
    this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(touchListener, this);