亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

利用Python進行游戲腳本編程,不愧是最強的腳本語言!

系統(tǒng) 2038 0

使用腳本語言可以更加快速地開發(fā)游戲邏輯,而不必擔(dān)心由于 C++ 程序員的粗心大意所造成的后果。使用已有的腳本語言可以節(jié)省開發(fā)新型自定義語言的時間和開銷,并且這些語言通常要比自己創(chuàng)造的語言更加的強大。Python 對于游戲腳本語言來說是一種不錯的選擇,它很強大,容易嵌入使用,能夠無縫地使用 C/C++ 進行擴展,包含很多腳本語言所具有的高級特性,并且它可以用來實現(xiàn)自動化過程[TR1: automating production]。另外,關(guān)于 Python 的書籍、開發(fā)工具 和 庫 很豐富,使得我們很容易從其他開發(fā)者那里受益。下來就談一談我們在 Humongous 娛樂公司將 Python 集成進新游戲引擎的一些經(jīng)驗。說明我們選擇 Python 的原因、獲得的收益、遇到的問題,以及我們是怎樣解決它們的。

為什么要使用腳本語言

C++ 是一種強大的語言,并且是 C 語言的巨大改進,但它并不是完成所有任務(wù)的最佳選擇。C++ 非常強調(diào)運行時性能 [Stroustrup94],譬如,假如一個語言特性使得程序跑起來變慢,那么這個特性便不會加入 C++ 語言中。C++ 程序員也因此背負了很多的限制和煩惱。這里列出一些限制,C++ 程序員經(jīng)常遭遇這些事情但很少注意它們的存在:手工管理內(nèi)存:C++ 程序員的大量時間都花在考慮調(diào)用 delete 的適當(dāng)時機。鏈接過程:C++ 模塊(在編譯時或加載時)鏈接在一起,因此在運行時,無需進行的函數(shù)地址的解析。這提高了運行時的性能,但是卻使 編輯/測試 周期變長了。缺乏自省能力 [TR2: introspection]:C++ 有自己的方式知道一個類中包含哪些成員,但是這種方式需要編寫過多的加載和存儲對象的代碼,而在一些腳本語言中這只需調(diào)用一個內(nèi)建函數(shù)就可以完成。C++ 是靜態(tài)的,而腳本語言是動態(tài)的。簡單地說,C++ 的程序運行地很快,但是腳本語言能讓你編碼更快。所以,C++ 應(yīng)該只用在你希望優(yōu)化運行時性能的地方。現(xiàn)在計算機的運行速度都足夠快,對于大多數(shù)代碼來說性能都不是問題。如果你用 C++ 開發(fā)那些用腳本語言也能實現(xiàn)的程序,那么你是在錯誤的事情上進行優(yōu)化。

SCUMM 的問題

Humongous 公司已經(jīng)使用 SCUMM (Script Creation Utility for Maniac Mansion) 創(chuàng)造了 50 多個游戲。SCUMM 是一個強大的 冒險游戲 開發(fā)語言,但是它有一些局限性。SCUMM 是十多年前寫的,它缺少一些現(xiàn)代語言的特性。盡管 SCUMM 有持續(xù)的補丁和維護,它也沒有辦法像其它語言一樣健壯和有完備的功能了。

為什么選擇 Python

