私は2Dフラッシュマルチプレイヤーゲームとソケットサーバーを書いています。クライアントとサーバー間の移動アルゴリズムに関する私の当初の計画は次のとおりでした。
- クライアントは、これらが変更されるたびに、プレーヤーの移動モード(前進または移動しない)とプレーヤーの回転モード(回転しない、左に曲がる、または右に曲がる)についてサーバーに通知します。
- サーバーは数ミリ秒ごとにすべてのプレーヤーをループし、時間の差に基づいて回転角度と移動距離を計算します。同じ計算がクライアントによって行われます。
クライアントの現在の計算(サーバーでも同じ計算が使用されます)==>
旋回
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)];
}
これはうまくいくようです。ラグを考慮に入れるために、サーバーはこのデータを送信することによってクライアントの情報を時々修正します。
このシステムでは、移動を処理するために使用される帯域幅はごくわずかです。ただし、サーバーとクライアントの座標および角度の違いが大きすぎます。ユーザーの待ち時間も考慮に入れるために、「アルゴリズム」を拡張する必要がありますか?または、優れたパフォーマンスを備えたクライアント<>サーバーマルチプレイヤーゲームの動きを処理するためのより良い方法はありますか?