Celestia/Celx 指令碼編寫/開發建議
| 一位讀者已將本章認定為未完成的草稿或提綱。 您可以幫助完成此作品,或在專案室尋求幫助。 |
一旦您超越了編寫最簡單的 CELX "Hello World" 指令碼,軟體的開發就會成為一個問題。Lua 程式設計與任何其他語言的程式設計一樣複雜,甚至可能比許多語言更具挑戰性。由於 Lua 是一種解釋型語言,具有執行時編譯器,因此查詢細微錯誤通常是一個問題。以下是一些建議,有助於更輕鬆地開發和除錯 Celestia 的 Lua 模組。
Celestia 在許多方面都是一個了不起的應用程式,其中最不重要的是它以 Lua 的形式提供了可擴充套件性,Lua 是它的內建程式語言。Lua 速度快、功能強大,可以增強 Celestia 體驗,其方式僅受想象力的限制。但正如本叔叔曾經對彼得·帕克說過的,能力越大,責任越大。Celestia 的 Lua 不會牽著你的手。它幾乎病態地堅持讓你幾乎可以做任何事而不會抱怨。就像有一個女朋友,她太甜了,從不抱怨任何事。然後有一天她不見了,你發現了一張關於你從不收拾襪子的惡毒便條。Celestia 的 Lua 就是這樣。你可以幾乎做任何事,但代價很高。而且 Lua 甚至不會留下便條。有一天 Lua 會拋棄你,你根本不知道為什麼。但這不像 Lua 不會告訴你她的問題,如果你問的話。你只需要問。(對你女朋友來說也是個好主意。)
您需要做的第一件事是熟悉一個名為 "pcall" 的 Lua 函式,就像 Lua 的所有函式一樣,您可以在 "Lua 參考手冊" 中找到完整的描述,該手冊以書籍或線上形式提供,可在 http://www.lua.org/manual/5.0/ 獲取。
您應該編寫的第一個函式之一類似於
error_pause = 20
result, error = pcall( f )
if(result == false) then
celestia:print(error, error_pause)
wait(error_pause)
end
其中 "f" 是您編寫的函式。當您開始程式設計時,您應該養成使用 pcall 呼叫所有函式的習慣。當您的程式除錯完畢後,可以根據需要刪除它們,但您可能應該保留包含 pcall 語句的程式副本。很有可能,您可能希望修改您的寶貝。
您實際上是在複製大多數其他語言內建的錯誤報告。這裡的優勢在於,當您完成操作時,可以消除錯誤檢測的開銷。
接下來您應該做的事情(如果您還沒有做的話)是閱讀 Harald Schmidt 關於 Lua/CELX 指令碼編寫的線上描述,網址為 http://celestia.h-schmidt.net/celx-summary-latest.html 這將提供所有可用的 Celestia 功能,以及一些關於 Lua 的提示,但我建議您還閱讀 Lua 手冊,並結合 Harold 的描述進行閱讀。
當然,程式設計風格是見仁見智的,但如果您要編寫任何大型程式,我建議您利用 Lua 的能力,在需要時簡單地讀取新程式碼。例如,下面的 dofile 就是一個示例。
function dofile(filename)
s = assert(loadfile( filename ), "unable to load " .. filename)
return s
end
此函式將編譯檔案中的程式碼,並在失敗時發出錯誤。
在這種情況下,您可以利用 Lua 的垃圾收集器。Lua 定期對程式不再連結的任何記憶體進行垃圾收集。"dofile" 上面的程式碼可能會覆蓋連結,Lua 會自動(最終)釋放記憶體,如果您需要,您的程式碼幾乎可以無限擴充套件。這也適用於您可能讀取的任何文字。覆蓋對字串的連結會釋放舊記憶體。
Lua 遵循 KISS 原則:"保持簡單,愚蠢。"Lua 中只有八種資料型別:nil、布林型、數字型、字串型、函式型、userdata、執行緒型和表型,其中 "userdata" 只是一個未定義的記憶體塊。
相信我,簡潔是一件好事,僅僅因為它比記住更容易設計。您可能最常使用的資料型別是表,它實際上是一個數組,幾乎可以用任何東西(除了 nil)作為索引。
如果您在 Mac 上程式設計,請注意,Mac 版本與 PC 版本有一些細微的差別,其中最主要的是如何處理註釋。手冊中說註釋可以以 "[[" 開頭,但這在 Mac 上不起作用。我在 Mac 上使用的註釋形式是
--[[ this is a comment ]]
請注意,"--" 位於括號之前。對於多行註釋,我使用
--[[
The following code is the most magnificent piece of ...
--]]
注意:這似乎是由 Mac 文字編輯器充當文字處理程式造成的。它們假設當您鍵入兩個連字元後跟一個空格時,您實際上想要一個 em 連字元(一個單一的、雙寬連字元),並用雙寬連字元的單個二進位制程式碼替換這兩個連字元。不幸的是,這破壞了 Lua 的註釋約定,該約定需要兩個單獨的連字元字元。幸運的是,如果您在兩個連字元後跟任何字元(空格或製表符除外),Mac 編輯器就不會進行替換。
Celestia v1.5.0 無法檢測到 ScriptedOrbit 或 ScriptedRotation 何時為將具有其位置或方向作為 ScriptedOrbit 或 ScriptedRotation 的副作用而修改的物件呼叫 obj:getposition() 或 obj:getorientation()。
因此,如果 "obj" 的位置(或方向)由該 Scripted 函式決定,即使是間接決定,也不能從 Scripted 函式中呼叫 obj:getposition()(或 obj:getorientation())。這樣做會導致 getposition() 呼叫例程,這些例程會呼叫 Scripted 函式,該函式又會呼叫 getposition()... 無窮無盡。這會很快耗盡堆疊空間並導致 Celestia 崩潰。
建議:Scripted 程式碼可以簡單地返回之前的位置或方向,而不是嘗試計算新的位置或方向。
希望這種情況會在 Celestia 的未來主要版本中得到解決。
在 celx 指令碼中使用 Lua 的 'require' 函式時,Lua 會使用 Celestia 的根目錄來查詢 Lua 檔案。 然後,您可以在 celx 指令碼中定義不同的路徑,使用
package.path = "mypath/?.lua;"
要將 celx 指令碼的目錄設定為預設路徑,只需在指令碼開頭新增以下行:
package.path = celestia:getscriptpath().."/../?.lua;"