この辺りで大体折り返し地点です。
さて、弾いたボールはだんだんと減速していくようにしましょう。色々なやり方があるかと思いますが、今回はシンプルにupdateの中でカウンタを回して、一定回数以上カウンタが回ったらスピードを落としていくやり方にしましょう。
と言うか、このやり方しか知りません・・・
プログラム実装
それでは、ボールの減速処理は下記のとおりです。ハイライト部分を追記してください。
HelloWorldScene.cpp HelloWorld::update
void HelloWorld::update(float dt){ if(_ball->_isBallMoving){ float x = _ball->getPosition().x - _ball->_speed*cosf(CC_DEGREES_TO_RADIANS(_ball->_degree)); float y = _ball->getPosition().y + _ball->_speed*sinf(CC_DEGREES_TO_RADIANS(_ball->_degree)); _ball->setPosition(Vec2(x, y)); // ドロップに接触した場合の跳ね返りの処理 std::list<Sprite*>::iterator it; for(it = _dropList.begin(); it != _dropList.end(); it++){ if(hitDetectionOval(_ball, (*it))){ // 跳ね返り角度の更新 _ball->_degree = getDegree(_ball->getPosition(), (*it)->getPosition()); } } // 画面端に接触した場合の跳ね返りの処理 Size visibleSize = Director::getInstance()->getVisibleSize(); // 画面下端 if(_ball->getPosition().y - _ball->getContentSize().height / 2 <= 0){ _ball->_degree = _ball->_degree * -1; y = _ball->getContentSize().height / 2; } // 画面上端 if(_ball->getPosition().y + _ball->getContentSize().height / 2 >= visibleSize.height - _enemy->getContentSize().height){ _ball->_degree = _ball->_degree * -1; y = visibleSize.height - _ball->getContentSize().width / 2 - _enemy->getContentSize().height; } // 画面左端 if(_ball->getPosition().x - _ball->getContentSize().width / 2 <= 0){ _ball->_degree = 180 - _ball->_degree; x = _ball->getContentSize().width / 2; } // 画面右端 if(_ball->getPosition().x + _ball->getContentSize().width / 2 >= visibleSize.width){ _ball->_degree = 180 - _ball->_degree; x = visibleSize.width - _ball->getContentSize().width / 2; } _ball->setPosition(Vec2(x, y)); // 減速処理 _ball->_speedDownCount++; // 一定回数をカウントしたら徐々に減速する if(_ball->_speedDownCount > 100){ // スピードが0になったらムーブフラグをfalseにする。減速したスピードを元に戻し、スピードダウンカウントを0に初期化する if(_ball->_speed <= 0){ // 減速していたスピードを元に戻す _ball->_speed = 50; // ボール移動中フラグを元に戻す _ball->_isBallMoving = false; // カウンタのリセット _ball->_speedDownCount = 0; }else{ // 減速処理 _ball->_speed -= 1; } } } }
HelloWorldScene.cpp HelloWorld::onTouchBegan
bool HelloWorld::onTouchBegan(Touch* pTouch, Event* pEvent){ // ボールが動いていない時だけタップ可能とする if(!_ball->_isBallMoving){ // タップした座標を取得 Vec2 touchPoint = convertTouchToNodeSpace(pTouch); // タップした座標がボール画像の中に入っているかどうかを判断 if(_ball->boundingBox().containsPoint(touchPoint)){ // タップした座標とボール画像の座標の二点間の角度の取得 _ball->_degree = getDegree(_ball->getPosition(), touchPoint); // 矢印オブジェクトの角度を設定 _allow = Sprite::create("allow.png"); _allow->setPosition(Vec2(_ball->getPosition().x, _ball->getPosition().y)); _allow->setRotation(_ball->_degree); this->addChild(_allow, 0, 7); return true; } } return false; }
プログラムの解説
ボール停止までの時間の調整
スピードの減速をカウンタで制御します。このプログラムではカウンタが100を超えたらスピードが1ずつ減速するようにしています。スピードが0になったら減速をやめ、ボールのスピード、フラグ、減速カウンタを元に戻します。
ボールが動き出してから約150カウント(100+50)で停止するようになっています。60fpsでは約2.5秒ですが、私の環境のシミュレータは30fps程度しか出ないため、ボールの動き出しから停止まで5秒程度かかります。
この辺りは実機で確認してゲームとしてのテンポを調整することになります。
ボールが動いているときはタップ不可能とする
このゲームではボールが動いている時にタップをさせることを想定していません。というわけで、タップしてボールを弾くという操作は、onTouchBeganメソッでボールが止まっている時だけに限定しています。また、ボールが停止したタイミングで再度タップ可能にするようにフラグを変更しています。
シミュレータの起動
それではシミュレータを起動しましょう。確認する項目は以下の3点です。
・ボールが減速すること
・ボールの移動~停止からの、再度ボールの移動~停止が可能なこと
・ボールが動いている最中にタップできないこと。(タップしても矢印画像が出ないこと)
どうでしょうか、確認項目をクリアできたでしょうか。なんかテストっぽくなってきましたね・・・!!(戦慄) テストは大事ですが退屈なものです・・・
次回はボールを弾く強さを調節するタイミングゲージを実装します!!
次回
第10回 「タイミングゲージによるボール移動距離の強弱付け」
はじめまして。
さとよしです。
cocosを使ったことがなかったので、こちらの記事で勉強させてもらっています。
とても有益で助かっています。
ところで、1点、誤植を見つけましたので、指摘させていただきます。
第9回 「移動しているボールの減速」
の、
HelloWorldScene.cpp HelloWorld::update
のソース改変部分、65行目がハイライトされていませんが、
65行目もハイライトするのが正しいと思います。
よろしくご確認ください。
さとよし
ご連絡ありがとうございます。
ご指摘の通りですのでハイライト部分を修正しておきました。