我們有過創(chuàng)造一種新型的、現(xiàn)代的 私有語言的想法,但最終明智地放棄了這種想法。我們的職責(zé)是在做游戲,而不語言。我們在每年花費大量開銷維護一套私有工具的情況下,確實希望使用一種已有的腳本語言而不是重新創(chuàng)造一種。使用已有語言更快地投入工作,花費更少的開銷,并且通常情況下要比我們創(chuàng)造的好,并且以后會發(fā)展地更好,即使我們不用它工作。一旦我們決定要使用已有的腳本語言,就需要從中選擇一種。我們需要一種支持 面向?qū)ο缶幊蹋⑶夷芮度氲轿覀冇螒蛑械恼Z言,而且它不存在任何技術(shù)和許可授權(quán)上的問題。我們考慮了 Lua [Lua01] 和 Python [Python02],這兩種語言已經(jīng)被應(yīng)用在某些游戲中了。Lua 較小,更加容易嵌入到應(yīng)用程序中,并且有一些很棒的語言結(jié)構(gòu)。但是,那時我們發(fā)覺 Lua 的文檔有些粗略,這大概是因為 Lua 是比 Python 更新的語言。Python 比 Lua 有更多的擴展模塊,更多的參考書籍,并且 stackless Python [Tismer01] 很適合為對象 AI 創(chuàng)建微線程[TR3: micro-threads]。最后我們沒有選擇 Python 的 stackless 版本,但開始用 Python 寫自動生成腳本,這給了我們繼續(xù)使用 Python 的動力。當(dāng)了解了 Python 后,我們喜歡上了它的語法,最后選擇了它。在我們決定之后,這兩種語言都發(fā)生了改進:Lua 已經(jīng)變成 stackless,而 Python 有了生成器,這個能提供一些相似的功能。現(xiàn)在任何一種都是安全的選擇。

誰在游戲中使用了 Python

Python 已經(jīng)被使用在很多游戲中,包括:

  • ToonTown -?http://www.toontown.com/

  • EveOnline -?http://www.eve-online.com/

還有很多其它的游戲,只是我們很難確認,例如至少有一個 PS2 游戲使用了 Python。

同時 Python 也至少用在兩個游戲引擎中:

  • Game Blender -?http://www.blender.nl/gameBlenderDoc/python.html

  • PyGame -?http://www.pygame.org/

一個生成腳本示例

下面是一段 Python 代碼示例,它是一個遞歸生成所有 VC++ 工作區(qū)的簡單生成腳本。它只有以下幾行:

加上更多的代碼,可以讓這個腳本 [Dawson02] 分析輸出結(jié)果,然后給團隊中的每個人發(fā)送一份結(jié)果報告郵件。不像某些其它腳本語言,上面代碼有很好的可讀性。使用 Python 來寫生成腳本和游戲腳本將會省卻很多學(xué)習(xí)的時間。這個生成腳本示例也顯示了一些對 Python 新手很頭疼的問題。Python 的流程控制由縮進指明,而不使用 begin/end 聲明或大括號。我用了很短的時間來適應(yīng)這種規(guī)則,最后我發(fā)現(xiàn)這種規(guī)則很有效。我曾經(jīng)不止一次討論過 C/C++ 中的大括號應(yīng)該寫在哪里,我想 Python 程序員有更高的工作效率,因為他們不用花費時間爭論 K&R 及其它縮進風(fēng)格[TR4: indenting style] 的事情。因為代碼塊由縮進定義,編寫時便不會出現(xiàn)任何不符合 Python 編譯器規(guī)則的縮進(因為那樣的話,程序就會出錯)。要注意的是,當(dāng)你混用 TAB 和空格進行縮進時,可能出現(xiàn)問題。大多數(shù)程序員使用寬度為 3 個或 4 個空格的 TAB 縮進,但是在 Python 編譯器內(nèi)部卻使用 8 個空格的縮進,混合使用 TAB 和空格可能導(dǎo)致語法錯誤。如果你完全地使用空格或 TAB 進行縮進,并且使用一個能夠提示混用空格、TAB 縮進警告的 IDE,那么便沒有什么問題。

游戲腳本示例

下面的示例是我們的第一個 Python/C++ 游戲中的一些 Python 代碼。這些代碼是 Python 正在執(zhí)行的一個主循環(huán),它調(diào)用了其它的模塊,這些模塊甚至可以用其它語言編寫:

因此,我們的游戲由 Python 啟動,并在需要時調(diào)用 C++ 程序。

它是如何工作的

