Top > プログラム > Cocos2d-x

最終更新日 2014/03/04
Cocos2d-xに関しての開発情報をまとめます。

目次 Edit

Cocos2d-xとは? Edit

  • Cocos2d-xは、2Dゲーム開発に用いられるオープンソースのフレームワークです。Unityと異なり、無料で使用可能です。
  • マルチプラットフォームに対応しており、Android、iOS向けのアプリを同時開発することができます。
  • C++で開発可能です。
  • Unity2Dと比較して、Cocos2d-xは圧倒的にパフォーマンスに優れているようです。
    Unity2D vs cocos2d-x描画性能検証レポートより

開発環境の構築 Edit

TIPS Edit

各TIPSのプロジェクト名は MyGame とし、HelloWorldシーンがそのまま残っているものとして説明します。
Cocos2d-x のバージョンは 3.0 beta2 です。

CocoStudioのAnimation Editorで出力したアニメーションを再生する Edit

CocoStudioのアニメーションエディタAnimation Editorで出力したアニメーションファイルをアプリ側で読み込んで再生する手順です。
CocoStudioは http://www.cocos2d-x.org/download から無料でダウンロード出来ます。
とりあえず、windows版で動作するよう設定します。

  1. Animation Editorでアニメーションをエクスポート
    CocosStudioを起動し、Animation Editor を選択してアニメーションエディタを起動します。
    DemoPlayerを選択、プロジェクト保存先を選択、キャラが表示されたら、
    ファイル>プロジェクトを出力 で、アニメーションデータをエクスポートします。
    出力されたExportフォルダを、フォルダごと、MyGame\Resources にコピーしておいてください。
    なお、これらのファイル構成はテスト用の為特に深く考えていません。
  2. ソリューションエクスプローラでソリューションを右クリック>追加>既存のプロジェクト で、
    .\cocos2d\cocos\editor-support\cocostudio\proj.win32\libCocosStudio.vcxproj
    を開き、追加します。
  3. libCocosStudioのプロジェクトをVisualStudio2013にアップグレード
    追加されたライブラリをソリューションエクスプローラで見ると、『libCocosStudio (Visual Studio 2010)』という風に、古いVisualStudio形式のままなのがわかります。
    『libCocosStudio (Visual Studio 2010)』を選択して右クリック>VC++ コンパイラとライブラリのアップグレード を選択すると、アップグレード確認が出るのでアップグレードしてください。
  4. MyGameプロジェクトに、libCocosStudioライブラリをリンク
    ソリューションエクスプローラでMyGameプロジェクトを選択して右クリック>プロパティ>共通プロパティ>参照>新しい参照の追加 で、
    libCocosStudioのチェックを有効にして、OKを押します。
  5. インクルードディレクトリを追加
    MyGameプロジェクトのプロパティ>構成プロパティ>C/C++>全般 の、『追加のインクルードディレクトリ』の右側にある『▼』をクリックして、出てきた『編集』をクリック。
    新しい行を追加(フォルダのようなアイコンをクリック)で、『$(EngineRoot)cocos\editor-support』を追加してOKを押します。
    これで、#include "cocostudio/CCArmature.h" のような記述ができるようになります。
  6. 実装
    HelloWorldScene.cpp を修正します。
    #include "cocostudio/CCArmature.h"
    HelloWorld::init() 内で、
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Point origin = Director::getInstance()->getVisibleOrigin();
    // アニメーション再生
    {
        cocostudio::ArmatureDataManager::getInstance()->addArmatureFileInfo(FileUtils::getInstance()->fullPathForFilename("Export/DemoPlayer.ExportJson"));
        cocostudio::Armature* armature = cocostudio::Armature::create("DemoPlayer");
        armature->getAnimation()->play("walk");
        armature->setPositionX(origin.x + visibleSize.width / 2);
        armature->setPositionY(origin.y + visibleSize.height / 2);
        armature->setScale(0.3f); // そのままだと大きすぎるので、ちょっと小さく表示する
        this->addChild(armature);
    }
  7. 後は実行すれば、再生できるはずです。
  • Android版の設定

    windows版が動作していることを前提にしています。
    (HelloWorldScene.cppが修正されていれば問題ないはずです)
    Android.mkを修正して、ヘッダのインクルードディレクトリと、cocostudioライブラリの設定を行います。

    LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes \    ← 末尾に『\』を追加
                        $(LOCAL_PATH)/../../cocos2d/cocos/editor-support    ← ここを追加
    
    LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static
    LOCAL_WHOLE_STATIC_LIBRARIES += cocosdenshion_static
    LOCAL_WHOLE_STATIC_LIBRARIES += box2d_static
    LOCAL_WHOLE_STATIC_LIBRARIES += cocostudio_static    ← ここを追加
    
    include $(BUILD_SHARED_LIBRARY)
    
    $(call import-module,2d)
    $(call import-module,audio/android)
    $(call import-module,Box2D)
    $(call import-module,editor-support/cocostudio)    ← ここを追加

