代碼範例
以下function會創建一個string內容為 "Hello, censing!"顯示給所有玩家:
function Trig_JASS_test_Actions takes nothing returns nothing call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "Hello, censing!") //在螢幕位置0,0處對本地玩家顯示文本訊息Hello, censing! endfunction
|
或者你只想傳送給某個玩家:
function Trig_JASS_test_Actions takes player p returns nothing call DisplayTextToPlayer(p, 0,0, "Hello, censing!") endfunction
|
還有你想遞增式連續顯示90次的話:
function Trig_JASS_test_Actions takes player p returns nothing local integer i=0 loop exitwhen i==90 call DisplayTextToPlayer(p, 0,0, "Hello, censing! "+I2S(i)) set i=i+1 endloop endfunction
|
學習語言
某些功能只靠GUI Trigger無法完成, 必須用JASS來實現。例如對指定玩家播放音效,或者替單位加上永不消失的被動物品技能等。
JASS可以定義
局部變數及自定義函式,增加設計的便利性,也提供更簡單可行的演算法。
GUI雖然能完成幾乎所有的功能,但是對於
記憶體釋放的能力太差,容易增加電腦不必要的負擔。
用JASS可以寫出比GUI效率更高的代碼,對執行速度有不小的幫助。一定要學JASS嗎?
當然不一定。即使是官方的戰役,其程式設計師也只使用了GUI來完成製作。一般來說,單純使用GUI Trigger,就可以達到大多數的功能。但是筆者還是建議對Trigger有相當了解的人學些基本的JASS寫法,可以省下不少力氣,且能讓你的地圖更不
lag!!
使用語言
觸發編輯器中的 Edit =>Convert To Custom Text 將觸發轉成文字型態。
在觸發編輯器下面選 Actions => Custom Script 可以插入單行JASS敘述。
此外,如果要定義所有觸發都能調用的函式
JASS語言的基本函式和常量都是直接調用遊戲的函式,他們被存放在war3patch.mpq內的Scripts\common.j中,另外還有一些擴充函式放在war3patch.mpq內的Scripts\blizzard.j中。war3patch.mpq內的Scripts\common.ai則包含了用於設計AI的內部函式和擴展函式,雖然AI也是用JASS碼編成,但本文不探討關於AI的設計,有興趣者請自行研究。
地圖中的觸發以及物件的擺設情形等,都會被編譯成JASS並儲存在war3map.j檔案中。讀者可以到WE中的 File => Export Script 將它導出。
JASS語言以列為基本單位。每一行的代碼必須有完整的意義,不能把一行的代碼分兩行寫;也不可把兩行的代碼寫在同一行。
JASS語言是區分大小寫的,該大寫就要大寫;該小寫就要小寫。
寫在//後面,直到該行結束的文字都是註解內容,這也是JASS唯一的注釋語法。後面的例子會多處用到這個注釋符號,這個符號和後面的注釋只是用於解釋代碼的功能,並不會被執行到 。
在JASS中,空格的使用限制很寬鬆,除了某些必要的地方一定要有至少一個的空格以外,其它的地方都是可空可不空。此外,要空幾格都無所謂,電腦不會因為你空了很多格就說有錯。因此,使用者應多多利用空格作縮進,以使代碼更易讀。
和數學一樣,()內的代碼優先被執行。不過請注意,JASS中只有小括弧()有用,
中括弧[]和
大括弧{}不可作為改變執行順序之用。
與一般高級語言一樣,Jass語言具有定義變數、賦值運算、
函式調用、條件語句、
循環語句、定義函式等最重要的功能。見下表
功能 | 示例或語法 |
變數定義與賦值 | local integer i=1 local real a=i+0.3 set i=i-100
|
| call BJDebugMsg( "A problem has occurred" ) call BJDebugMsg( I2S( 5000 ) )// I2S把整數轉化為字元串,從而輸出"5000"
|
條件語句 | if ( ... ) then .... elseif ( ... ) then ... // 支持多個elseif分支 else ... endif
|
| loop ... exitwhen ( ... )// exitwhen可以出現在循環下任何位置,一般情況下至少要有一個exitwhen ... endloop
|
定義函式 | function<函式名> takes<參數表> returns <返回類型>// 參數不存在或不返回值時寫nothing ... return <返回值> endfunction
|
錯誤處理
語法錯誤:少寫一個字母,少空空格,或者把大寫寫成小寫等,都是寫JASS常犯的錯誤。一般來說,如果語法有問題,在存檔時電腦會顯示編譯錯誤的信息,並指出是哪一行有問題,依它的指示修正即可。不過當電腦指出某行有誤時,也可能是前面的幾行出了問題(範圍大概約1~5行),所以如果你怎么檢查都看不出某行到底錯在哪裡的時候,檢查前面的代碼。此外,某些錯誤會導致存檔時WE當掉,導致先前的辛苦付諸流水,所以請隨時存檔並儘量小心。
執行錯誤:一般會發生這種問題是指定的變數沒有賦值,當電腦找不到變數的值時,由於無法繼續執行,因此會無條件跳出目前的函式,如果該函式是要傳回值的函式,它將不會傳回值(也是無任何返回),因而可能導致調用它的函式也跳出。此外如除數為0也會造成類似的結果。
無限循環:一般這種事都是人為疏忽(忘了寫exitwhen,或是觸發的動作引發同一個觸發,而造成無限循環等),發生機會不大。不過一旦發生可是會讓War3當掉的喔。
常用系統
數據系統,顧名思義,就是用來儲存數據的。好的數據系統要求存得下、存得多、找得到、找得快。以下是Jass里常用的幾種數據系統。
1. 全局變數(global variables)
全局變數可以是單個的,也可以是數組形式,後者常被作為數據系統。全局變數的形式為:變數名[索引]。變數名以字母開頭、由數字字母和下劃線組成,索引是0-8191的整數。Jass里的變數一經申明為數組,數組大小永遠都是8192。它的優點是,只要知道索引,可以立即訪問到對應變數的值;缺點恰恰是,不知道索引就訪問不到。全局變數的聲明有兩種,一種是直接在變數里創建,另一種是寫在檔案頭,只是觸發編輯器里直接在觸發創建的全局變數會被系統添加udg_的前綴。
2. 遊戲快取(gamecache)
遊戲快取本來是用於在單機戰役的不同地圖之間傳遞數據的。但是由於有一些與
哈希表類似的非常好的特性,在1.24之前的版本里,遊戲快取一直扮演著哈希表的角色,returnbug+gamecache曾是最流行的數據系統,而ruturnbug也是利用的War3本身所擁有的bug。它的用法與哈希表差不多,只不過它的母鍵和子鍵卻不是整數,而是字元串。由於War3里字元串不可避免的泄漏,以及遊戲快取本身的效率問題,它還是遠遠不及
哈希表優秀的。該系統由於JASS的不安全因素被
hashtable所取代。(雖然這部分漏洞被修正,不過依然存在漏洞)
3. 哈希表(hashtable)
這個是1.24的新玩意兒,用SaveXxx和LoadXxx兩個系列的函式完成數據的儲存和讀取。哈希表的容量是無限的,而且什麼都可以存,即使存了很多東西以後,存取效率也不會變低。不僅如此,它的母鍵和子鍵可以是任意的整數,與GetHandleId函式配合,比
數組變數方便很多。一個示例:
call SaveInteger(udg_ht, GetHandleId(udg_unit), 'ABCD', 123456789) set i=LoadInteger(udg_ht, GetHandleId(udg_unit), 'ABCD') //此時i的值就是123456789
|
除了以上三種數據系統以外,還有location鏈、rect矩陣等等,當然你也可以自己編寫更適用的
hash算法,把這幾種數據系統相互組合,構造出適合你的、你需要的最佳數據系統。
哈希表語法結構:
a=SaveInteger(pv,key1, key2, b)
pv是一個表格
key1自定義數值
key2自定義的值
b是你的變數
b=LoadInteger(pv,key1,key2,a)