Python 程序由模塊組成,當(dāng)在一個源文件中使用另一個源文件中定義的函數(shù)時,需要導(dǎo)入那個文件。例如,gameai.py 有一個 UpdateAI 函數(shù),那么在其它 Python 源文件中可以這樣調(diào)用它:

游戲程序員能夠想到的一個很棒的事情是,如果 UpdateAI() 跑起來很慢,那么可以用 C++ 來重寫它。為了做到這點,在 gameai.py 中的函數(shù)和類型需要用 C++ 實現(xiàn),并且在 Python 中注冊為原先的模塊名。之后,使用者能夠繼續(xù)導(dǎo)入并使用 gameai 模塊,而不需要任何更改。因此,Python 模塊能夠幫你簡單地用 Python 搭建你的整個游戲框架,而在適當(dāng)?shù)牡胤接?C++ 代碼實現(xiàn)。

粘合代碼 (Glue Code)

如果你自己手工編寫讓 C++ 代碼和 Python 協(xié)同工作的粘合代碼,那將是一件枯燥繁瑣的事情 [TR5: glue code]。一個能夠產(chǎn)生粘合代碼的系統(tǒng)框架是很重要的。Swig, Boost, CXX 等 [Abrahams01] 能幫你產(chǎn)生代碼,更方便地將 Python 和 C++ 粘合起來。還有 Fubi[Bilas01],它是一個通用的框架,可以將 C++ 的函數(shù)和類映射到一種腳本語言中。早期,大多數(shù)這些粘合代碼框架都依靠分析 C++ 頭文件工作。因此,它們受到暴露的 C++ 頭文件的限制,并且一些框架不支持從 C++ 類派生出 Python 類。后來,這些框架都有所改進,所以現(xiàn)在還是值得考慮的。而我們決定做一個自己的方案,它可以根據(jù)類的 IDL 描述或?qū)С龊瘮?shù)來生成粘合代碼。它的代碼叫做 Yaga,是一個遞歸命名法,表示 Yaga is A Game Architecture。

一個典型的 Yaga IDL 代碼如下:

它可以生成以下粘合代碼,還有其它一些代碼:

使用這個框架可以很簡單地導(dǎo)出類和函數(shù),從 C++ 類派生 Python 類,將 C++ 的數(shù)組和 vector 映射為 Python 的序列類型,以及更多的事。

內(nèi)存分配

Python 之中任何東西都是對象,對象被分配內(nèi)存。因為所有的對象都有引用計數(shù),所有你不用擔(dān)心釋放內(nèi)存。但是,如果你是在編寫游戲,尤其是控制臺游戲(譯注:指次時代及專用游戲機平臺游戲),你必需要明白這些內(nèi)存從何處分配而來,以及分配過程會產(chǎn)生內(nèi)存碎片的嚴(yán)重性。為了控制這個性能問題,你需要隔離 Python,使其有自己的內(nèi)存分配場。你需要重定向所有的內(nèi)存分配操作到一個自定義的分配器上,它從一個固定大小的分配場中分配內(nèi)存。只要你預(yù)留足夠大小的緩沖區(qū),大于最大的 Python 歷史分配額度(原文:leave enough of a buffer above the maximum Python memory footprint),應(yīng)該就能避免內(nèi)存碎片問題。另一個內(nèi)存問題是沒有釋放的塊。這通常在 Python 中不是問題,因為每個對象都有引用計數(shù),當(dāng)變量離開作用域或者被顯式刪除,其引用計數(shù)就會減一,當(dāng)計數(shù)為 0 時,對象就被釋放,對象生命結(jié)束。試想這樣情況,一個被忘記的變量,它關(guān)聯(lián)了一串其它的對象,這時就會阻礙這些對象的釋放,所以你應(yīng)該對清理對象保持警惕。然而,更糟糕的事情是循環(huán)引用問題,例如:對象 A 包含對象 B,但是對象 B 有一個回調(diào)指針指向?qū)ο?A,那么這兩個對象永遠都不會被刪除。Python 的開發(fā)者們意識到這個問題,在最近的 Python 版本中加入了一個垃圾收集器,它搜尋無法訪問到達的對象,并將其全部清除。垃圾收集器對于游戲是很糟的,因為無法預(yù)知它們的運行時間,并且可能運行很長時間,使得畫面的幀率降低。因此,游戲程序中需要禁用垃圾收集器,這個做起來很簡單,隨后在每個游戲關(guān)卡后顯式地調(diào)用它。垃圾收集器同時也能告訴你 有多少無法訪問到達的對象仍然在分配中,這個可以幫助你跟蹤循環(huán)引用的情況,之后你可以手工地解決它們,這相當(dāng)于 Python 的內(nèi)存泄露檢查。

