2009-06-30 9 views
8

私は2Dフラッシュマルチプレイヤーゲームとソケットサーバーを書いています。クライアント - サーバマルチプレイヤー(MMO)ゲームの動き "アルゴリズム"?

  • クライアントは、プレーヤの移動モード(前進または後退)とプレーヤの旋回モード(旋回しない、左に旋回する)についてサーバに通知します。クライアントとサーバ間の移動アルゴリズムのオリジナル計画は次のとおりです。または右に曲がる)。
    • サーバーは、数ミリ秒ごとにすべてのプレーヤーをループし、時間の差に基づいて回転した角度と移動した角度を計算します。同じ計算がクライアントによって行われます。

クライアントのために私の現在の計算(同じ数学がサーバーで使用されている)==>

回す

var newTimeStamp:uint = UtilLib.getTimeStamp(); //set current timeStamp 
       var rot:uint = Math.round((newTimeStamp - turningTimeStamp)/1000 * 90); //speed = x degrees turning every 1 second 
       turningTimeStamp = newTimeStamp; //update timeStamp 
       if (turningMode == 1) //left 
       { 
        movementAngle = fixAngle(movementAngle - rot); 
       } 
       else if (turningMode == 2) //right 
       { 
        movementAngle = fixAngle(movementAngle + rot); 
       } 

private function fixAngle(angle:int):uint //fixes an angle in degrees (365 -> 5, -5 -> 355, etc.) 
     { 
      if (angle > 360) 
      { 
       angle -= (Math.round(angle/360) * 360); 
      } 
      else if (angle < 0) 
      { 
       angle += (Math.round(Math.abs(angle)/360) + 1) * 360; 
      } 
      return angle; 
     } 

運動

var newTimeStamp:uint = UtilLib.getTimeStamp(); //set current timeStamp 
       var distance:uint = Math.round((newTimeStamp - movementTimeStamp)/1000 * 300); //speed = x pixels forward every 1 second 
       movementTimeStamp = newTimeStamp; //update old timeStamp 
       var diagonalChange:Array = getDiagonalChange(movementAngle, distance); //with the current angle, howmuch is dX and dY? 
       x += diagonalChange[0]; 
       y += diagonalChange[1]; 

private function getDiagonalChange(angle:uint, distance:uint):Array 
     { 
      var rAngle:Number = angle * Math.PI/180; 
      return [Math.round(Math.sin(rAngle) * distance), Math.round((Math.cos(rAngle) * distance) * -1)]; 
     } 

これはうまくいくようです。遅れを考慮するために、サーバーはクライアントの情報を毎回修正してから、このデータを送信します。

このシステムでは、動きを処理するために非常に小さな帯域幅が使用されます。しかし、私のサーバーとクライアントの座標と角度の違いは大きすぎます。私はたぶん私の「アルゴリズム」を拡張して、ユーザが持っているレイテンシを考慮に入れるべきでしょうか?または、クライアントの動きをよりうまく処理する方法がありますか?<>優れたパフォーマンスを発揮するサーバーマルチプレイヤーゲームはありますか?

答えて

6

私の初期設計はあなたのものと似ていますが、それが機能しない場合は、おそらくクライアントがすべての動きをしてサーバーに範囲検査をさせることができます。

最後に報告された位置がXであった場合、次の位置はXからの半径以内でなければなりません。半径はx、yデータでクライアントから送信されたタイムスタンプの差に基づいています。

これは主に不正行為を検出するために必要なことです。

攻撃を伴ってポジションを送信する必要があり、ポジションによってトリガーされるアクションは、クライアントがそのポジションで更新を送信した後にのみトリガーされますが、サーバーベースになります。

これはあまりにも役立ちますが、最初のアルゴリズムからわかるはずの再同期を停止する可能性があります。

コメント応答:

