LV. 42
GP 1k

 ~輕鬆學JASS~ (入門篇)

樓主 Weber Weberkkk

===============

  ---(入門篇)---

===============


《4》函數構造

函數(function)是JASS運作的基本單位,其構造是:

function 函數名 takes 引數類型1 引數名1, 引數類型2 引數名2, ... returns 傳回值類型
  //*****************************
  //***    函數主體    ***
  //*****************************

  return 回傳值
endfunction


引數可以用來在各個function之間傳遞資料
GUI未開放這個功能,所以剛從GUI轉JASS的函數引數都是nothing(無)
但是在JASS你可以透過引數輕鬆的在各個觸發間傳遞資料

假設你A觸發裡面抓到一個部隊,而你要把這部隊的資料傳給觸發B

在GUI的做法是將部隊設為一個全域變數,並執行處發B

在JASS則是使用指令 call 函數B(部隊) 直接將部隊資料從函數A傳給函數B


呼叫函數:(自成一行時)
call 函數名(引數1,引數2,引數3...)


設定變數等於函數回傳值:(變數A的類型與函數回傳值類型必須相同
(A是整數,函數的回傳值就要是整數,A是部隊,函數的回傳值就要是部隊
set A = 函數名(引數1,引數2,引數3...)


多重呼叫:(作為函數A引數的函數B,回傳值類型必須等於函數A需要的引數
call 函數名(函數名B(B引數1,B引數2),A引數2,A引數3...)

 

《5》向前參照

  JASS都有所謂的向前參照特性,雖然所有的function都可以直接被呼叫出來運作,但只有後面的function可以呼叫前面的function,而前面的function如果要呼叫後面的function就會相對的困難許多,除了使用WE自學手冊提到的ExecuteFunc之外,也可以跟GUI一樣先做一個觸發器(包包)把要用的function裝起來,等需要的時候再拿來使用。

  JASS的排列方式,是照著觸發器的順序排列的,你把JASS寫在比較前面的觸發,儲存的時候這段JASS就會被排在前面,但這排列順序只針對WE剛讀取的檔案,之後新增的觸發JASS都會被排在最後方!


共用區(永久置頂)  → 共用區(永久置頂)
 觸發A       →  觸發A
 觸發B       →  觸發B
 觸發C       →  觸發C
 觸發D       →  觸發D


在A與B之間新增一條觸發:

共用區(永久置頂)  → 共用區(永久置頂)
 觸發A       →  觸發A
 觸發E       →  觸發B
 觸發B       →  觸發C
 觸發C       →  觸發D
 觸發D       →  
觸發E


關閉WE再重新載入地圖存檔:

共用區(永久置頂)  → 共用區(永久置頂)
 觸發A       →  觸發A
 觸發E       →  觸發E
 觸發B       →  觸發B
 觸發C       →  觸發C
 觸發D       →  觸發D


《6》觸發的簡化


showMediaClick("img") 請點選觀看圖片

這是一個非常基礎的GUI英雄技能觸發
直接判定英雄施展的技能類型,並啟動相對應的觸發
以GUI來說,已經是非常節省資源的做法

不過以JASS的角度來看,仍相當累贅呢!


function Trig_Skill_GO_Func001Func001Func001C takes nothing returns boolean
  if ( not ( GetSpellAbilityId() == 'AEfk' ) ) then
    return false
  endif
  return true
endfunction

function Trig_Skill_GO_Func001Func001C takes nothing returns boolean
  if ( not ( GetSpellAbilityId() == 'AOws' ) ) then
    return false
  endif
  return true
endfunction

function Trig_Skill_GO_Func001C takes nothing returns boolean
  if ( not ( GetSpellAbilityId() == 'AHbz' ) ) then
    return false
  endif
  return true
endfunction

function Trig_Skill_GO_Actions takes nothing returns nothing
  if ( Trig_Skill_GO_Func001C() ) then
    call TriggerExecute( gg_trg_Skill_A )
  else
    if ( Trig_Skill_GO_Func001Func001C() ) then
      call TriggerExecute( gg_trg_Skill_B )
    else
      if ( Trig_Skill_GO_Func001Func001Func001C() ) then
        call TriggerExecute( gg_trg_Skill_C )
      else
        call TriggerExecute( gg_trg_Skill_D )
      endif
    endif
  endif
endfunction

//=================================
function InitTrig_Skill_GO takes nothing returns nothing
  set gg_trg_Skill_GO = CreateTrigger( )
  call TriggerRegisterUnitEvent( gg_trg_Skill_GO, gg_unit_hpea_0000, EVENT_UNIT_SPELL_EFFECT )
  call TriggerAddAction( gg_trg_Skill_GO, function Trig_Skill_GO_Actions )
endfunction


這是剛從GUI轉成JASS的樣子,還真夠複雜的對吧!
初步的減化是把所有判定直接移回主要的 function 裡面
減少不必要的呼叫,也讓整個觸發變得更簡單明瞭


function Trig_Skill_GO_Actions takes nothing returns nothing
  if GetSpellAbilityId() == 'AEfk' then
    call TriggerExecute( gg_trg_Skill_A )
  else
    if GetSpellAbilityId() == 'AOws' then
      call TriggerExecute( gg_trg_Skill_B )
    else
      if GetSpellAbilityId() == 'AHbz' then
        call TriggerExecute( gg_trg_Skill_C )
      else
        call TriggerExecute( gg_trg_Skill_D )
      endif
    endif
  endif
endfunction

//=================================
function InitTrig_Skill_GO takes nothing returns nothing
  set gg_trg_Skill_GO = CreateTrigger( )
  call TriggerRegisterUnitEvent( gg_trg_Skill_GO, gg_unit_hpea_0000, EVENT_UNIT_SPELL_EFFECT )
  call TriggerAddAction( gg_trg_Skill_GO, function Trig_Skill_GO_Actions )
endfunction


接下來是把英雄施展的技能紀錄下來,以整數直接判定類型
並且把多層的if判定改寫為elseif


function Trig_Skill_GO_Actions takes nothing returns nothing
local integer ID = GetSpellAbilityId()

  if ID == 'AEfk' then
    call TriggerExecute( gg_trg_Skill_A )
  elseif ID == 'AOws' then
    call TriggerExecute( gg_trg_Skill_B )
  elseif ID == 'AHbz' then
    call TriggerExecute( gg_trg_Skill_C )
  else
    call TriggerExecute( gg_trg_Skill_D )
  endif

endfunction

//=================================
function InitTrig_Skill_GO takes nothing returns nothing
  set gg_trg_Skill_GO = CreateTrigger( )
  call TriggerRegisterUnitEvent( gg_trg_Skill_GO, gg_unit_hpea_0000, EVENT_UNIT_SPELL_EFFECT )
  call TriggerAddAction( gg_trg_Skill_GO, function Trig_Skill_GO_Actions )
endfunction


至此,觸發的簡化已經告一段落

如果這四個技能的觸發也已經純JASS化
你可以直接把這四個技能的初始化觸發清空

不加入事件、條件、動作,連觸發器都不用創造
function InitTrig_Skill_D takes nothing returns nothing

(清空,刪光光!)

endfunction

直接從主要的function去啟動技能的function
為了方便整理,也可以在裡面使用一些引數,直接傳送必要的數值過去
例如英雄技能等級、可造成傷害


function Trig_Skill_GO takes nothing returns boolean
local integer ID = GetSpellAbilityId()

  if ID == 'AEfk' then
    call Trig_Skill_A_Actions(引數1,引數2,引數3...)
  elseif ID == 'AOws' then
    call Trig_Skill_B_Actions(引數1,引數2,引數3...)
  elseif ID == 'AHbz' then
    call Trig_Skill_C_Actions(引數1,引數2,引數3...)
  else
    call Trig_Skill_D_Actions(引數1,引數2,引數3...)
  endif

  return false
endfunction

//=================================
function InitTrig_Skill_GO takes nothing returns nothing
  set gg_trg_Skill_GO = CreateTrigger( )
  call TriggerRegisterUnitEvent( gg_trg_Skill_GO, gg_unit_hpea_0000, EVENT_UNIT_SPELL_EFFECT )
  call TriggerAddCondition( gg_trg_Skill_GO, Condition(function Trig_Skill_GO) )
endfunction


因為不使用等待指令,所以能騙WE說這條function是Condition而不是Action
還記得第3篇提到的處理流程吧?

Condition會在Action之前被處理,而且效率比Action更快

所以針對不需等待的觸發
純JASS化之後可以把Action的東西全部移到Condition

當然在Condition裡面也可以用TimerStart做到更精準且節省資源的等待動作
不過這比較複雜,後面再做詳細介紹


板務人員:

3963 筆精華,10/04 更新
一個月內新增 0
歡迎加入共同維護。


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】