性能

如果你用 Python 做一些繁重的浮點計算工作,和 C++ 的性能相比會很讓人失望。Python 是一個慢語言,每個對象引用都意味著進行哈希表查詢,每個函數(shù)調(diào)用也一樣。這根本不能和 C++ 的性能相提并論,后者的變量位置和函數(shù)調(diào)用地址在編譯時就決定了。但這并不意味著 Python 不適合做游戲編程,而是你需要在適當(dāng)?shù)牡攸c用它。如果拿字符串操作或 C++ STL 的 set 和 map 類型操作做對比,那么 Python 代碼也許會做地更快。Python 的字符串操作函數(shù)是用 C 寫的,并且 Python 的引用計數(shù)對象模型能夠避免一些 C++ string 類的字符串復(fù)制過程。set 和 map 的大多數(shù)操作的復(fù)雜度是 O(log n),而對于 Python 的哈希表復(fù)雜度則是 O(1)。你一定想,最好不要用 Python 寫 場景圖形遍歷 或 BSP 沖突檢測代碼。但是如果你用 C++ 寫它們,而后又導(dǎo)出到 Python 中使用,那么你就可以更快地編寫 AI 代碼。請牢記 90/10 原則,這意味著對于 90% 的代碼,你不必過多操心它們的運行時性能,而代碼的明確表達力和編碼的效率才是關(guān)鍵。

控制臺游戲

內(nèi)存和性能問題在控制臺游戲平臺上尤其重要。當(dāng)不存在虛擬內(nèi)存可以讓你漫不經(jīng)心做內(nèi)存分配的時候,保證在獨立的內(nèi)存分配場中分配 Python 內(nèi)存就顯得格外重要。同時,也要更明智地使用垃圾收集器 (as is using the garbage collector wisely)。控制臺平臺沒有鍵盤、鼠標(biāo)和多顯示器,所以在控制臺平臺上運行 Python 調(diào)試器用起來很不方便。遠程調(diào)試是關(guān)鍵,它能讓你知道 Python 代碼的運行過程。很幸運,使用免費的 HapDebugger[Josephson02] 可以很容易建立遠程調(diào)試環(huán)境。Python 使用 C 編寫,并且已經(jīng)被移植到多種編譯環(huán)境和平臺下,包括 PDA。因此,在某個控制臺游戲平臺下 Python 可能已經(jīng)有了很充分的發(fā)展。Python 會花費掉一小部分和控制臺游戲無關(guān)的內(nèi)存,但是在新一代游戲平臺上可以不用擔(dān)心這個,它們最小都有 24M 內(nèi)存。

法律問題