いいえ、クライアントはまだ彼らの位置をサーバに通知しますが、サーバーは、次の位置を計算しようとしないでしょう。これは、サーバー(および他のすべてのクライアント)が、少なくとも1回の送信/受信サイクルがその位置にあることを意味します。

私はクライアントにすべての作業をさせ、キャラクターの位置を把握してサーバーに伝えてもらいたいと思っていますが、サーバーがオプションで有効性をチェックして誰も不正行為をしないようにすることができます。

チート検出は、パフォーマンスのためにオフにすることも、ランダムにチェックすることもできます。

注:移動範囲内のオブジェクトのすべての衝突/位置情報は、これが機能するにはクライアントに送信する必要があります。

+0

すべてのクライアントが他のすべてのクライアントに現在の場所について通知する必要がある場合、サーバーは大量のメッセージを受信して​​再送信する必要はありませんか? – Tom

+0

+1私は実際に同じことを提案しようとしていました。これは、人気のあるマルチプレーヤーのビデオゲームの多くが何をしているのかです。サーバーは誰もが定期的に同期していることを確認します。 (私はQuakeのゲームがこれをすると信じています) –

+0

まあ、私の最初の質問はまだ適用されます。すべてのステップでサーバーを最新の状態に保つために、クライアントは常に何千ものメッセージを送信する必要はありませんか?その後、このデータを近くのすべてのプレーヤーに送信するサーバーが続きます。 – Tom

0

サーバーが非常に遅いので、すべての動作を処理できませんか?特に2次元ゲームでは?通常、私はほとんど2dゲームを作っても、サーバは私にすべての動きを返すので、クライアントでの計算は必要ありません。サーバーが遅れ始めると、私はちょっと凍結します。これは、とにかく(通常これが起こることはほとんどありませんが)一般的に予想されるものです。

いずれの場合でも、クライアントが実際の計算自体を行わないとパフォーマンスがどのようになるかは間違いありません。パフォーマンスが十分でない場合は、サーバー上のプレーヤーの動きによるループが遅延を引き起こしているかどうかを確認してください(クライアントごとに別のスレッドを使用し始める)。

実際に帯域幅に実際の制限がある場合(動き自体がほとんどデータを渡さない場合)、その特定のユーザーの平均遅延を見つけて、アルゴリズムに計算する必要があります。ただし、平均値(精度)を継続的に把握し続けるには、往復時間を見つけるためにサーバーにpingを実行する必要があります。

+0

これはちょっとした2Dゲームではありません。何百人ものプレーヤーを同時に扱うことになっています。可能な限り最適化されたシステムが必要です。 – Tom

+0

ええと、その場合は十分に小さい間隔でデータを送信するようにサーバーを調整する必要があります。もちろん、すべてのサーバーには何らかの種類のプレーヤー上限が必要ですが、少なくともクライアントの移動側に10〜20msの遅延を追加します。ほとんど目立たず、ほとんどの場合、プレーヤーの実際のポジションに対応する必要があります。 – AlbertoPL

1

私はこれを行うことが考えられる2つの方法があります - クライアントがサーバーにコマンドを発行して&サーバーが究極のマップキーパーになるようにしてください。

&マップをクライアントに保管しておくと、クライアントは移動を行うために近くにある他のクライアントとの接続を確立する必要があります。サーバーによって記録が行われます。&ハッカー警察)。

私にとって興味深いのは、ピア接続を監視する可能性であり、特定のしきい値を超える待ち時間を持つピアは、ゲームには表示されません。

+0

面白いですが、この種の制限は、P2Pが同時に多くの接続を処理できないため大きな争いです。他のクライアントのクライアント接続にも依存しています。私はまだ最高のサーバー<>クライアントシステムを探しています。 – Tom

+2

P2Pで多くの接続を処理できないのはなぜですか?誰かが何かをするたびに、サーバーからの再ブロードキャストか、ピアからのメッセージが必要です。私はトラフィックが同じ(私は間違っている可能性があります)に近いと思った。 – ryansstack

関連する問題