我一直在寫一個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)];
}
這似乎很好。爲了考慮滯後,服務器通過發送這些數據來糾正客戶端的信息。
這個系統使用很少的帶寬來處理移動。但是,我的服務器和客戶端的座標和角度之間的差異太大。我是否應該擴展我的「算法」,同時考慮到用戶的延遲?還是有更好的方式來處理客戶端運行效果很好的服務器多人遊戲?
如果所有客戶都必須通知所有其他客戶他們當前的位置,服務器是否不得不繼續接收並重新發送大量消息? – Tom 2009-06-30 22:28:22