推向一種新的語言對于我們公司來說是個重大的決定,我覺得在進行之前,它定是受到了公司律師們的祝福。律師懂得法律,但他們通常不太懂編程。大多數(shù)程序員在引入開源代碼前都不會咨詢公司的律師,當(dāng)你確實問他們時,他們會認為你正在問一些奇怪且偏僻的事情。他們的立即反應(yīng)是,認為那是有風(fēng)險、沒有保證的計劃。如果你和一個擅長知識產(chǎn)權(quán)的律師長談,他會一直向你灌輸“使用開源軟件會讓你焦頭爛額”的思想。有一些案例指明,在“免費發(fā)布”的源碼中包含專利或有版權(quán)的內(nèi)容時,有嚴(yán)重的法律問題隱患。當(dāng)你從商業(yè)軟件供應(yīng)商那里得到授權(quán)代碼時,他們會保護你免受法律責(zé)任,但對于開源軟件沒有人能給予授權(quán)許可 (with open source software there is no one to license it from)。然而,開源社區(qū)對知識產(chǎn)權(quán)法律總是很警惕。例如 JPEG 已經(jīng)從它們的開發(fā)庫中移除了 LZW 算法代碼以避免專利問題 [IJG]。負責(zé)的程序員會關(guān)心授權(quán)許可問題,并且通常對 GPL 和 LPGL[FSF01] 以及他們的區(qū)別很熟悉。將開源代碼引入商業(yè)產(chǎn)品存在很多風(fēng)險。這些風(fēng)險應(yīng)嚴(yán)肅對待,但不應(yīng)該阻止對開源代碼的使用。有很多開源的開發(fā)庫使用在游戲開發(fā)中,Python 實在沒什么理由不被使用。

缺點

多語言開發(fā)增加了額外的復(fù)雜層次。同時調(diào)試兩種語言的代碼很困難,而且必須花費時間維護綁定兩種語言的粘合代碼。類似 Python 的動態(tài)語言沒有編譯時類型檢查。這種情況初看讓人驚恐,但它的實際意味著,相比 C++ 你會遇到各式各樣不同的運行時錯誤,通常它們都很容易解決。

不同類型的換行符

UNIX (LF)、Mac OS (CR) 和 Windows (CR LF) 對待文本文件中一行的結(jié)束有不同的約定,這實在很糟。Windows 上的 C/C++ 庫(譯注:指 Windows API 和 VC 運行時庫)會做換行符轉(zhuǎn)換,所以 UNIX 文件能夠在 Windows 上讀取,可以將 Windows 文件像 UNIX 文件一樣的操作。UNIX 和 Macintosh 文本文件之間的共同點更少,只能依靠假定某個平臺上的文件都只是這個平臺上曾經(jīng)創(chuàng)建的,這個假設(shè)進行轉(zhuǎn)換。這個假設(shè)在當(dāng)今的網(wǎng)絡(luò)環(huán)境下站不住腳,Python 也深受其害。直到現(xiàn)在,在 Windows 下寫的 Python 代碼可能無法在 Macintosh 下編譯,反之亦然。這個問題的解決方法是,在運行 Python 代碼前,將 Python 源文件通過一個文件過濾器(可以用 Python 開發(fā)?)執(zhí)行,另一種方法是以編譯后的字節(jié)碼形式發(fā)布 Python 代碼。但是,這兩種辦法都有缺點。最理想的是在計算機工業(yè)中標(biāo)準(zhǔn)化文本文件格式,或者讓所有的文件 IO 庫實現(xiàn)讀取任意類型文本文件的能力。這個問題在蘋果的 OS X 上更加有趣,換行符由運行程序的模式而定,你可以運行 UNIX 或 Macintosh 兩種模式程序。這會在一個系統(tǒng)下出現(xiàn)兩種不同的換行符,甚至不用重啟。Python 的 Macintosh 版本最近修正了這個問題,在打開文件時檢查換行符并對每個文件進行調(diào)整。將所有的換行符都規(guī)定為 UNIX 類型是一種可行的方法,它在所有平臺下都能工作,但是還是要留心這個問題。

調(diào)試器問題

