jass触发器
??????????????????
? ? ? ? 好吧,我們開始接觸jass中的觸發器吧。
? ? ? ? 早在開篇我就提過,war3中的對象都是用handle標識的。觸發器也不例外。
? ? ? ? 一個觸發器變量僅僅存放了標識觸發器的handle,而不是觸發器的真正數據。
? ? ? ? 理解這個對于我們的jass相當重要。
回想WE中的觸發器都由什么構成?
對了,就是事件,環境,動作三部分。
? ? ? ? 在WE中,把三部分放到一起,方便我們設計觸發器。而在jass中,三部分不必在同一地方,非常的靈活。
1.首先,得創建一個觸發器對象。
? ? ? ? 要注意的是創建觸發器對象并不是聲明一個觸發器變量——那該死的trigger變量僅僅是一個句柄變量。創建觸發器對象的函數war3已經封裝好了,是CreateTrigger 直接用就行了,不需要任何參數,它返回一個trigger句柄,你可以用一個trigger變量來存放,也可以不存放。不管你存不存放,它都已經在內存中創建好了。
? ? ? ? 當然,沒有任何的參數,你一定會奇怪,觸發器的事件,環境,動作到哪里去了。
? ? ? ? 不要急,先前就說過,觸發器的設計在jass中是可以分開的;我們先創建一個空的觸發器;以后再添加它的事件,動作也是可以的。
2.在jass中給觸發器添加事件是通過調用相應的接口函數(API)來實現的,而且war3把它叫做注冊事件函數。
? ? ? 這種函數不只一個,有很多,不同類型的事件有不同的注冊函數。這讓jass寫觸發器的人很麻煩。
? ? ? 我介紹一種簡單的方法,可以避開自己去找哪個事件對應哪個函數:
? ? ? ? ? ? ? 用WE中的觸發編輯器,把你要的事件添加好之后,再把觸發器轉化為文本。就可以清楚的看到事件是該怎么注冊的。
? ? ? ? ? ? ? 到jassshoppro中查看這些注冊函數,你會發現它們有個共同點,第一個參數都是trigger變量,即觸發器句柄。這表示把事件注冊到哪個觸發器上面。我們在為一個觸發器注冊事件時,一定要保證這個參數是我們要設計的那個觸發器的句柄,不然就會注冊錯。
3.好吧,事件注冊完了,輪到環境和動作了。
? ? ? ? 為什么把他們并到一塊呢?
? ? ? ? 因為它們有很多共同點:
? ? ? ? ? ? ? 1>首先他們的注冊函數只有一個。你此時肯定會想到WE中的條件和動作是那么的多;
? ? ? ? ? ? ? 2>其次,他們注冊的東西不是一個對象了,而是一個函數。
? ? ? ? 這下能想通剛才的困惑了吧?
? ? ? ? 環境注冊函數把一個條件函數注冊到觸發器。動作注冊函數把動作函數注冊到觸發器。
? ? ? ? 這里以動作為例就不講條件了。條件函數的要求是返回值類型為boolean。
? ? ? ? 注冊分先后,觸發器觸發時,動作函數的運行先后也確定了,和你的注冊順序是一樣的。在jass下注冊動作一般只注冊一個動作函數。在那個動作函數里把所有的動作和判斷都完成,我們還推薦你不要注冊條件,而是把條件判斷寫到動作函數里。
? ? ? ? 當然僅僅是對于靜態的觸發器而言,如果你的觸發器需要不時的增加和減少條件動作,那么你不得不多寫幾個函數了。
? ? ? ? 這種動態的觸發器只是聽說過和設想過,往往寫成jass的只有很簡單的觸發了。
下面介紹一下jass下觸發器的原理:
? ? ? ? 當一個事件注冊到觸發器后,每當發生該事件war3都會創建一個線程運行該觸發器的條件函數,一旦條件函數返回假,線程就停止運行。
? ? ? ? 如果條件函數返回真,則運行下一個條件函數。直到所有的條件函數返回值都是真時運行動作函數。
? ? ? 這時觸發器的觸發計數器加一。接著是其他的動作函數。記住,運行下一個動作函數是要等待上一個返回的。
下面講觸發器中最重要的部分:觸發資源。
? ? ? ? 為觸發器注冊的事件往往不是詳細的事件,而是一個籠統的事件。比如說“一個單位進入某個區域” ,雖然區域指定了,但是單位沒有指定,任何單位進入該區域我們的事件都會觸發。我們怎么能知道進入區域的那個單位,是不是我們要等它進入的那個單位呢?
? ? ? ? war3在為觸發器創建線程時,同時也創建了線程的全局資源(你可以理解為全局變量),之所以叫全局資源而不叫全局變量,是因為我們不能像訪問變量一樣訪問它們,它們被要求是只讀的;如果弄成全局變量我們很有可能錯誤的對它進行寫操作,所以war3把它們設計成了只能用函數讀取值的資源。
下面是幾個常見的觸發器資源讀取API(接口)
GetTriggerPlayer()返回觸發事件的玩家
GetTriggingTrigger()返回當前觸發器的句柄
還有更多,它們和WE中的要求變量時可選的“功能”有一樣的效果。當然你只能在相應的觸發器下面使用相應的資源讀取API,不同事件的觸發器總能有一些相同命名的資源。
? ? ? 你如果要了解更多資源,請使用jassShopPro。
? ? ? 至此war3 jass最基本的東西算是講完了
八、過濾器
? ? ? ? 對不起,這個我也不太會,但是它是用Jass寫(群殺)(光環)技能的重要工具。如果有人會這個,麻煩帖一下。
高級運用:
一、丟棄垃圾全局變量:我們打開一個用WE做的圖可以看見全局變量有很多。用JassShopPro檢查一下,發現這些變量我們根本就沒調用過,說明是垃圾變量,這些變量大都是一些句柄變量,用來保存我們在地圖上放置的單位,方便觸發編輯器中調用。很多沒用到的變量占用了資源,學過了JASS應該知道怎么辦吧,記住:句柄變量不是對象,一個對象沒有句柄變量也能存在。當一個對象創建完畢,不需要句柄變量時就可以
對句柄變量賦值另一個句柄;典型的用法是在觸發器的設計上,當我們設計觸發器時,必須有設計中的觸發器對象的句柄,
設計完成后,就不需要該句柄了,觸發器能自己去運行,如
jass:??Copy code
local trigger t
? ? ? set t=CreateTrigger()
? ? ? call TriggerRegisterEvent()
? ? ? call TriggetAddAction()
? ? ? set t=CreateTrigger()
? ? ? call TriggerRegisterEvent()
? ? ? call TriggetAddAction()
//...
能理解嗎?這一次不能理解我也不會解釋了。
二、動作函數
? ? ? ? 如果叫你用WE的觸發器編輯器和jass來完成觸發器的動作部分,你會選擇JASS嗎?
? ? ? ? 在JASS里面,沒有別扭的循環數A,循環數B。在JASS里面判斷條件比在觸發編輯器中找條件要方便得多,如果你用過。
? ? ? ? 另外你可以在動作函數里面寫一些資源,如數組的string,這是觸發編輯器絕不可能辦到的。
三、讀圖線程和觸發線程
? ? ? ? main函數開始的線程是讀圖線程,讀圖的時候運行。
? ? ? ? 觸發動作函數開始的線程是觸發線程。
? ? ? ? 讀圖線程負責初始化全局變量,注冊觸發器,創建對象。在讀圖線程中的交互式操作無效。如顯示消息,對話框等等。
? ? ? ? 通常至少有一個觸發器在讀圖線程中被注冊。一般情況下觸發器都由讀圖線程注冊。如果你懂你可以在觸發線程中注冊另一個觸發器或修改本身。
四、關于GetLocalPlayer()
? ? ? ? 這個函數很簡單。返回一個玩家。
? ? ? ? 你需要理解jass腳本在war3中的執行方式:多終端同步執行,也就是說jass腳本不是只在建主機(OP)的那個機器上運行,而是所有的終端都在運行,終端之間的全局變量通常是完全一致的。
? ? ? ? 這個函數的用法就是自己去理解吧,真難表述!后悔沒學好語文。通常
jass:??Copy code
if GetTriggerPlayer()==GetLocalPlayer() then
? ? ? call action()
endif
這樣就能節約資源,要掉線也只是他一個掉,不會出現主機掉的情況。
我d發現:
1.RemoveUnit(null)這個函數調用不會被認為是錯誤,運行時也不會導致程序退出。但它讓玩家不能使用UI鍵,而只能使用鼠標。
2.UnitRemoveAbility可以刪除單位的基本技能如'Aatk'攻擊,'Amov'移動,但不能添加這些技能,其他的技能不存在此問題。
總結
- 上一篇: ubuntu-20.04.3-live-
- 下一篇: Visual Paradigm 教程[U