あさちゅんのゲームブログ

UnityやSiv3Dに関するゲーム開発メモを残していきます

Siv3D + Ruby で通信ゲームを作る #3 ゲームの同期

Siv3D + Ruby で通信ゲームを作ろうの第3回です。

前回で入力の同期は出来ましたが、ゲームの開始の同期やボールの再配置が出来ていません。

今回はその入力以外の同期を行っていきます。

ゲーム開始の同期

入力の同期はある程度ごまかせますが、そもそも開始したのがずれていたのでは話になりません。

そこで、「start」を受信した時ではなく、「start」の受信と共に開始時刻を受け取るようにし、その時刻に一斉に開始するようにします。

Main.cppはWaitingクラスを、main.rbはacceptメソッドを読んでから「start」を送信するまでを変更します。

手っ取り早く時刻を扱うのにUNIXタイム(UTC)を使用します。「start」を送信した時刻から3秒後を開始し時刻に設定することによって3秒以内の遅延なら、各クライアントで同時刻で開始できるようになりました。

ボールの再配置

入力のみを同期しているので、サーバはボールが画面外に出たかを知る術がありません。なので、クライアントに判定させるのですが、判定するのは1人だけでいいはずなので、今回は親に任せます。

画面外に出た時にサーバに「goal」という文字列を送信し、サーバはそれを各クライアントに送信し直します。入力の時と同様に画面外に出た瞬間ではなく、一度サーバを通すことを忘れないでください。

また、画面外に出てから実際に再配置するまでタイムラグがあるので、そのままだと「goal」という文字列が何回も送信されてしまいます。遅れてサーバが受信して、再配置されたのに送ってしまったら大変なので、isSendGoal変数を使って1回だけ送るようにしましょう。

サーバをループさせる

ゲームは完成しましたが、1回対戦する度にrubyコマンドを打ってサーバを起動しなければなりません。

1回対戦しただけで、サーバが落ちているのではサービスにならないので、全体をループで囲んで繰り返し対戦できるようにします。

今までは気にしてしませんでしたが、終了する時にソケットをクローズするのを忘れないでください。

相手がいなくなって対戦が終了したのに、通信が終わったことが通知されず、幽霊と対戦する羽目になります。

まとめ

通信対戦ゲームが作れたでしょうか?

オンライン要素となると、難しくて作るのが大変なイメージがありますが、仕組みさえ理解してしまえば簡単なので、これを機にオンライン要素や通信対戦に挑戦してみてください!

おまけ

コピペで動くSiv3DとRubyを置いておきます。

使用したソフト
Windows 10
Siv3D August 2016
Ruby 2.3.1