いちおくまんえん

最近はcocos2d-xでゲームアプリ「いちおくまんえん」の制作がメインです。 あとアニメも少々・・

プロローグ画面作成① CocosBuilderとの紐付け そして初のyoutube投稿

ついにyoutubeに動画投稿しちゃいました(・∀・)

音質が終わってるのはお許し下さい・・。
組み込みマイクでPCから出てる音拾ってるだけなので・・。


ゲームアプリ「いちおくまんえん」制作過程01 - YouTube

これでどんな感じになるかが伝わりやすくなったかなと思います( ・`ω・´)

しかし、どんだけお金持ちになりたいんだっていう(;´∀`)ね


基本的にアニメーション部分はCocosBuilder側で実装しているので、cocos2d-xのソースでアニメーションを作っている部分はありません。

なので、アニメーションの管理部分と途中で値や画像を差し替えたい部分のみ紐付けて上げれば良いので楽ちんです。

過去にCocosBuilderとの連携については書いているのですが、cocos2d-xのversion2系での内容なので今回のversion3系での内容をうpします。

今回は繋ぎ込みがメインなので全てのアニメーションを繋げて連続再生させています。
ゲームのロジックは次の更新時に組み込みます。

PrologueScene.h

#ifndef __PROLOGUE_SCENE_H__
#define __PROLOGUE_SCENE_H__

#include "cocos2d.h"
#include "cocos-ext.h"
#include "AppMacros.h"

NS_ICHI_BEGIN

class PrologueScene
: public cocos2d::Layer
// 変数結びつけます
, public cocos2d::extension::CCBMemberVariableAssigner
// アニメーション完了を受け取れます
, public cocos2d::extension::CCBAnimationManagerDelegate
{
public:
    PrologueScene();
    virtual ~PrologueScene() {};
    
    static cocos2d::Scene* createScene();
    
    virtual bool init() override;
    // シーン切り替え後にBGMを再生
    virtual void onEnterTransitionDidFinish() override;
    // タップでゲーム開始させる
    virtual bool onTouchBegan(cocos2d::Touch* touch, cocos2d::Event* event) override;
    // 開始のアニメーション
    void animationStart();
    // 開始のアニメーションを終了するアニメーション
    void animationStartEnd();
    // テキスト表示開始のアニメーション
    void animationTextStart();
    // テキスト表示終了のアニメーション
    void animationTextEnd();
    
    // CocosBuilder通常メンバ変数紐付け
    virtual bool onAssignCCBMemberVariable(cocos2d::Object* pTarget, const char* pMemberVariableName, cocos2d::Node* pNode);
    // CocosBuilderアニメーション紐付け
    void setAnimationManager(cocos2d::extension::CCBAnimationManager* pAnimationManager);
    // CocosBuilderアニメーション完了時にタイムライン名が引数として実行される
    virtual void completedAnimationSequenceNamed(const char *name);
    CREATE_FUNC(PrologueScene);
    
private:
    cocos2d::LabelTTF* _messageTTF;
    cocos2d::extension::CCBAnimationManager* _animationManager;
};

// ccbiに設定した拡張クラス(今回の場合PrologueScene)を読み取る為のローダー
// 別ファイルPrologueSceneLoader.hなどを作成して分けても構いません
class PrologueSceneLoader : public cocos2d::extension::LayerLoader {
public:
    virtual ~PrologueSceneLoader() {};
    CCB_STATIC_NEW_AUTORELEASE_OBJECT_METHOD(PrologueSceneLoader, loader);
    
protected:
    CCB_VIRTUAL_NEW_AUTORELEASE_CREATECCNODE_METHOD(PrologueScene);
};

NS_ICHI_END

#endif // __PROLOGUE_SCENE_H__

PrologueScene.cpp

#include "PrologueScene.h"
#include "SimpleAudioEngine.h"

USING_NS_CC;
USING_NS_CC_EXT;
using namespace CocosDenshion;
USING_NS_ICHI;


PrologueScene::PrologueScene()
: _messageTTF(nullptr)
, _animationManager(nullptr)
{
    // こっちで初期化するより上のコロンで繋げて書いている方が余計な処理が入らない分軽くなるそう
}

