またnullptrだよ...
少し間が空いてしまいましたが取り敢えずの進捗報告をします。
今回の成果
- 簡単なシーケンス遷移の実装
- ジャンプの高さ、時間制限
- ジャンプすると自動的に一度相手をロックする
- 弾の発射、またその弾が一定時間たつ、又は相手に当たると消える
- Imageクラスの実装
という感じです。
シーケンス遷移の階層は簡単のため1段階にし、タイトル、ゲーム開始前、ゲーム、ゲーム結果画面を実装しました。*1
ジャンプに関しては書いてある通りで、弾の当たり判定は「弾の座標がロボの直方体の中に入るかどうか」というシンプルな実装になっています。
Image
クラスに関しては画像をただ表示するクラスです。これは、以前制作したボンバーマンクラスにもありましたが*2、今回はハードウェアの力を借りて三角形に分割して表示しようという方針ですので別で作る必要がありました。前回に比べ、かなりすっきりしたコードになりハードウェアの力を実感しております...
今回の失敗
- シーケンス遷移の作り方を完全に忘れていた(一番時間を食いました...)
- この本では画像ファイルを2冪×2冪で取ることをすっかり忘れていた
- ジャンプ時に相手と反対方向を向き、空中浮遊したまま地面に戻らない
またもう一つ以下のような失敗をしました。簡単に言うとnullptr
です。
ロボ(プレイヤー)の位置、角度、カメラの初期位置から、現在のカメラの位置を設定する以下の部分を関数化してupdate
関数の見た目をすっきりさせようと試みたところ画面が真っ黒になってしまいました…
Child* Game::update(Parent* parent) { //ここから Matrix34 w; w.setTranslation(mRobo[mPlayerId]->position()); w.rotateY(mRobo[mPlayerId]->angleY()); Vector3 cameraPos, cameraTarget; w.multiply(&cameraPos, mRobo[mPlayerId]->cameraPosition()); w.multiply(&cameraTarget, mRobo[mPlayerId]->cameraTarget()); mCamera->setPosition(cameraPos); mCamera->setTarget(cameraTarget); //ここまでを関数化 }
本当に関数化以外は何もしていなかったので大パニック!
実際に悪さをしていたのはsetPosition
とsetTarget
の2つの関数だと判明。
// Cameraクラス内 void Camera::setPosition(Vector3& pos) { mPosition = &pos; } void Camera::setTarget(Vector3& target) { mTarget = ⌖ }
という定義だったので、update
内で定義していた変数cameraPos
,cameraTarget
を新しい関数内で定義すると、新しい関数の実行後にその2つの変数は消され、mPosition
,mTarget
は既に存在しない参照を見ることになります。(同じようなミスを前にもしたような…)
// Cameraクラス内 void Camera::setPosition(Vector3& pos) { *mPosition = pos; } void Camera::setTarget(Vector3& target) { *mTarget = target; }
へ訂正すると、mPosition
,mTarget
の(事前に確保されている)参照先にcameraPos
,cameraTarget
の値を代入できるので、解決。(mPosition,mTarget == 0
の時に*mPosition
を見てよいのか気になりますが、これはCameraクラスのコンストラクタ内でnew
によりメモリを確保しているので大丈夫です。)
関数化だけでもバグの原因になってしまうという良い教訓でした。
これからもぼちぼち頑張っていきます。