很多 Python 程序員認為自動化測試和打印語句是他們唯一需要的調(diào)試工具,而使用調(diào)試器會影響編碼的產(chǎn)能。或許這對他們來說的確如此,但我已經(jīng)習(xí)慣于進行源碼級調(diào)試,并且不會輕易放棄它。PythonWin 是一個在 Windows 下的 Python 調(diào)試器兼 IDE(奇特吧?)。它是免費的,有一些不錯的功能,但也有一些缺點,如:只能在 Windows 下運行,無法調(diào)試有自身消息循環(huán)的 Python 程序。在 Humongous 娛樂公司,我們?yōu)?Macintosh 和 Windows 開發(fā)游戲,同時也涉及控制臺游戲的開發(fā)。我們需要一種能工作在所有三個平臺上的調(diào)試器,而最好的方案就是使用遠程調(diào)試器。Python 的架構(gòu)使得編寫它的調(diào)試器很容易,再加上其它一些免費組件,我們開發(fā)出了自己的 Python 調(diào)試器,我覺得它的效果比 PythonWin 好,并且具有遠程調(diào)試功能。被調(diào)試的客戶端需要運行一些額外代碼。調(diào)試接口是 socket 上的 ASCII 文本,另外,我們還沒考慮將調(diào)試器客戶端移植到更多其它平臺的問題。因為我們希望集中精力開發(fā)游戲本身,而不是語言工具,所以決定再次借用開源的力量。我們在 Python 社區(qū)發(fā)布了 HAP 調(diào)試器 (Humongous Addition to Python),將其作為一個開源項目[Josephson02]。這是一個回饋社區(qū)的好機會,并且我們也從維護這個調(diào)試工具的事務(wù)中解放出來。我們還沒有解決的問題是調(diào)試器的性能問題。大多數(shù)編譯式語言實現(xiàn)調(diào)試斷點的方法是,將常規(guī)指令替換為導(dǎo)致 CPU 異常的指令,如 x86 處理器的 int 3 中斷。這讓程序可以全速執(zhí)行,直到觸發(fā)中斷點。Python 不支持從異常處恢復(fù)執(zhí)行,所以不能使用斷點異常的方法。Python 調(diào)試器處理斷點的方法是 單步檢查代碼,即不停地在問自己“這一行有沒有斷點?”這個性能影響的后果可能很嚴(yán)重。我們現(xiàn)在減小此影響的方法是,保證開發(fā)機器要比目標(biāo)機器快得多。還有,將所有重量級計算用 C++ 擴展實現(xiàn),這樣即使 Python 代碼拖慢了調(diào)試器,也不至于讓整個游戲速度太慢。這是一個可以解決的問題,只是 Python 的主要開發(fā)者還沒考慮過。

代碼安全和游戲作弊

C++ 程序員有時開玩笑說,刪除注釋和縮短變量名可以優(yōu)化代碼。然而,在 Python 中確實如此。Python 代碼在運行時被編譯成字節(jié)碼,并緩存起來以備后續(xù)運行,所以刪除注釋的方法不會起到優(yōu)化程序的效果,但是縮短變量名則是另外一回事。大多數(shù)腳本語言都是在運行時通過名字定位變量的,這也是腳本語言強大的原因之一,因為它可以突破很多由 C++ 編譯時綁定造成的限制。然而,這也意味著變量名會一直伴隨著代碼而存在(譯注:C/C++ 等傳統(tǒng)編譯式語言則不同,經(jīng)優(yōu)化編譯后的 C/C++ 程序中沒有變量名而只有地址的概念)。游戲程序中包含語義清晰 (scatological) 的變量名,會被人當(dāng)做笑談。更嚴(yán)重的問題是,如果在多人游戲中使用 Python 腳本,作弊者反編譯 Python 程序后會得到完整的變量和函數(shù)名,這比起通過反編譯 C++ 程序來破解游戲要更簡單。

Python 的優(yōu)點

