clusterのリアルタイム通信サーバーの漸進的な進化のような仕組みを理解したいなと思い、手習い用にMQTT+Protocol Buffersを使ってリアルタイムに2次元位置を同期するサーバーを書いてみている。今回はリアルタイムに2次元位置を同期するサーバーにアイテム情報を追加したの続きで、プレイヤーから弾を発射できるようにしてみた。
できたもの
client側でスペースキーを押すと弾を発射できるようにした。弾はプレイヤーの目の前から発射し、プレイヤーの進行方向に進む。
実装コードはこの辺り。
- https://github.com/shibayu36/terminal-shooter/pull/9
- https://github.com/shibayu36/terminal-shooter/blob/9e40fd2d3e31cdccaf276ff30296f8ff28d54042/README.md
実装
clientからは「弾を撃つというアクションをしたい」ということだけを送ってもらうようにし、server側で初期位置や方向の計算をする作戦とした。
client -> serverにはplayer_actionトピックのPayloadとしてPlayerActionRequestというprotoの構造で送ってあげる。実際のclientの変更はこれだけ。
serverのパケットを受け取った側は、PlayerActionRequestのTypeを見て、gameのShootBulletメソッドへ処理を委譲する。実装はこの辺り。
ShootBulletメソッドではプレイヤー前方を計算し、そこに弾を配置するだけ。
弾さえ生成してgameオブジェクトの状態に保持できれば、あとは前回作ったclientへの状態配信の仕組みにしたがって、自動的に弾の移動が全clientに同期される。
これだけでプレイヤーからの弾の発射を実現できた。
まとめ
今回はプレイヤーからの弾の発射を実装してみた。
前回はgameオブジェクトの更新ロジックと、その更新通知を受け取ったらclientに配信するロジックを、別goroutineとして分離しておいた。そのおかげでgameオブジェクトの状態変更だけを実装するだけで実装が終わった。設計大事。