ホーム < ゲームつくろー! < IKD備忘録

Cocos2d-x
ロゴのフェードインアウトをアクションで実現する

(2015. 1. 19)


 前章でロゴを自前でフェードインアウトさせてみましたが、コードが割と煩雑でした。Cocos2d-xには数値を連続的に動かすための強力なアニメーションクラスが多数用意されています。それらを使ってもっとスマートにロゴのフェードインアウトを実現させてみましょう。



@ CCFadeIn、CCFadeOut

 まずは改良したコードをご覧ください:

ロゴフェードイン
#include "LogoLayer.h"

USING_NS_CC;

LogoLayer::LogoLayer() : logo_() {
}

LogoLayer::~LogoLayer() {
}

bool LogoLayer::init() {

    if ( Layer::init() == false )
        return false;

    this->scheduleUpdate();

    Size display = Director::getInstance()->getVisibleSize();

    logo_ = Sprite::create( "logo.png" );
    logo_->setPosition( display.width / 2, display.height / 2 );
    logo_->setOpacity( 0.0f );

    CCSequence *seq = CCSequence::create(
        CCFadeIn::create( 1.0f ),
        CCFadeIn::create( 1.5f ),
        CCFadeOut::create( 1.0f ),

        CCCallFunc::create( this, callfunc_selector( LogoLayer::end ) ),
        NULL

    );

    logo_->runAction( seq );

    this->addChild( logo_, 0, "logo" );

    return true;
}

void LogoLayer::end() {
}

前回フェードインアウトの状態遷移を起こすためにあれこれ作ったメソッドが無くなってしまいました。それに関連するメンバ変数も無くなり、logo_だけが残りました。ポイントは上の太文字部分です。

 SpriteにはrunActionメソッドが用意されています。この引数にActionオブジェクトを渡すとそれに従ったアクションが起こります。アクションには非常に沢山種類があります。上にあるCCFadeIn、CCFadeOutもそういうアクションの一つです。

 CCFadeInはSpriteに対してフェードインを起こすアクションです。CCFadeIn::createメソッドを通して作成します。引数にはフェードインしきるまでの時間を秒数で指定します。同じようにCCFadeOutはSpriteにフェードアウトを起こさせます。



A CCSequenceで連続アクション、そしてコールバック

 上の実装例ではCCSequenceというアクションを作っています。これは複数のアクションを連続的に起こすためのコンテナアクションです。Sequence::createメソッドで作成します。このメソッドには連続的に起こしたいアクションを引数に繋げて行けます。これは可変長引数を使っているため実現できているようです。上の例では最初の1秒間でフェードイン、そこで1.5秒待って(同じくフェードインさせているだけ)、さらに1.0秒でフェードアウトさせているのがわかります。これが分かりやすいと言うのがアクションを使う良さですよね。

 上の例では、フェードアウトの後に「CCCallFunc」ともう一つアクションを起こしています。これはコールバックをしてくれるアクションです。第1引数にはコールバックを保持している物のポインタ(上の例だとLogoLayer自身)、第2引数にコールバックメソッドを渡します。この時「callfunc_selector」というマクロを使うようです。

 アクションを起こした場合、その終わりを待って何かしたいと言う事がとても多くなります。ロゴの表示だとロゴが表示し終わったら次のシーンに飛びたいわけです。上のコールバックの仕組みはゲームを作る上で多用されると思います。

 そして大切なこと、上のような可変長引数でアクションを指定した場合、最後は必ずNULLで締めます。これをしないと落ちます!注意です。



B 同時に動かしたい

 例えばフェードインしながらSpriteの位置やスケールを変化させるという事は、ゲームの演出で多用される一つです。アクションは登録するとそれを複数同時に実行してくれます。例えば上のロゴをフェードインさせながら少し上に動かし、スケールもちょっと大きくするというアクションにするには次のようにします:

ロゴフェードイン
#include "LogoLayer.h"

USING_NS_CC;

LogoLayer::LogoLayer() : logo_() {
}

LogoLayer::~LogoLayer() {
}

bool LogoLayer::init() {

    if ( Layer::init() == false )
        return false;

    this->scheduleUpdate();

    Size display = Director::getInstance()->getVisibleSize();

    logo_ = Sprite::create( "logo.png" );
    logo_->setPosition( display.width / 2, display.height / 2 - 50.0f );
    logo_->setOpacity( 0.0f );
    logo_->setScale( 0.8f );

    CCSequence *seq = CCSequence::create(
        CCFadeIn::create( 1.0f ),
        CCFadeIn::create( 1.5f ),
        CCFadeOut::create( 1.0f ),
        CCCallFunc::create( this, callfunc_selector( LogoLayer::end ) ),
        NULL
    );

    logo_->runAction( seq );
    logo_->runAction( CCMoveTo::create( 0.7f, Vec2( display.width / 2, display.height / 2 ) ) );
    logo_->runAction( CCScaleTo::create( 0.7f, 1.0f ) );

    this->addChild( logo_, 0, "logo" );

    return true;
}

void LogoLayer::end() {
}

CCMoveToは現在の位置から指定の位置まで動かすアクションオブジェクト、CCScaleToはスケールを変化させるアクションオブジェクトです。基本的な動きはこれらのアクションを使えば相当に細かくそして綺麗に作り込んで行けそうです。