読者です 読者をやめる 読者になる 読者になる

cocos2d-x 画像ボタンをMenuItemImageからui::Buttonに変更する

・ボタンを追加するごとにメソッドを増やすのが必要

・1つしかボタンが無くてもMenuが必要

・ボタンを放した時にしか分からない

というMenuItemImageが凄く不便なのでui::Buttonに変えた

元のソース

MenuItemImage* button = MenuItemImage::create("btn01.png", "btn01_press.png", CC_CALLBACK_1(TestScene::btn01, this));
button->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT);
Menu* menu = Menu::create(button, NULL);
menu->setPosition(Vec2(0, 0));
this->addChild(menu);

void TestScene::btn01(Ref* pSender)
{
    //処理
}

 

ui::Buttonの記述

#include "ui/CocosGUI.h"

ui::Button * button = ui::Button::create();
button->setTouchEnabled(true);
button->loadTextures("btn01.png", "btn01_press.png", "");
button->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT);
button->addTouchEventListener([this](Ref* sender, ui::Widget::TouchEventType type) {
    if (type == ui::Widget::TouchEventType::ENDED) {
        //処理
    }
});
this->addChild(button);

cocos2d-x BitmapFont をTexturePacker

Bitmap Fontの作り方は前の記事を参照

cocos2d-x Bitmap Fontを使う (Texture Atlas) - GardenFarm cocos2d-x C++ ゲーム開発

 

上記で出来上がった.fntとpngファイルを使いTexturePackというソフトで暗号化を行う

TexturePacker - Create Sprite Sheets for your game!

初回起動時にcocos2d-xを選択する。

 

①左のSpriteの部分にフォントのpngをドラッグドロップ

f:id:FALStar:20160717143015p:plain

 

②右側のTextureFormat をPVR+zlibに変える。

(PixelFormatはファイルサイズを減らすための設定なので任意 RGBA8888->RGBA4444にした)

f:id:FALStar:20160717143519p:plain

 

③右のContent protectionの鍵ボタンを押して暗号化キー入力をする

32文字で、使える文字は16進数「0123456789abcdef」

入力後Closeボタンで暗号化ダイアログを閉じる

f:id:FALStar:20160717144210p:plain

 

④右のスクロールを一番下まで移動

Trim modeをNone

Extrudeを0

に変更する

f:id:FALStar:20160717144812p:plain

 

⑤ファイル書き出し

File -> Publish sprite sheet を選択して、 保存場所を決めて保存する

f:id:FALStar:20160717145037p:plain

 

⑥保存場所に出来た.plistは使わないので破棄してOK

.pvr.cczファイルを ゲームのプロジェクトリソースの.fntと同じ場所に配置

.fntをテキストエディタで開き3行目の読込画像ファイルの部分を⑤で書き出したファイル名にする

 

f:id:FALStar:20160717145527p:plain

⑦プログラム内で使用時はシーンのinitなどに暗号化キーをセット

キー32文字を8桁区切りで頭に「0x」をつけて記述

ZipUtils::setPvrEncryptionKey(0x01234567, 0x89abcdef, 0x01234567, 0x89abcdef);

あとは普通にフォントを使う

Label* label = Label::createWithBMFont("フォント名.fnt", "出力文字");
label->setScale(20);

this->addChild(label);

 これでFontのpngファイルは格納しなくてよくなった

cocos2d-x 背景画像表示

cocos2d-xは左下がX0 Y0座標で右上に行くほど数字が増える為

背景画像表示は画像の基準位置を左下に設定することで簡単に表示できる

Sprite* bgsprite = Sprite::create("background.png");
bgsprite->setAnchorPoint(Vec2::ANCHOR_BOTTOM_LEFT);
this->addChild(bgsprite);

 

cocos2d-x Tagが一致している物をオブジェクトを一括で削除

Tagが一致している物をオブジェクトを一括で削除する

