国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

使用Python和Asyncio編寫在線多人游戲(三)

開發(fā) 前端
在這個系列中,我們基于多人游戲 貪吃蛇 來制作一個異步的 Python 程序。上一篇文章聚焦于編寫游戲循環(huán)上,而本系列第 1 部分則涵蓋了如何異步化。

[[172015]]

在這個系列中,我們基于多人游戲 貪吃蛇 來制作一個異步的 Python 程序。上一篇文章聚焦于編寫游戲循環(huán)上,而本系列第 1 部分則涵蓋了如何異步化


4、制作一個完整的游戲 


4.1 工程概覽

在此部分,我們將回顧一個完整在線游戲的設計。這是一個經(jīng)典的貪吃蛇游戲,增加了多玩家支持。你可以自己在 (http://snakepit-game.com) 親自試玩。源碼在 GitHub 的這個倉庫。游戲包括下列文件:

  • server.py - 處理主游戲循環(huán)和連接。
  • game.py - 主要的 Game 類。實現(xiàn)游戲的邏輯和游戲的大部分通信協(xié)議。
  • player.py - Player 類,包括每一個獨立玩家的數(shù)據(jù)和蛇的展現(xiàn)。這個類負責獲取玩家的輸入并相應地移動蛇。
  • datatypes.py - 基本數(shù)據(jù)結構。
  • settings.py - 游戲設置,在注釋中有相關的說明。
  • index.html - 客戶端所有的 html 和 javascript代碼都放在一個文件中。

4.2 游戲循環(huán)內(nèi)窺

多人的貪吃蛇游戲是個用于學習十分好的例子,因為它簡單。所有的蛇在每個幀中移動到一個位置,而且?guī)苑浅5偷念l率進行變化,這樣就可以讓你就觀察到游戲引擎到底是如何工作的。因為速度慢,對于玩家的按鍵不會立馬響應。按鍵先是記錄下來,然后在一個游戲循環(huán)迭代的最后計算下一幀時使用。

現(xiàn)代的動作游戲幀頻率更高,而且通常服務端和客戶端的幀頻率是不相等的。客戶端的幀頻率通常依賴于客戶端的硬件性能,而服務端的幀頻率則是固定的。一個客戶端可能根據(jù)一個游戲“嘀嗒”的數(shù)據(jù)渲染多個幀。這樣就可以創(chuàng)建平滑的動畫,這個受限于客戶端的性能。在這個例子中,服務端不僅傳輸物體的當前位置,也要傳輸它們的移動方向、速度和加速度。客戶端的幀頻率稱之為 FPS(每秒幀數(shù)(frames per second)),服務端的幀頻率稱之為 TPS(每秒滴答數(shù)(ticks per second))。在這個貪吃蛇游戲的例子中,二者的值是相等的,在客戶端顯示的一幀是在服務端的一個“嘀嗒”內(nèi)計算出來的。

我們使用類似文本模式的游戲區(qū)域,事實上是 html 表格中的一個字符寬的小格。游戲中的所有對象都是通過表格中的不同顏色字符來表示。大部分時候,客戶端將按鍵的碼發(fā)送至服務端,然后每個“滴答”更新游戲區(qū)域。服務端一次更新包括需要更新字符的坐標和顏色。所以我們將所有游戲邏輯放置在服務端,只將需要渲染的數(shù)據(jù)發(fā)送給客戶端。此外,我們通過替換通過網(wǎng)絡發(fā)送的數(shù)據(jù)來減少游戲被破解的概率。

4.3 它是如何運行的?

這個游戲中的服務端出于簡化的目的,它和例子 3.2 類似。但是我們用一個所有服務端都可訪問的 Game 對象來代替之前保存了所有已連接 websocket 的全局列表。一個 Game 實例包括一個表示連接到此游戲的玩家的 Player 對象的列表(在 self._players 屬性里面),以及他們的個人數(shù)據(jù)和 websocket 對象。將所有游戲相關的數(shù)據(jù)存儲在一個 Game 對象中,會方便我們增加多個游戲房間這個功能——如果我們要增加這個功能的話。這樣,我們維護多個 Game 對象,每個游戲開始時創(chuàng)建一個。

客戶端和服務端的所有交互都是通過編碼成 json 的消息來完成。來自客戶端的消息僅包含玩家所按下鍵碼對應的編號。其它來自客戶端消息使用如下格式:

  1. [command, arg1, arg2, ... argN ] 