Scene* PrologueScene::createScene()
{
    auto scene = Scene::create();
    // タイトルのccbiファイルを読み込む
    auto nodeLoaderLibrary = NodeLoaderLibrary::getInstance();
    // プロローグシーンのローダーを追加
    nodeLoaderLibrary->registerNodeLoader("PrologueScene", PrologueSceneLoader::loader());

    CCBReader* reader = new CCBReader(nodeLoaderLibrary);
    auto prologueNode = reader->readNodeGraphFromFile("ccbi/PrologueScene.ccbi");
    // アニメーションマネージャーをセットする
    static_cast<PrologueScene*>(prologueNode)->setAnimationManager(reader->getAnimationManager());
    scene->addChild(prologueNode);
    // 開放
    reader->release();

    return scene;
}


bool PrologueScene::init()
{
    CCLOG("PrologueScene::init()");
    if ( !Layer::init() )
    {
        return false;
    }
    
    // BGM・SEのプリロード
    SimpleAudioEngine::getInstance()->preloadBackgroundMusic(BGM_PROLOGUE);
    SimpleAudioEngine::getInstance()->preloadEffect(SE_TOUCH_NORMAL);

    // シングルタップのみ受付 最初のアニメーションまではタップさせない
    setTouchEnabled(false);
    setTouchMode(Touch::DispatchMode::ONE_BY_ONE);
    
    return true;
}

void PrologueScene::onEnterTransitionDidFinish()
{
    CCLOG("PrologueScene::onEnterTransitionDidFinish()");
    Layer::onEnterTransitionDidFinish();

    SimpleAudioEngine::getInstance()->playBackgroundMusic(BGM_PROLOGUE, true);
    animationStart();
}

bool PrologueScene::onTouchBegan(Touch *touch, Event *event)
{
    CCLOG("PrologueScene::onTouchBegan()");
    SimpleAudioEngine::getInstance()->playEffect(SE_TOUCH_NORMAL);
    return false;
}

void PrologueScene::animationStart()
{
    CCLOG("PrologueScene::animationStart()");
    _animationManager->runAnimationsForSequenceNamedTweenDuration("Start", 0.0f);
}

void PrologueScene::animationStartEnd()
{
    CCLOG("PrologueScene::animationStartEnd()");
    _animationManager->runAnimationsForSequenceNamedTweenDuration("StartEnd", 0.0f);
}

void PrologueScene::animationTextStart()
{
    CCLOG("PrologueScene::animationTextStart()");
    _animationManager->runAnimationsForSequenceNamedTweenDuration("TextStart", 0.0f);
}
void PrologueScene::animationTextEnd()
{
    CCLOG("PrologueScene::animationTextEnd()");
    _animationManager->runAnimationsForSequenceNamedTweenDuration("TextEnd", 0.0f);
}


bool PrologueScene::onAssignCCBMemberVariable(Object* pTarget, const char* pMemberVariableName, Node* pNode)
{
    CCLOG("onAssignCCBMember: %s", pMemberVariableName);
    CCB_MEMBERVARIABLEASSIGNER_GLUE(this, "m_messageTTF", LabelTTF*, _messageTTF);

    return true;
}

void PrologueScene::setAnimationManager(CCBAnimationManager *pAnimationManager)
{
    CCLOG("PrologueScene::setAnimationManager()");
    CC_SAFE_RELEASE_NULL(_animationManager);
    _animationManager = pAnimationManager;
    CC_SAFE_RETAIN(_animationManager);
    // アニメーション終了を受け取れるようにデリゲートをセット
    _animationManager->setDelegate(this);
}

void PrologueScene::completedAnimationSequenceNamed(const char *name)
{
    CCLOG("completedAnimation: %s", name);
    // タイムラインの名前によって処理を分ける。必要のあるものだけ指定する
    if(strcmp(name,"Start") == 0)
    {
        setTouchEnabled(true);
        animationStartEnd();
    }
    else if(strcmp(name,"StartEnd") == 0)
    {
        animationTextStart();
    }
    else if(strcmp(name,"TextStart") == 0)
    {
        animationTextEnd();
    }
    else if(strcmp(name,"TextEnd") == 0)
    {
        animationTextStart();
    }
}

一応こんな感じに書いてあげれば先に上げた動画のようにプロローグの開始→開始の終了→テキスト表示開始→終了→開始→終了→(ry
な流れでCocosBuilderで設定したタイムラインを再生させることが可能です。

演出とかを考えるセンスが皆無なので大量の時間を費やしてもこんな感じのものしか作れませんでした。゚(゚´Д`゚)゚。

素敵なキャラ絵は頂けるけどUI周りがえらいことになりそうな悪寒・・。どうにかしないと!

今回のコミットログ
https://github.com/yasuhiro-matsuda/ichi_okuman_yen/commit/3a4fbf93725741f1c1beabe9ef183e4de516e014