clusterのリアルタイム通信サーバーの漸進的な進化のような仕組みを理解したいなと思い、手習い用にMQTT+Protocol Buffersを使ってリアルタイムに2次元位置を同期するサーバーを書いてみている。今回はリアルタイムに2次元位置を同期するサーバーでプレイヤーから弾を発射できるようにの続きで、プレイヤーが爆弾を配置できるようにした。
できたもの
client側でBボタンを押すとその場に爆弾を配置できる。爆弾はしばらくすると爆破し、火に当たるとプレイヤーはやられる。
実装コードはこの辺り
- https://github.com/shibayu36/terminal-shooter/pull/17
- https://github.com/shibayu36/terminal-shooter/pull/18
処理の流れ
このような形になった。
- 爆弾と爆弾の火はアイテムのタイプとして分離する
- Game structにすべて任せるとどんどん肥大化してしまうため、それぞれの状態管理はそのアイテムごとに任せるようにした。衝突した時に何をするかなどもアイテムに任せる
- アイテム生成や自身の削除を行いやすくするため、Gameに対して一部のオペレーションを依頼することを可能にする
アイテム自身にTickの更新が起きた時や衝突が起きた時のロジックを任せる
アイテム自身にTickの更新が起きた時や衝突が起きた時のロジックを任せるという部分だけ工夫したので書いておく。
Game structがどんどん肥大化しそうな気配があったので、アイテム自身にロジックを任せることにした。Tickの更新が起きるたびにアイテムのUpdateが呼ばれ、他のアイテムとの衝突が起きるたびにOnCollideWithが呼ばれるようにする。
- Game側で全アイテムのupdateをTickごとに呼ぶ
- Game側で衝突が起きたらOnCollideWithを呼ぶ
- 銃の弾の場合
- Updateのたびにtickを増やす。一定以上のtickが経ったら自身を動かす
- 衝突が起きてそれがPlayerとの衝突であれば、自分自身を消滅させる
- OnCollideWithに渡るproviderがGameに対して依頼を投げるインターフェースになっているので、それを利用する
- Player側がどうなるかはこちらに書いている
- 爆弾の場合
- Updateのたびにtickを増やす。一定以上になったらBombFireをいい感じにマス目に配置する
- 当たった時は何もしなくて良いので実装なし
まとめ
今回はリアルタイムに2次元位置を同期するサーバーで爆弾を置けるようにした。爆弾を置こうとすると、ロジックをどこに置いたら分かりやすくなるかを考える必要が出てきて勉強になった。