CocoStudioのUI Editorで出力したUIを再生する Edit

前項『[CocoStudioのAnimation Editorで出力したアニメーションを再生する』が動作済みであることを前提としています。
同じように、windows版の設定、実行から始めます。

  1. UI EditorでUIをエクスポート
    CocosStudioを起動し、UI Editor を選択してUIエディタを起動します。
    DemoShopを選択、プロジェクト保存先を選択、UIが表示されたら、
    ファイル>プロジェクトを出力 で、UIデータをエクスポートします。
    出力されたExportフォルダ内にあるDemoShopフォルダを、フォルダごと、MyGame\Resources\UIEditor にコピーしておいてください。
    なお、これらのファイル構成はテスト用の為特に深く考えていません。
  2. 追加のライブラリプロジェクト2つをソリューションに追加する
    ソリューションを右クリック>追加>既存のプロジェクト で、
    .\cocos2d\cocos\gui\proj.win32\libGUI.vcxproj
    を開き、追加します。
    続けて、
    .\cocos2d\extensions\proj.win32\libExtensions.vcxproj
    も追加します。
  3. 追加したプロジェクトのアップグレード
    前項で追加した2つのプロジェクトはVisual Studio 2010のバージョンになっていると思うので、アップデートします。
    プロジェクトを右クリック>VC++ コンパイラとライブラリのアップグレード
    で、2プロジェクトともアップグレードしてください。
  4. MyGameプロジェクト前項2プロジェクトのライブラリをリンク
    MyGameプロジェクト右クリック>プロパティ>共通プロパティ>参照>新しい参照の追加 で、libGUIとlibExtensionsのチェックボックスを有効にします。
    libCocosStudioのチェックを有効にして、OKを押します。
  5. インクルードディレクトリの設定
    MyGameのプロパティ>C/C++>全般>追加のインクルードディレクトリに
    $(EngineRoot)
    $(EngineRoot)cocos
    を追加してください。
  6. 実装
    HelloWorldScene.cpp
    #include "CocosGUI.h"
    #include "cocostudio/CCSGUIReader.h"
    HelloWorld::init() 内で、
    // CocoStudio UI Editor で出力したデータを再生
    {
        gui::Layout*	layout = gui::Layout::create();
        auto widget = cocostudio::GUIReader::getInstance()->widgetFromJsonFile(FileUtils::getInstance()->fullPathForFilename("UIEditor/DemoShop/DemoShop.json").c_str());
        layout->addChild(widget);
        this->addChild(layout);
    }
  7. 実行
    あとは実行すれば動作するはずです。
  • Android版の設定

    Android.mk を編集
    インクルードフォルダの設定のみで行けました。
    (いまいちどのライブラリに何が入っているか理解しきれていません・・・)

    LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes \
                        $(LOCAL_PATH)/../../cocos2d \
                        $(LOCAL_PATH)/../../cocos2d/cocos \
                        $(LOCAL_PATH)/../../cocos2d/cocos/editor-support \
                        $(LOCAL_PATH)/../../cocos2d/cocos/gui \
                        $(LOCAL_PATH)/../../cocos2d/extensions

Websocketを使う Edit

単純なwebsocketのテストです。

  1. MyGameソリューションにlibNetworkプロジェクトを追加します。
    ソリューションを右クリック>追加>既存のプロジェクト から追加できます。
    cocos2d\cocos\network\proj.win32\libNetwork.vcxproj
  2. MyGameプロジェクトにlibNetworkライブラリをリンク
    MyGameプロジェクト右クリック>プロパティ>共通プロパティ>参照>新しい参照の追加 で、libNetworkのチェックボックスを有効にして、OKをおします。
  3. 続いて、MyGameプロジェクトにwebsocketライブラリをリンクします。
    MyGameプロジェクト右クリック>プロパティ>構成プロパティ>リンカー>入力>追加の依存ファイル に、
    websocket.lib
    を追加してください。
  4. 実装
    HelloWorldScene.h
    #pragma once
    
    #include "cocos2d.h"
    // ext
    #include "cocos-ext.h"
    // network
    #include "network/WebSocket.h"
    
    //! 最小のWebsocket構成テスト
    class TestWebsocketHelloWorld
    	: public cocos2d::Layer
    	, public cocos2d::network::WebSocket::Delegate
    {
    public:
    	static cocos2d::Scene* createScene();
    	TestWebsocketHelloWorld();
    	virtual ~TestWebsocketHelloWorld();
    	virtual void onOpen(cocos2d::network::WebSocket* ws);
    	virtual void onMessage(cocos2d::network::WebSocket* ws,const cocos2d::network::WebSocket::Data& data);
    	virtual void onClose(cocos2d::network::WebSocket* ws);
    	virtual void onError(cocos2d::network::WebSocket* ws,const cocos2d::network::WebSocket::ErrorCode& error);
    	virtual bool onTouchBegan(cocos2d::Touch *touch,cocos2d::Event *unused_event);
    	CREATE_FUNC(TestWebsocketHelloWorld);
    private:
    	cocos2d::network::WebSocket*	m_websocket;	//!< Websocketインスタンス
    	cocos2d::LabelTTF*		m_statusLabel;	//!< ステータス表示用
    	int				m_sendCount;	//!< 送信回数
    };
    HelloWorldScene.cpp
    #include "HelloWorldScene.h"
    
    // 文字列リテラルをutf8で扱う
    #pragma execution_character_set("utf-8")
    
    USING_NS_CC;
    USING_NS_CC_EXT;
    
    // シーン生成
    Scene* TestWebsocketHelloWorld::createScene()
    {
    	auto scene = Scene::create();
    	auto layer = TestWebsocketHelloWorld::create();
    	scene->addChild(layer);
    	return scene;
    }
    // コンストラクタ
    TestWebsocketHelloWorld::TestWebsocketHelloWorld()
    	: m_websocket(NULL)
    	, m_statusLabel(NULL)
    	, m_sendCount(0)
    {
    	auto winSize	= Director::getInstance()->getWinSize();
    	// タイトル表示
    	auto label = LabelTTF::create("TEST WebSocket","Arial",28);
    	label->setPosition(Point(
    		winSize.width / 2,
    		winSize.height - label->getContentSize().height*2));
    	addChild(label,0);
    	// ステータス表示
    	m_statusLabel = LabelTTF::create("オープン中です...","Arial",28,Size(winSize.width*0.8f,winSize.height*0.8f),TextHAlignment::CENTER,TextVAlignment::CENTER);
    	m_statusLabel->setPosition(Point(
    		winSize.width*0.5f,
    		winSize.height*0.5f));
    	this->addChild(m_statusLabel);
     	// websocketを初期化してオープン
    	m_websocket = new network::WebSocket();
    	if (!m_websocket->init(*this,"ws://echo.websocket.org"))
    	{
    		CC_SAFE_DELETE(m_websocket);
    	}
    	// タッチできるように
    	{
    		auto listener = EventListenerTouchOneByOne::create();
    		//タッチメソッド設定
    		listener->onTouchBegan = CC_CALLBACK_2(TestWebsocketHelloWorld::onTouchBegan,this);
    		//優先度100でディスパッチャーに登録
    		this->getEventDispatcher()->addEventListenerWithFixedPriority(listener,100);
    	}
    }
    // デストラクタ
    TestWebsocketHelloWorld::~TestWebsocketHelloWorld()
    {
    	// websocketクローズ
    	if (m_websocket) {
    		m_websocket->close();
    	}
    }
    // オープンした
    void TestWebsocketHelloWorld::onOpen(network::WebSocket* ws)
    {
    	m_statusLabel->setString("オープンしました\nタッチするとテストを開始します");
    }
    // 受信した
    void TestWebsocketHelloWorld::onMessage(network::WebSocket* ws,const network::WebSocket::Data& data)
    {
    	m_sendCount++;
    	char times[100] ={ 0 };
    	sprintf(times,"%d",m_sendCount);
    	std::string textStr = std::string("受信しました msg: ")+data.bytes+" : "+times;
    	m_statusLabel->setString(textStr.c_str());
    }
    // クローズした
    void TestWebsocketHelloWorld::onClose(network::WebSocket* ws)
    {
    	m_websocket = NULL;
    	// websocketインスタンスを解放
    	CC_SAFE_DELETE(ws);
    	m_statusLabel->setString("クローズしました");
    }
    // エラーが発生した
    void TestWebsocketHelloWorld::onError(network::WebSocket* ws,const network::WebSocket::ErrorCode& error)
    {
    	char buf[100] ={ 0 };
    	sprintf(buf,"エラーが発生しました code: %d",error);
    	m_statusLabel->setString(buf);
    }
    // タッチした時に送信する
    bool TestWebsocketHelloWorld::onTouchBegan(Touch *touch,Event *unused_event)
    {
    	if (m_websocket && m_websocket->getReadyState() == network::WebSocket::State::OPEN)
    	{
    		m_statusLabel->setString("メッセージを送信中です...");
    		m_websocket->send("Hello WebSocket, I'm a text message.");
    	}
    	else
    	{
    		std::string warningStr = "websocketインスタンスがオープン状態ではありません";
    		log("%s",warningStr.c_str());
    		m_statusLabel->setString(warningStr.c_str());
    	}
    	return true;
    }
  • Android版の設定

    Android.mk を編集

    LOCAL_WHOLE_STATIC_LIBRARIES += cocos_network_static

    と、

    $(call import-module,network)

    を追加。

HTTPクライアントを使う Edit

HTTPプロトコルを使用して通信のやりとりをする単純なHTTPクライアントのテストです。

  1. MyGameソリューションにlibNetworkプロジェクトを追加します。
    libNetworkプロジェクトを追加していなければ、ソリューションに追加してください。
    cocos2d\cocos\network\proj.win32\libNetwork.vcxproj
  2. MyGameプロジェクトにlibNetworkライブラリをリンク
    libNetworkライブラリをリンクしていなければリンクしてください。
    MyGameプロジェクト右クリック>プロパティ>共通プロパティ>参照>新しい参照の追加 で、libNetworkのチェックボックスを有効にして、OKをおします。
  3. 続いて、MyGameプロジェクトにlibcurl_impライブラリをリンクします。
    MyGameプロジェクト右クリック>プロパティ>構成プロパティ>リンカー>入力>追加の依存ファイル に、
    libcurl_imp.lib
    を追加してください。
  4. (書きかけです)

Windows版(VisualStudio)でビルドした時に出る警告 C4819 の解消方法 Edit

VisualStudio2013で、Cocos2d-xのプロジェクトをビルドすると CCSAXParser.h で、

warning C4819: ファイルは、現在のコード ページ (932) で表示できない文字を含んでいます。データの損失を防ぐために、ファイルを Unicode 形式で保存してください。

な警告が出てしまいます。
CCSAXParser.h は、utf8形式のエンコードなのですが、『BOM』が付いていません。
VisualStudioのutf8はBOM付きじゃないとダメみたいなので、BOMを付けて保存し直しましょう。
VisualStudio2013上で、エンコードの変更ができます。
CCSAXParser.hを開いてからツールバーのファイル>保存オプションの詳細設定
を選択します。
エンコードを

Unicode(UTF-8 シグネチャ付き) - コードページ65001

にしてOK。ファイルを保存します。これで、utf8のBOM付きで保存されます。

エンコード変更の必要があったファイルは

CCSAXParser.cpp
CCSAXParser.h
CCScale9Sprite.h
CCTMXXMLParser.cpp
MciPlayer.h (これはすでに文字化けしていました)
CCFont.cpp (これはエンコード変更するとwarning C4566: ユニバーサル文字名 '\u00A1' によって表示されている文字は、現在のコード ページ (932) で表示できません  な警告が新たに発生してしまうので、スルーしました)
plane.c
vec3.c

になります。

この状態でリビルドすれば、警告がなくなっているのが確認できると思います。


リロード   新規 編集 凍結 差分 添付 複製 名前変更   ホーム 一覧 単語検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS
Last-modified: 2014-03-30 (日) 03:37:38 (1182d)