來自服務端的消息以列表的形式發(fā)送,因為通常一次要發(fā)送多個消息 (大多數(shù)情況下是渲染的數(shù)據(jù)):

  1. [[command, arg1, arg2, ... argN ], ... ] 

在每次游戲循環(huán)迭代的最后會計算下一幀,并且將數(shù)據(jù)發(fā)送給所有的客戶端。當然,每次不是發(fā)送完整的幀,而是發(fā)送兩幀之間的變化列表。

注意玩家連接上服務端后不是立馬加入游戲。連接開始時是觀望者(spectator)模式,玩家可以觀察其它玩家如何玩游戲。如果游戲已經(jīng)開始或者上一個游戲會話已經(jīng)在屏幕上顯示 “game over” (游戲結束),用戶此時可以按下 “Join”(參與),來加入一個已經(jīng)存在的游戲,或者如果游戲沒有運行(沒有其它玩家)則創(chuàng)建一個新的游戲。后一種情況下,游戲區(qū)域在開始前會被先清空。

游戲區(qū)域存儲在 Game._field 這個屬性中,它是由嵌套列表組成的二維數(shù)組,用于內(nèi)部存儲游戲區(qū)域的狀態(tài)。數(shù)組中的每一個元素表示區(qū)域中的一個小格,最終小格會被渲染成 html 表格的格子。它有一個 Char 的類型,是一個 namedtuple ,包括一個字符和顏色。在所有連接的客戶端之間保證游戲區(qū)域的同步很重要,所以所有游戲區(qū)域的更新都必須依據(jù)發(fā)送到客戶端的相應的信息。這是通過 Game.apply_render() 來實現(xiàn)的。它接受一個 Draw 對象的列表,其用于內(nèi)部更新游戲區(qū)域和發(fā)送渲染消息給客戶端。

我們使用 namedtuple 不僅因為它表示簡單數(shù)據(jù)結構很方便,也因為用它生成 json 格式的消息時相對于 dict 更省空間。如果你在一個真實的游戲循環(huán)中需要發(fā)送復雜的數(shù)據(jù)結構,建議先將它們序列化成一個簡單的、更短的格式,甚至打包成二進制格式(例如 bson,而不是 json),以減少網(wǎng)絡傳輸。

Player 對象包括用 deque 對象表示的蛇。這種數(shù)據(jù)類型和 list 相似,但是在兩端增加和刪除元素時效率更高,用它來表示蛇很理想。它的主要方法是 Player.render_move(),它返回移動玩家的蛇至下一個位置的渲染數(shù)據(jù)。一般來說它在新的位置渲染蛇的頭部,移除上一幀中表示蛇的尾巴的元素。如果蛇吃了一個數(shù)字變長了,在相應的多個幀中尾巴是不需要移動的。蛇的渲染數(shù)據(jù)在主類的 Game.next_frame() 中使用,該方法中實現(xiàn)所有的游戲邏輯。這個方法渲染所有蛇的移動,檢查每一個蛇前面的障礙物,而且生成數(shù)字和“石頭”。每一個“嘀嗒”,game_loop() 都會直接調(diào)用它來生成下一幀。

如果蛇頭前面有障礙物,在 Game.next_frame() 中會調(diào)用 Game.game_over()。它后通知所有的客戶端那個蛇死掉了 (會調(diào)用 player.render_game_over() 方法將其變成石頭),然后更新表中的分數(shù)排行榜。Player 對象的 alive 標記被置為 False,當渲染下一幀時,這個玩家會被跳過,除非他重新加入游戲。當沒有蛇存活時,游戲區(qū)域會顯示 “game over” (游戲結束)。而且,主游戲循環(huán)會停止,設置 game.running 標記為 False。當某個玩家下次按下 “Join” (加入)時,游戲區(qū)域會被清空。

在渲染游戲的每個下一幀時也會產(chǎn)生數(shù)字和石頭,它們是由隨機值決定的。產(chǎn)生數(shù)字或者石頭的概率可以在 settings.py 中修改成其它值。注意數(shù)字的產(chǎn)生是針對游戲區(qū)域每一個活的蛇的,所以蛇越多,產(chǎn)生的數(shù)字就越多,這樣它們都有足夠的食物來吃掉。

4.4 網(wǎng)絡協(xié)議

從客戶端發(fā)送消息的列表:

命令 參數(shù) 描述
new_player [name] 設置玩家的昵稱
join   玩家加入游戲

從服務端發(fā)送消息的列表:

命令 參數(shù) 描述
handshake [id] 給一個玩家指定 ID
world [[(char, color), ...], ...] 初始化游戲區(qū)域(世界地圖)
reset_world   清除實際地圖,替換所有字符為空格
render [x, y, char, color] 在某個位置顯示字符
p_joined [id, name, color, score] 新玩家加入游戲
p_gameover [id] 某個玩家游戲結束
p_score [id, score] 給某個玩家計分
top_scores [[name, score, color], ...] 更新排行榜

典型的消息交換順序:

客戶端 -> 服務端 服務端 -> 客戶端 服務端 -> 所有客戶端 備注
new_player     名字傳遞給服務端
  handshake   指定 ID
  world    初始化傳遞的世界地圖
  top_scores   收到傳遞的排行榜
join      玩家按下“Join”,游戲循環(huán)開始
    reset_world 命令客戶端清除游戲區(qū)域
    render, render, ... 第一個游戲“滴答”,渲染第一幀
 (key code)      玩家按下一個鍵
    render, render, ... 渲染第二幀
    p_score 蛇吃掉了一個數(shù)字
    render, render, ... 渲染第三幀
      ... 重復若干幀 ...
    p_gameover 試著吃掉障礙物時蛇死掉了
    top_scores 更新排行榜(如果需要更新的話)

5. 總結

說實話,我十分享受 Python 最新的異步特性。新的語法做了改善,所以異步代碼很容易閱讀。可以明顯看出哪些調(diào)用是非阻塞的,什么時候發(fā)生 greenthread 的切換。所以現(xiàn)在我可以宣稱 Python 是異步編程的好工具。

SnakePit 在 7WebPages 團隊中非常受歡迎。如果你在公司想休息一下,不要忘記給我們在 Twitter 或者 Facebook 留下反饋。

責任編輯:龐桂玉 來源: Linux中國
相關推薦

2016-09-19 21:24:08

PythonAsyncio游戲

2016-09-14 21:17:47

PythonAsyncio游戲

2010-03-05 18:42:31

杜比語音聊天

2020-02-21 08:00:00

Pythonasyncio編程語言

2018-06-27 14:50:06

Cloud StudiSpring Boot應用

2011-12-16 10:08:36

Node.js

2021-09-15 14:53:35

在線文檔多人協(xié)作

2014-11-20 13:56:08

2024-01-18 08:37:33

socketasyncio線程

2015-07-31 10:10:12

javaweb在線聊天

2021-04-13 06:35:13

Elixir語言編程語言軟件開發(fā)

2020-01-16 11:42:45

PyramidCornicePython Web

2018-10-08 15:35:56

Python異步IO

2020-09-21 08:58:57

PythonOpenCV乒乓球

2014-10-30 10:28:55

Node.js

2012-03-20 21:13:27

Android

2023-08-30 08:43:42

asyncioaiohttp

2011-11-30 16:37:58

sync

2014-03-31 10:51:40

pythonasyncio

2017-08-02 15:00:12

PythonAsyncio異步編程
點贊
收藏

51CTO技術棧公眾號

