ゲームの操作感がわかってきたところで、ゲーム全体の流れの大枠を作っていきましょう。
今回のゲームはターン制を想定しています。つまり、プレイヤーのターンと敵のターンです。
なんだ、つまり表題通り、プレイヤーのターンと敵のターンを作ればいいのね。
・・・確かにその通りなのですが、もう少し、ゲームプレイの流れを整理していきましょう。
ゲームの流れの整理
ゲーム開始>プレイヤーのターン>敵のターン>プレイヤーのターン>敵のターン・・・
と進んでいった時、最後には勝敗を付けなければいけません。つまり、プレイヤーの勝利、もしくはプレイヤーの敗北がゲームの流れの最後に存在します。
この、「プレイヤーのターン」、「敵のターン」、「プレイヤーの勝利」、や「プレイヤーの敗北」という出来事を、ゲームが持つ「状態」という捉え方をしてみましょう。
状態は下図の様にその状態を変えていくことになります。
それでは、この4状態をプログラムに実装していきましょう。
プログラムの実装
HelloWorldScene.h
// ゲームの状態 enum State{ TYPE_PLAYER_TURN, // プレイヤーのターン TYPE_ENEMY_TURN, // 敵のターン TYPE_WIN, // 勝利イベント TYPE_LOSE, // 敗北イベント }; State _state = TYPE_PLAYER_TURN; // 最初はプレイヤーのターンから開始する bool _gameEndEvent = false; // 勝利イベント、敗北イベントを一回のみ実行するためのフラグ
HelloWorldScene.cpp HelloWorld::update
void HelloWorld::update(float dt){ // プレイヤーのターン if(_state == TYPE_PLAYER_TURN){ // パワーゲージの増加 if(_isPowerGaugeCounting){ if(_powerGaugeCount >= 100){ _powerGaugeCount = 100; _powerGaugeStopCount++; if(_powerGaugeStopCount >= 6){ _powerGaugeCount = 0; _powerGaugeStopCount = 0; } }else if(35 < _powerGaugeCount && _powerGaugeCount < 100){ _powerGaugeCount += 10; }else{ _powerGaugeCount += 5; } // パワーゲージ増減の表示 viewPowerGauge(); } 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()); // 効果音 CocosDenshion::SimpleAudioEngine::getInstance()->playEffect("reflection.mp3"); // ヒットエフェクトの表示 Vec2 pos = Vec2(ccpMidpoint(_ball->getPosition(), (*it)->getPosition())); viewHitEffect(pos); } } // 画面端に接触した場合の跳ね返りの処理 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 > _powerGaugeCount){ // スピードが0になったらムーブフラグをfalseにする。減速したスピードを元に戻し、スピードダウンカウントを0に初期化する // 減速し終えたら攻撃エフェクト if(_ball->_speed <= 0){ // 減速していたスピードを元に戻す _ball->_speed = 50; // ボール移動中フラグを元に戻す _ball->_isBallMoving = false; // カウンタのリセット _ball->_speedDownCount = 0; }else{ // 減速処理 _ball->_speed -= 1; } } } } // 敵のターン else if(_state == TYPE_ENEMY_TURN){ } // 勝利イベント else if(_state == TYPE_WIN){ } // 敗北イベント else if(_state == TYPE_LOSE){ } }
これでとりあえず「状態」のガワだけできました。ガワだけなので、まだプレイヤーのターンから状態が遷移することはありません。
次回はターンの交代、プレイヤーの攻撃、敵の攻撃の実装に入りましょう。
次回