マルチプレイヤータイルベースの動きの同期


8

私はインターネット上で複数のプレイヤーの動きを同期させなければなりません、そしてそれを行うための最も安全な方法を見つけようとしています。

ゲームはタイルベースで、4方向にしか移動できません。移動するたびにスプライトが32ピクセル移動します(もちろん時間とともに)。さて、この移動アクションをサーバーに送信し、すべてのプレーヤーにブロードキャストする場合、ウォークキーを押し続けている間、ウォーキングを続けるには、次のコマンドを実行してサーバーに送信する必要があります。そして、すべてのクライアントにとって、時間内に、または動きはもはやスムーズではなくなります。私はこれを他のゲームで見ました、そしてそれはラグがなくてもかなり醜くなります。だから私はこれが実行可能なオプションでさえあるのだろうかと思っています。これはシングルプレイヤーにとって非常に優れた方法のようですが、簡単で簡単です(次の移動アクションを時間内に実行してリストに追加するだけです)。マウスの移動を簡単に追加できます(タイルをクリックする)。キューへのパスを追加するために、それは歩きました。

私の頭に浮かんだもう1つのことは、誰かがどこかの方向に動き始めたという情報を送り、もう一度彼が停止または方向を変えたときに、位置とともにスプライトが正しい位置に表示されるようにするか、位置が間違っている場合は、位置を修正できます。これは(うまくいけば)誰かが本当に遅れている場合にのみ問題を引き起こすはずです。その場合、それは予期されることです。これがうまくいくためには、何らかの方向のキューが必要です。ここで、着信方向の変更やものが保存され、スプライトが次のタイルへの現在の移動が完了した後、どこに行くべきかがわかります。これは実際には機能するかもしれませんが、ちょっと複雑すぎるようです。これを行う唯一の方法かもしれませんが、吃音のリスクはありません。停止または方向変更がクライアント側で受信された場合 sはキューに保存され、charは停止または方向を変更する前に、指定された座標に移動し続けます。もちろん、新しいコマンドが遅すぎると、どもりも発生します...

私は方法を決めるのに苦労しており、まだこれに関する例を見つけることができませんでした。私の主な問題はタイルの動きをスムーズに保つことです。そのため、ピクセルベースの動きの同期に関する他のトピックがあまり役に立たないのはこのためです。

これを行う「標準的な」方法は何ですか?

回答:


4

リアルタイムでの移動について話していると思います。位置を補間しようとすることは、おそらく失われた原因です。遅い接続では、ゲームの状態が実際のゲームの状態よりもさらに遅れることがあります。他のコメントとは異なり、サーバー側に多くのゲームロジックを配置しないことをお勧めします。この種のソリューションを実装したとき、クライアントはサーバーへのTCPソケットを常に持っています。ゲームの状態が変化すると、「クライアントはx = 10、y = 20にいる」などのメッセージをサーバーに送信します。サーバーは他のクライアントにメッセージをプッシュし、クライアントは独自の内部ロジックに基づいてメッセージを処理しようとします。TCPを使用すると、メッセージが順番に到着するようになります。

残念ながら、AAAゲームでさえ極端なラグを処理することはできません。プレイヤーは時々非常に速く移動します、なぜなら彼らのローカルとネットワークの状態は打ちのめされていないからです。往復のpingを監視し、遠すぎたり遅すぎたりするユーザーを蹴るのがこれに役立ちます。


1
+1は「AAAゲームでも極端な遅延を処理できない」です。実際、小さなラグでも完璧に処理できる人はいません。私たちはそれをできるように見せることができます。
Valmond

3

基本的に、これはシンプルで安全な方法でそれを行う方法です(警告、極端な疑似コード):

A)クライアント(playerid = 5)は、サーバーに「右」(またはそれ以上、73,18に移動)するように要求します。

B)サーバーはプレーヤー(またはプレーヤーIDなど)を含む大きな2Dマップをチェックします。

 if(map[73][18] == occupied)
     Send back ('Not OK') to client (the case is blocked by another player)
else
    Set the new position as blocked: map[73][18]=5
    Release the old position: map[72][18]=0;
    Send a 'new position: 5, 73,18' message to all players who are nearby (moving client included)

C)クライアントが「新しい位置」メッセージを受け取る(まあ、またはプレイヤー5が「Not Ok」メッセージを受け取る)

D)クライアントは、playerid = 5のアイテムを新しい位置に向かってゆっくりと移動します(または、playerid = 5のアイテムが1つもない場合は作成します)


まあ、ありがとう、でも私の問題は、タイルの一般的な動きではなく、複数の継続的なタイルの動きを通じて他のクライアントでスムーズに保つことです^^
Mars

速度を正しく設定し、たとえば推測航法または単に「愚かな」「一定速度で目標に向かって移動する」(または位置に沿ってタイムスタンプを送信する場合は特定のしきい値を超える比例速度)を使用して、遅れを補正します。問題はありません。
Valmond

1

あなたが説明した方法はかなり良いと思います、特に4つの動きしか許されていない単純なゲームでは。これが私がどのように実装したかです。

基準はわかりませんが、最初に頭に浮かんだのは、プレーヤーから他のプレーヤーへの「入力の変更」、つまりプレーヤーの入力の変更のみをブロードキャストすることでした。たとえば、[押されたキー、キーID、時間]、または[キーが離された、キーID、時間]の行に沿ったメッセージのみをブロードキャストし、これらの入力の変化に応じてプレーヤーのゲームを動作させることができます。時間を含めると、パスの修正に役立ちます(プレーヤーが時間tで方向を変えた場合、時間t + 1で「進む」を修正する必要があります)。

ただし、このソリューションでは、メッセージが失われるという問題が発生する可能性があります。「キーが解放されました」メッセージが送信されなかったとしたら?これを助けることができる何かは定期的にプレーヤーのゲーム状態をポーリングし、プレーヤーの現在の位置、および押されているキーを返すこと、あるいはゲーム状態全体を返すことです。プレーヤーとコマンドの数に応じて、クライアント/サーバー間でやり取りされるメッセージのバランスをとるためにこれを微調整できます。

調査できるもう1つのことは、経路計画です。たとえば、プレーヤーが5秒間前進している場合、次のミリ秒の確率でプレーヤーは引き続き前進します。その場合、遅延を回避するために、経路予測の類似を作成できます。これは基本的に上記の方法で行われていることですが、循環パスを考慮に入れることもできます。

これがお役に立てば幸いです。


1
入力を送信するだけの場合の問題は、1つの入力を見逃したり、時には間違った順序でそれらを解釈したりすると、ゲーム状態がそれ以上問題ないことです。2つのクライアントは異なる「画面」を表示します。
Valmond

@Valmond非常に良い点...実際、私は自分の答えを削除したい気がします。
ジョナサンピトレ

1
入力をサーバーに送信できます(問題がなくなるまで)(IMO)サーバーは正確なデータを送信するか、少なくともデータを確認するか、ゲーム全体を送信する必要があります(これは、Blood Bowlなどの実際のゲームで行われています) )、多分あなたは:-)代わりにそれを削除するあなたの答えを微調整することができます
Valmond
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.