Python 編程很有趣。Python 易于學(xué)習(xí),有更高的生產(chǎn)效率,并且促使你使用另一種思維編程。學(xué)習(xí) Python 編程讓我成為更好的 C++ 程序員。快樂的程序員有更高的學(xué)習(xí)效率和生產(chǎn)效率,他們傾向創(chuàng)造更好的游戲。Humongous 公司中使用 Python 開發(fā)游戲的團隊,在整個公司中擁有最高的工作士氣。Python 游戲編程系統(tǒng)(譯注:應(yīng)指開發(fā)工具、框架、類庫等)具有很高的生產(chǎn)效率,而且它們?nèi)匀辉诎l(fā)展之中。因為采用了它們,我們節(jié)省了很多資金。(原文:Productivity is higher with the Python game programming system, even though development is still being done on it. It is already clear that we will save a lot of money from this switch.)用戶界面的開發(fā),在 C++ 中可能花費較長的時間,而在 Python 中可以使用一些新意的方式進行實現(xiàn)。通常使用文本文件定義 GUI 元素的位置和關(guān)聯(lián)圖形資源,進而定義菜單。在 C++ 中會使用硬編碼的函數(shù)和控件對象,掛鉤 GUI 元素;而在 Python 中,可將函數(shù)及對象名放入文本文件中,并在運行時掃描它們。Python 的動態(tài)和內(nèi)省特性 (introspective) 使得做起這些事來很自然。(譯注:C++ 也可使用讀取文本配置方式,自動生成菜單,只是用 Python 的反射特性做起來更自然)很多起先我們擔(dān)憂的 Python 語言限制問題都已成為過去。Python 的開發(fā)者們對該語言進行持續(xù)地改進,有時他們就像一直在滿足我們對 Python 特性需求的渴望一樣。

游戲存檔和讀檔

C++ 程序員要花費很多時間解決腳本語言中不會出現(xiàn)的困難問題。例如,用 C++ 進行游戲狀態(tài)的存儲和讀取就是一個麻煩問題,經(jīng)常要編寫大量的代碼。而且這種方法通常會導(dǎo)致,存檔只能和特定版本的游戲程序配合工作。而在 Python 中,使用 cPickle 模塊可以很方便的解決此問題,它可以存儲和讀取任何復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。下面例子中聲明了一個對象 mainObject,通常它是一個用戶自定義類對象,包含各種需要存儲的狀態(tài)的句柄,但為簡單起見,這里只把它做成一個列表。最初該列表包含數(shù)字 0 和一個字符串,然后將列表的第一個元素賦值為另外一個列表。這個過程可以繼續(xù)下去,讓 mainObject 包含任意復(fù)雜嵌套層次的對象,包括循環(huán)引用。

接下來保存著這個 mainObject,這需要兩行代碼。一行導(dǎo)入 cPickle 模塊,另一行打開一個文件,將對象保存為二進制格式。在開發(fā)時,保存為文本格式很有用,只需省略掉 dump() 的最后一個參數(shù)即可。

然后是裝載文件數(shù)據(jù),這同樣需要兩行代碼。一行導(dǎo)入 cPickle 模塊,另一行重建 mainObject 對象,以及包含的子對象、列表、成員變量等。第三行打印出 mainObject 對象,可以看出已經(jīng)正確地恢復(fù)了嵌套的列表。

這個 Python 特性在 C++ 基本功能中不存在。

生成器:游戲 AI 的微線程

微線程將對象狀態(tài)信息放到局部變量中(這是恰當(dāng)?shù)奈恢茫瑥亩鴺O大簡化 AI 和對象更新代碼 [Carter01]。可以使用匯編語言的技巧將微線程放進 C++ 中,但是那樣很凌亂。在最近版本的 Python 中,微線程內(nèi)建于語言之中。現(xiàn)在使用微線程會工作地很好。在 Python 中它們叫做生成器 (generator),使用它們編寫函數(shù),函數(shù)產(chǎn)生某個結(jié)果后,控制返回到主程序。主程序稍后可以重新喚醒它們,并從中斷處繼續(xù)運行,并保持原來的局部變量值。下面的示例代碼展示創(chuàng)建一個對象,并移動它們穿過屏幕。這個簡單例子并不能從微線程/生成器中得到實際的好處,它只是基本展示它們怎樣用來簡化 AI 和對象更新代碼。