for (int i=0; i < 10; i++) {

Label* label = Label::createWithBMFont("フォント名", "文字");
label->setScale(10);
label->setTag(1000);

this->addChild(label);

}

 動的に沢山作成したオブジェクトを一気に消す。

Vector<Node*> childrens = getChildren();
if (childrens.size() > 0) {
    reverse(childrens.begin(), childrens.end());
    for (Node* children : childrens) {
        if (children->getTag() == 1000) {
            children->removeFromParentAndCleanup(true);
        }
    }
}

 

cocos2d-x std::stringにUTF8の文字を入れて 1文字ずつ処理

std::stringにUTF8の文字を入れて 1文字ずつ処理する

WindowsAndroid共通で動作する物

#define UTF8_CHAR_LEN( byte ) ( ( 0xE5000000 >> ( ( byte >> 3 ) & 0x1e ) ) & 3 ) + 1

 int GetUnicodeLength(const char* utf8)
{
    int ByteCount = 0;
    while (*utf8){
        int charlen = UTF8_CHAR_LEN(*utf8);
        ByteCount++;
        utf8 += charlen;
    }
    return ByteCount;
}
void GetUnicodeChar(const char* utf8, int charnum, int& index, int& len)
{
    int ByteIndex = 0;
    int ByteLength = 0;
    for (int i = 0; i <= charnum; i++){
        if (i == 0) {
            ByteLength = UTF8_CHAR_LEN(*utf8);
        }
        else {
            int charlen = UTF8_CHAR_LEN(*utf8);
            ByteIndex += charlen;
            utf8 += charlen;
            ByteLength = UTF8_CHAR_LEN(*utf8);
        }
    }
    index = ByteIndex;
    len = ByteLength;
}

 

std::string moji_text = UTF8Bom無で保存した外部ファイルから読込

//文字数を取得する

int len = GetUnicodeLength(moji_text.c_str() );

int i = 0, charindex = 0, charlength = 0;

for (; i < len; i++) {

//文字のインデックスと長さを取得

        GetUnicodeChar(moji_text.c_str(),i, charindex, charlength);

//moji に1文字読込
        std::string moji = moji_text.substr(charindex, charlength);

//処理を記載

}

cocos2d-x 3.12 Android FullScreen bug

 v3.12 Androidにて勝手にフルスクリーンがデフォルト設定になりました

 

AndroidManifest.xmlにて

@android:style/Theme.NoTitleBar.Fullscreen

@android:style/Theme.Light.NoTitleBar

 でフルスクリーンを切ってるのに勝手になる不具合

修正方法は、

プロジェクト\cocos2d\cocos\platform\android\java\src\org\cocos2dx\lib\Cocos2dxActivity.java 419行目

protected void hideVirtualButton() {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {

        getWindow().getDecorView().setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
                        | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
                        | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
    }
}

 を

protected void hideVirtualButton() {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
/*
        getWindow().getDecorView().setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
                        | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
                        | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
*/
    }
}

に変更

cocos2d-x Win32 [修正]アプリの二重起動をさせないようにする

Classes\AppDelegate.cpp

glview = GLViewImpl::createの第1引数で使われているアプリ名をまず調べます。

glview = GLViewImpl::create("アプリ名");

 

proj.win32\main.cpp

_tWinMainの最初にチェック処理を追加する

クラス名がGLFWから始まり、タイトルがゲーム名の物があるかチェック

BOOL CALLBACK EnumWndProc(HWND hWnd, LPARAM lParam)
{
    wchar_t buff[256] = L"";
    GetClassName(hWnd, buff, sizeof(buff));
    if (wcsstr(buff, L"GLFW") != NULL) {
        GetWindowText(hWnd, buff, sizeof(buff));
        if (wcsstr(buff, (wchar_t*)lParam) != NULL) {
            return false;
        }
    }
    return true;
}

int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    if (!EnumWindows(EnumWndProc, (LPARAM)L"アプリ名")) {
        return FALSE;
    }
    // create the application instance
    AppDelegate app;
    return Application::getInstance()->run();
}