国产一区二区三区四区| 91精品国产综合久久久久久| 亚洲国产日日夜夜| 成人激情视频免费在线| 日本不卡1234视频| 精品久久久久久久久国产字幕| 97久草视频| 亚洲精品中文字幕99999| 精品视频久久久久久久| 黄色录像1级片| 成人午夜激情在线| 天天久久人人| 欧美在线网站| 成人在线小视频| 欧美高清在线| 97在线免费观看视频| 先锋欧美三级| 亚洲天堂免费在线| 肉体视频在线| 日韩欧美国产综合一区| 黄色网在线播放| 欧美一二三四在线| 男人和女人做事情在线视频网站免费观看| 中文字幕国产精品一区二区| 日韩网站在线免费观看| 国产精品综合网| 免费在线看黄色片| 国产又粗又猛又爽又黄91精品| 手机成人在线| 国产aⅴ综合色| 欧美精品人人做人人爱视频| 一区二区激情| 亚洲av综合色区| 国产剧情一区二区| 国产精品丝袜久久久久久消防器材 | 国产永久免费高清在线观看视频| 国产精品拍天天在线| 神马伦理电影| 欧美一区永久视频免费观看| 日本天堂在线观看| 亚洲最新中文字幕| 久久天堂久久| 超碰97在线人人| 视频一区欧美精品| 免费激情视频在线观看| 狠狠色狠色综合曰曰| 久久大胆人体| 青青草精品毛片| 国产专区综合网| 国产三级av在线| 日韩精品高清在线| 国产欧美一区二区精品久久久| 欧美日韩综合久久| 久久精品无码一区二区三区| 免费在线一级视频| 亚洲精品一区久久久久久| 蜜桃tv一区二区三区| 高清无码视频直接看| 亚洲成人福利片| 成人久久网站| 免费h精品视频在线播放| 亚洲欧美另类综合偷拍| 欧美性理论片在线观看片免费 | 国产精品99在线观看| 亚洲 欧美 综合 另类 中字| 午夜精品福利一区二区蜜股av| 女生影院久久| 免费av在线一区二区| 一区二区在线电影| 久久五月天小说| 国产日韩欧美在线播放| 色天下一区二区三区| 在线亚洲国产精品网| √8天堂资源地址中文在线| 色美美综合视频| 男女私大尺度视频| 久久九九全国免费| 精品一区二区三区影院在线午夜 | 国产欧美韩日| 国产欧美日韩视频在线| 91麻豆精品国产91久久久久久久久| 九色视频成人自拍| 精品少妇一区二区三区日产乱码 | 成人高清免费观看mv| 国产精品99久久久久久似苏梦涵 | 俄罗斯xxxx性全过程| 久久中文在线| 18岁网站在线观看| 一区二区成人精品| 91麻豆精东视频| 曰本一区二区三区视频| 国产在线视频资源| 日本特级黄色大片| 国产精品久久久久久久9999| 欧美色手机在线观看| 国产福利一区二区三区在线视频| 超碰精品在线观看| 僵尸再翻生在线观看| 制服影音先锋| 99在线观看视频| 欧美日韩国产色视频| 色喇叭免费久久综合网| 精东影业在线观看| 欧美理论一区二区| 欧美激情精品久久久久久蜜臀| 国产精品美女久久久久av爽李琼| 国产在线播放精品| 四虎在线视频| 久久久久一区二区| 色婷婷香蕉在线一区二区| 日韩电影在线视频| 日韩在线不卡| 人人视频精品| 91精品国产综合久久久久久蜜臀| 99久久影视| 欧美日韩在线观看一区| 日本色综合中文字幕| 992tv在线观看免费进| 亚洲美女在线一区| 精产国产伦理一二三区| 欧美日韩视频专区在线播放| 日韩欧美四区| 欧美6一10sex性hd| 污视频在线看操| 99视频在线视频| av动漫在线看| 成人在线观看a| 99亚洲精品视频| 亚洲精品一区二| 欧美日韩系列| 中日韩在线视频| 亚洲一区 在线播放| 亚洲一区二区三区精品视频 | 视频一区亚洲| 国产精品久久久91| 久久这里只有精品99| 一区二区欧美在线观看| 国产乱色国产精品免费视频| 国产一区高清在线| 你懂的国产精品永久在线| 97超碰成人| 日韩成人影音| 黄色片网站在线| 免费在线黄网站| 国产精品初高中精品久久| 日韩成人小视频| 欧美刺激性大交免费视频| 亚洲综合在线中文字幕| 一区二区视频在线| 99中文字幕一区| 欧美久久久久久久久久久久久| 国产高清精品一区二区三区| 全球成人中文在线| 欧美极品少妇xxxxx| 久久精品亚洲国产| 中文字幕欧美精品在线| 在线播放日韩欧美| 日韩有码在线播放| 色综合久久悠悠| 日本精品久久久| 成人在线小视频| 日本亚洲导航| 欧美 丝袜 自拍 制服 另类| 97成人在线观看视频| 97av视频在线观看| 天天天干夜夜夜操| 国内精品卡一卡二卡三新区| 欧美精品少妇| av资源在线| www.久久| 人人精品视频| 免费不卡在线视频| 国产欧美日韩视频一区二区| 亚洲成人免费视| 中文字幕9999| 国产精品美女网站| 日本人妻伦在线中文字幕| 高清hd写真福利在线播放| 1区2区在线观看| 欧美午夜寂寞| 免费视频最近日韩| 精品久久久中文| 精品久久久久人成| 日韩午夜激情电影| 国产成人精品av| 亚洲v日韩v欧美v综合| 国产一级粉嫩xxxx| 自由日本语热亚洲人| 国产一区二区观看| 成人综合激情网| 欧美高清hd18日本| 午夜在线免费视频| 欧美国产欧美综合| 欧美在线观看18| 欧美在线视频观看| 日韩高清av| 男女无套免费视频网站动漫| 欧洲亚洲视频| 亚洲一区二区三区免费在线观看| 欧美日韩看看2015永久免费|