即使你不使用生成器,在 Python 中實現(xiàn) AI 更新方法也比用 C++ 更干凈。因為如果你的某部分 AI 代碼需要一些額外的臨時狀態(tài)時,Python 可以將它加入到對象中,然后在不需要時刪除它。而 C++ 因其靜態(tài)特點,不能在運行時加入新的成員變量,這使你的對象在任何時候都必須包含所需的所有狀態(tài)。

開始使用 Python

如果你開始使用 Python,第一件事是訪問 Python 的官方網(wǎng)站?http://www.python.org/?下載你的平臺上的 Python 版本。Python 文檔在?http://www.python.org/doc/current/download.html,也有編譯的 HTML 版本 (CHM) 更便于檢索。Windows 開發(fā)者可以使用 PythonWin 和各種 Win32 擴展http://users.bigpond.net.au/mhammond/win32all-142.exe調(diào)試器 HapDebugger?https://sourceforge.net/projects/hapdebugger/你可以下載并編譯 Python 源碼,構(gòu)建自己的 Debug 和 Release 版 Python。Python 2.2 源碼下載ftp://ftp.python.org/pub/python/2.2/Python-2.2.tgz最后,你可以閱讀關(guān)于手工創(chuàng)建 Python 擴展的細節(jié)http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66509,然后選擇一種粘合代碼包來幫你做這些事情

參考

  • [Stroustrup94] Stroustrup, Bjarne "The Design and Evolution of C++", Addison Wesley, 115

  • [Lua01] "The Programming Language Lua"

  • http://www.lua.org/

  • [Python02] Python Language Website

  • http://www.python.org/

  • [Tismer01] Tismer, Christian "Stackless Python"

  • http://www.stackless.com/

  • [Dawson02] Dawson, Bruce "Python Scripts"

  • ftp://ftp.cygnus-software.com/pub/pythonscripts.zip

  • [Abrahams01] Abrahams, David, "Comparisons with Other Systems"

  • http://www.boost.org/libs/python/doc/comparisons.html

  • [Bilas01] Bilas, Scott, "FuBi: Automatic Function Exporting for Scripting and Networking"

  • http://www.gdconf.com/archives/proceedings/2001/bilas.doc

  • [IJG]?http://www.ijg.org/?- docsREADME in the source distribution

  • [FSF01] "What is Copyleft?"

  • http://www.gnu.org/copyleft/

  • [Josephson02] Josephson, Neal "HAP Python Remote Debugger"

  • http://sourceforge.net/projects/hapdebugger/

  • [Carter01] Carter, Simon "Managing AI with Micro-Threads", Game Programming Gems II, Charles River Media, 265-272

  • ?

更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 精精国产www视频在线观看免费 | 久久99热只有频精品6不卡 | 尤物精品国产福利网站 | 五月婷婷激情四射 | 亚洲成网站www久久九 | 成人性视频免费网站 | 香蕉视频黄色片 | 91亚洲国产成人久久精品网址 | 欧美hdvideosex4k| 91精品久久国产青草 | 激情综合网五月激情 | 国产性做久久久久久 | 黄色片网站观看 | 激情综合婷婷 | 97精品久久天干天天蜜 | 黄色毛片免费观看 | 欧美区一区| 91精品成人福利在线播放 | 午夜精品福利在线 | 精品不卡 | 日本边添边爱边做视频 | 高清不卡免费一区二区三区 | 国产成人精品久久亚洲高清不卡 | 日本中文字幕一区二区高清在线 | 欧美毛片免费看 | 爱爱免费观看高清视频在线播放 | 色婷婷色综合 | 国产精品国内免费一区二区三区 | 中文字幕在线二区 | 两性视频网站 | 亚洲第一视频在线播放 | 色综合久久综合欧美综合 | 国产在线精品一区免费香蕉 | 久久成人亚洲香蕉草草 | 人成xxxwww免费视频 | 最新国产中文字幕 | 奇米影视播放器 | 99热精品在线 | 天天操天天摸天天碰 | 精品中文字幕乱码一区二区 | 精品一区二区日本高清 |