だらだら〜個人事業〜

HatenaDiaryから引っ越してきました。Githubもnyakagawanです。

coco2dx 3.0

作業めも

りぽじとり:https://github.com/nyakagawan/MyGame

Resourceファイルの相対パス指定

Resources/chara/majo.pngの画像ロードができない・・・。Resources/majo.pngならおk。パスの解決に失敗しているみたいだけど、いちいち全SubDirectoryをAddSearchPathしないと駄目とか??まさか。
謎だが、先に進む

plistでSpriteAnimation

cocos付属のSampleコードを参考に。
素材は[ぴぽや]さんのを使わせていただいた
http://piposozai.blog76.fc2.com
96x128のpng画像

こういう32x32ピクセルの魔女っこの歩くアニメーションを実装してみる。
http://blog-imgs-68-origin.fc2.com/p/i/p/piposozai/optpix_png2.png
テストなので一番上の列の左から順に再生するだけ。

SpriteAnimationのSpriteSheetはplistファイルで指定する様子。TexturePackerとかの結合ツールでバラバラのスプライトをくっつけて一緒にplistを吐き出して利用するのが真面目な使い方みたいだが、今回は結合済みのSpriteを使うので、plistを手書きする。
plistはcocos2dx TestCppのなかのResources/animations/grossi_blue.plistをパクってきた。これをxcodeで開いて編集。

  • Root/texture
    • もとになる画像の縦横サイズを設定
  • Root/frames
    • アニメーションフレームの定義。フレームの名前を付けて、表示サイズなどの設定を行う。offsetX/Yがわからない(表示するときのずらし量だろうか?)

コードはTestCpp/SpriteTest/SpriteTest.cpp SpriteFrameTest::onEnter() の辺を持ってくる。こげなかんじ。

    auto pSprite = Sprite::create("majo.png");
    pSprite->setPosition(Point(100,100));
    this->addChild(pSprite);

    
    auto cache = SpriteFrameCache::getInstance();
    cache->addSpriteFramesWithFile("majo.plist", "majo.png");
    
    auto s = Director::getInstance()->getWinSize();
    auto _sprite1 = Sprite::createWithSpriteFrameName("majo_01.png");
    _sprite1->setPosition( Point( s.width/2-16, s.height/2) );
    
    auto spritebatch = SpriteBatchNode::create("majo.png");
    spritebatch->addChild(_sprite1);
    addChild(spritebatch);
    
    Vector<SpriteFrame*> animFrames(3);
    
    char str[100] = {0};
    for(int i = 1; i < 3; i++)
    {
        sprintf(str, "majo_%02d.png", i);
        auto frame = cache->getSpriteFrameByName( str );
        animFrames.pushBack(frame);
    }
    
    auto animation = Animation::createWithSpriteFrames(animFrames, 0.5f);
    _sprite1->runAction( RepeatForever::create( Animate::create(animation) ) );

これは、Layerのinitで実行している。実行すると魔女っ子がとことこあるく。

次はAction

ここはcocos2dxでも特徴のある部分かと思う。なんとなく使いどころのイメージは湧いてるが、さてはて。。。

とりあえずこちらのサイトは役立ちそうだ。いろんなActionのScreenShotがみることができる。

魔女っ子をEasingして永遠にうろうろさせるアクションをつくったみた。
ちょろっとActionについて調べてみたが、自分の作りたいものを作るには、一般的なX/Yに自分で値を足していってというアプローチをとるほうが良さそう。でもせっかく作ったのでコードは張っとく

    // create move actions
    {
        auto seqActs = Vector<FiniteTimeAction*>();
        {
            auto spawnActs = Vector<FiniteTimeAction*>();
            
            auto mv = MoveBy::create(2, Point(0, -50));
            auto es = EaseInOut::create(mv, 10);
            spawnActs.pushBack( es );
            
            mv = MoveBy::create(2, Point(50, 0));
            es = EaseInOut::create(mv, 10);
            spawnActs.pushBack( es );
            
            auto actSpawn = Spawn::create( spawnActs );
            seqActs.pushBack(actSpawn);
        }
        {
            auto spawnActs = Vector<FiniteTimeAction*>();
            spawnActs.pushBack( MoveBy::create(2, Point(0, 50)) );
            spawnActs.pushBack( MoveBy::create(2, Point(-50, 0)) );
            auto actSpawn = Spawn::create( spawnActs );
            seqActs.pushBack(actSpawn);
        }
        
        auto actSeq = Sequence::create(seqActs);
        
        _sprite1->runAction(RepeatForever::create(actSeq));
    }

Unitクラスを作ってみる

さて、古き良きゲームオブジェクト指向設計に則ってUnitクラスをつくってみる。まぁWorkだとか、Taskだとかいろいろ呼び方はあるだろうけど、ゲーム中のキャラとか弾とかのオブジェクトに当たるクラスということで。
cocos2d::Nodeを継承して、そこに先ほど作成したSprite関係のやつをぶっ込んだらとりあえず絵のでるUnitクラスが出来上がる。

memo

単にupdateをoverrideしただけでは、コールされない。scheduledUpdate()を実行しておく必要がある。

memo2

時間に関するキャラの属性変更に関してはActionを継承して独自に作る。UnitではStateやスプライトの管理を行うってのがあってる???

memo3

Componentクラスってなんだろう?これはユーザが継承して使うって良いようなものなんだろうか