2009-05-01 141 views
15

對於單機遊戲,基本的遊戲循環是(來源:維基百科)算法客戶端 - 服務器遊戲

while(user doesn't exit) 
    check for user input 
    run AI 
    move enemies 
    resolve collisions 
    draw graphics 
    play sounds 
end while 

但如果我開發客戶端 - 服務器般的遊戲,像地震,此Ragnarock,賽道狂飆,

什麼是客戶端和服務器部分遊戲的循環/算法?

回答

19

它會像

客戶:

while(user does not exit) 
    check for user input 
    send commands to the server 
    receive updates about the game from the server 
    draw graphics 
    play sounds 
end 

服務器:

while(true) 
    check for client commands 
    run AI 
    move all entities 
    resolve collisions 
    send updates about the game to the clients 
end 
+0

忍者 - 心靈! +1 – GWLlosa 2009-05-01 15:52:17

3

客戶端部分基本相同,除了與取代

run AI 
move enemies 
resolve collisions 
upload client data to server 
download server updates 

而服務器只是做:

while (game is running) 
{ 
    get all clients data 
    run AI 
    resolve collisions 
    udpate all clients 
} 
3

您可以使用幾乎同樣的事情,但你們中的大多數邏輯會在服務器上,你可以把定時器,聲音,grafics和客戶端應用上的其他UI組件。 任何業務規則(AI,Movements)都在服務器端。

4

這真的不是一個簡單的問題。在最基本的層面上,你可以說網絡提供了與原始循環的MoveEnemies部分相同的數據。所以,你可以簡單地取代你的循環:

while(user doesn't exit) 
    check for user input 
    run AI 
    send location to server 
    get locations from server 
    resolve collisions 
    draw graphics 
    play sounds 
end while 

不過,還需要考慮到延遲,所以你真的不希望與呼叫網絡暫停主循環。爲了克服這一點,是很平常看到的網絡引擎儘可能快,因爲它可以坐在第二個線程,輪詢服務器上的數據和配售對象的新位置爲共享內存空間:

while(connectedToNetwork) 
    Read player location 
    Post player location to server 
    Read enemy locations from server 
    Post enemy locations into shared memory 

然後主循環看起來像:

while(user doesn't exit) 
    check for user input 
    run AI 
    read/write shared memory 
    resolve collisions 
    draw graphics 
    play sounds 
end while 

這種方法的好處是,你的遊戲循環會以最快的速度,因爲它可以運行,但來自服務器的信息時,纔會更新當一個完整的帖子,並從服務器已完成。當然,你現在遇到了跨線程共享對象的問題,以及隨附的鎖等樂趣。

在服務器端循環大致相同,每個播放器有一個連接(通常每個播放器也在一個單獨的線程上,以便一個連接的延遲不會影響其他連接)當客戶機向服務器請求讀取所有從共享存儲器塊中的其他球員位置的敵人的位置,並將其回運行像

while (PlayerConnected) 
    Wait for player to post location 
    Place new location in shared memory 

循環。

這是一個非常簡化的概述,還有更多的調整可以提高性能(例如,服務器可以將敵方位置發送給客戶端而不是客戶端請求它們),並且您需要決定某些地方邏輯上作出決定(客戶是否決定他是否已經出手,因爲他有最先進的爲自己最新的情況,或者服務器停止作弊)

12

客戶:

connect to server 
while(user does not exit && connection live) 
    check for user input 
    send commands to the server 
    estimate outcome and update world data with 'best guess' 
    draw graphics 
    play sounds 
    receive updates about the game from the server 
    correct any errors in world data 
    draw graphics 
    play sounds 
end 

服務器:

while(true) 
    check for and handle new player connections 
    check for client commands 
    sanity check client commands 
    run AI 
    move all entities 
    resolve collisions 
    sanity check world data 
    send updates about the game to the clients 
    handle client disconnects 
end 

在客戶端的命令和世界的數據的完整性檢查是,以除去任何「不可能」的情況下引起的或者通過故意的作弊行爲(移動速度太快,穿牆等)或滯後(通過在客戶端認爲是打開的門去,但服務器知道關閉等)。

爲了處理客戶端和服務器之間的延遲,客戶端必須對接下來會發生什麼(使用當前的世界數據和客戶端命令)做出最佳猜測 - 客戶端必須處理所有客戶端和服務器之間的差異它預測會發生,服務器後來告訴它實際發生了什麼。通常情況下,這將足夠接近玩家不會注意到差異 - 但是如果滯後很大,或者客戶端和服務器不同步(例如由於作弊),那麼當客戶需要進行突然更正時它從服務器接收數據。

還有很多關於將這些過程的各個部分拆分爲單獨的線程以優化響應時間的問題。

一個啓動的最佳方法是從具有活動插件社區的遊戲之一抓住一個SDK - 鑽研如何工作將提供應如何做一個很好的概述。

1

一個非常有用的,我認爲相關文件讀的是這一個:Client-Server Architectures

我給它一讀,並從中學到了很多東西,有很大的意義作出。通過將您的遊戲分離爲戰略定義的組件或層,您可以創建更易維護的體系結構。該程序比代碼描述的傳統線性程序模型更易於編寫代碼,並且更加可靠。

這個思考過程在前面的文章中出現,這裏講述瞭如何使用「共享內存」在程序的不同部分之間進行對話,從而克服了使用單線程和步驟後續遊戲邏輯的侷限性。

你可以花幾個月的完美架構和程序流程的工作,讀一個單一的文件,並意識到你已經找錯了樹。

tldr;閱讀。