質問: よろしくお願いします。 C++とCocos2d-xを触りだして一週間程度です。 ゲームの制作において円運動を使いたいのですが、C++とCocos2d-xというものを触ってからとても日が浅いです。 Sceneの作成や遷移は出来ますが、ゲームの動きとなる部分が全く進まず、コードが全く思いつきません。 携帯向けのゲームですので、円の中心は画面の真ん中に考えています。 よろしくお願い致します。
回答: こんにちは Cocos2d-x 等を使っている者です Cocos2d-x(C++版)として回答します ### ■方法1、フレーム単位に呼んでもらい自分で動きを付ける this->scheduleUpdate() を呼ぶとフレーム単位で自身の update がコールされるので、update で setPosition() などを使って動きを付けます。 自レイヤーを作り init でスケジュールする。 ※レイヤーではなく自分のシーンクラスでも構いません。 ``` bool MyLayer::init() { ..略 this->scheduleUpdate(); ..略 ``` すると自レイヤークラスの update メソッドが約 1/60 秒ごとに呼ばれる 自転 ``` void MyLayer::update(float delayTime) // delayTime がフレーム時間(秒)です { float newRot = _sprite->getRotation() + delayTime * _angVel; _sprite->setRotation( newRot ); } ``` 公転 ``` void MyLayer::update(float delayTime) // delayTime がフレーム時間(秒)です { // レイヤーの中心座標 Size siz = this->getContentSize(); Vec2 center( siz.width/2, siz.height/2 ); // 画面のサイズならこちら // auto pDirector = Director::getInstance(); // Size siz = pDirector->getWinSize(); _revo += delayTime * _angVel; // 時間経過による角度を更新 float r = CC_DEGREES_TO_RADIANS( _revo ); // 度数法を弧度法へ Vec2 newPos( _len * cosf(r), _len * sinf(r) ); _sprite->setPosition( center + newPos ); } ``` 以下をメンバーなどで事前に定義&設定したとする ``` Sprite* _sprite は create & addChildしたスプライト float _angVel は自転角速度 (度数法) float _revo は公転角度 (度数法) float _len は公転で中心からの距離 (pixel) ``` ・参考 ### ■2、アクションで動きを付ける 条件などによる細かな動きがなければアクションで行うと簡単です。 自転 ``` _sprite->runAction( RepeatForever::create( // 無限に動かす RotateBy:crete( 0.5f, 90 ) // 0.5 秒あたり 90 度+ )); ``` 公転 ``` // レイヤーの中心座標 Size siz = this->getContentSize(); Vec2 center( siz.width/2, siz.height/2 ); _sprite->runAction( RepeatForever::create( // 無限に動かす ActionFloat::create( 2.0f, 0, 360, // 2 秒で 360 度+ this, center // C++ のラムダ式で処理 { float r = CC_DEGREES_TO_RADIANS( angle ); // 度数法を弧度法へ Vec2 newPos( _len * cosf(r), _len * sinf(r) ); _sprite->setPosition( center + newPos ); }) )); ``` 他にも多くのアクションがあります。 * MoveTo::create で移動 * ScaleTo::create で拡大縮小 * TintTo::create で色変化 * FadeTo::create でフェードインアウト * Sequence::create で流れが組めます。(回転後に移動してその後でフェードアウトするなど) * Spawn::create で組み合わせができます(回転しながら移動しつつ同時に色変化など) * DelayTime::create で時間待ち * RemoveSelf::create で自動削除ができます これ以外にもアクションがあります。 **・参考** プロジェクト cpp-tests の 3.Actions ~ 5.Actions を参照 コードは ActionsTest/ActionsTest.cpp ActionsEaseTest/ActionsEaseTest.cpp など (chrome ならば右クリックで日本語に翻訳) ### ■方法3、物理エンジンで動きを付ける 余談ですがこのような方法もあるという事で、モーターや関節でクランクなどもできます。 基本的な物理シーンの設定 動きや値の設定例 プロジェクト cpp-tests の PhysicsTest を参照 ### ■補足 update や runAction は Node クラスの仕様なので、Sprite だけではなくシーンやレイヤーやボタンやラベルなど全てのパーツに使えます。 ボタンにアクションをつける ``` MenuItemSprite* menuItem; menuItem->runAction( ~ ui::Button* button; button->runAction( ~ ``` 例えばキャラの種類が多くあり、種類ごとに異なる動きを付ける場合、レイヤーの update で行うと複雑なコードになりますが、スプライトごとにクラス分けして動きを付けるとスマートになります。 ``` class BattleShip02 : public Sprite { }; ``` という自スプライトクラスを作り ``` bool BattleShip02 ::init() { this->scheduleUpdate(); ・・略 void BattleShip02 ::update(float delayTime) { this->setPosition( ~ ); などで動きをつける } ``` と実装する事もできます。