オブジェクト同士の当たり判定を実装した
四分木衝突空間の実装が完了した。
これでオブジェクト対オブジェクトの衝突も可能になったぞ。
(なお、今回から動画はニコ動のリンクを貼り付けることにする。gifに変換するとサイズが馬鹿でかくなってはてなブログの10MB規制に引っかかってしまうためだ。gifは画質も落ちるし…)
四分木衝突空間は、だいぶ昔に書いたソースコードがあったので、そいつをHDDから引っ張り出してD言語に書き直した。
なんか昔の実装は結構無駄なことやってたな… かつての自分は何を考えていたんだ…? まあ過去の資産が無駄にならずに済んでよかった。
それにしてもモートン序列ってすげえよな。数学全然わからん勢の筆者でも数学のミラクルを感じる。
こんなとき役立った rdmd
分割レベルごとの先頭の空間にアクセスするオフセット配列が必要でこんなコードを書いたのだが、
private static immutable int[] offsets = 0 ~ maxLevel.iota.cumulativeFold!((a, b) => a + 4 ^^ b)(0).array;
さて困った。ほんとに正しいオフセットがこのコードで生成されるのか自信がない。コーディングしているとたまにあるやつだ。
そんな時にサクッと結果を確認できるので rdmd
は便利なのだ。
rdmd --eval
で楽々検証
rdmd
の --eval
機能を使用する。
rdmd --eval="..."
とコマンドを打ち込めば、ダブルコーテーション内のコードを main
関数で包み、コンパイルして即実行してくれる。いちいちソースファイルを準備する必要はない。
今回のオフセット配列の検証では、以下のようなコマンドを打ち込めばいい。VSCode でコーディングしていれば、おそらくターミナルが常に開いているはずなので、手間はかからないだろう。
(なお、結果を表示しないといけないので、writeln
をくっつけている点だけ注意。また、最大分割レベル maxLevel
は 7
と仮定している。)
rdmd --eval="(0 ~ 7.iota.cumulativeFold!((a, b) => a + 4 ^^ b)(0).array).writeln;"
で、実行すると、このように…
[0, 1, 5, 21, 85, 341, 1365, 5461]
…結果がものの数秒で表示されて「あ~よしよし、想定通りだな」とすぐにわかるわけだ。大変便利である。
rdmd
で生成されるコードには、よく使いそうな module
が一通り import
されているので、ライブラリの参照をほとんど意識せず書けるというのもありがたい。
ちょっとした確認には rdmd --eval="..."
。勉強になった。
今後の作業
さて、グラフィックは出せる、サウンドも出せる、ユーザ入力も受け付ける、当たり判定もある…
ゲームとしての下地はおよそすべて完成しているわけだ。こうなるともはやできないことは何もないのよね。
そして、ここからが失踪者多発、最大の茨の道の入り口なのだ。
ここから先待ち受けるのは、大量のゲームオブジェクトの実装、大量のイベントの調整、大量の画像やサウンド等のリソースの準備…
とにかく 大量で地道な作業の連続 なのだ。
「グラフィック出せたやで!」とか「オブジェクト同士がぶつかったやで!」みたいな、飛躍的で瞭然な進歩はもはや存在しない 。
次の大きな喜びは、最後ゲームを完成させたその瞬間にしか訪れない のだ。
そこに至るまでにいかにモチベーションを維持するかというのは最大にして最も困難な問題である。
えーさん ますめ君の運命やいかに…!?