定義自己的函數

AngleBetweenPointsXY

還記得前面做過的範例嗎?

function Trig_Compound_Curse_Actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local unit target = GetSpellTargetUnit()
    local unit hiddencaster = CreateUnit( GetOwningPlayer(caster), 'o000', GetUnitX(caster), 下行接續
        GetUnitY(caster), 0.0 )
    call ShowUnit( hiddencaster, false )
    call SetUnitFacingToFaceUnitTimed( hiddencaster, target, 0 )
    call UnitAddAbility( hiddencaster, 'A003' )
    call UnitAddAbility( hiddencaster, 'A005' )
    call UnitAddAbility( hiddencaster, 'A004' )
    call UnitAddAbility( hiddencaster, 'A006' )
    call IssueTargetOrder( hiddencaster, "slow"      , target )
    call IssueTargetOrder( hiddencaster, "faeriefire", target )
    call IssueTargetOrder( hiddencaster, "cripple"   , target )
    call IssueTargetOrder( hiddencaster, "curse"     , target )
    //set caster = null
    //set target = null
    //set hiddencaster = null
endfunction

其實SetUnitFacingToFaceUnitTimed也 挺囉嗦,我們可以根據裡面用到的AngleBetweenPoints,自己仿製一個AngleBetweenPointsXY函數放在共用區,利用傳點在一開始就讓隱藏部隊的方向正確。

還記得「共用區」在哪裡嗎?……看來十之八九忘了,這裡再講一次,一定要記得喔:
自定函數

以下是修改後的結果:

function AngleBetweenPointsXY takes real X1, real Y1, real X2, real Y2 returns real
    return bj_RADTODEG * Atan2( Y2 - Y1, X2 - X1 )
endfunction
function Trig_Compound_Curse_Actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local unit target = GetSpellTargetUnit()
    local unit hiddencaster = CreateUnit( GetOwningPlayer(caster), 'o000', GetUnitX(caster), 下行接續
        GetUnitY(caster), AngleBetweenPointsXY( GetUnitX(caster), GetUnitY(caster), GetUnitX(target), 下行接續
        GetUnitY(target) ) )
    call ShowUnit( hiddencaster, false )
    call UnitAddAbility( hiddencaster, 'A003' )
    call UnitAddAbility( hiddencaster, 'A005' )
    call UnitAddAbility( hiddencaster, 'A004' )
    call UnitAddAbility( hiddencaster, 'A006' )
    call IssueTargetOrder( hiddencaster, "slow"      , target )
    call IssueTargetOrder( hiddencaster, "faeriefire", target )
    call IssueTargetOrder( hiddencaster, "cripple"   , target )
    call IssueTargetOrder( hiddencaster, "curse"     , target )
    //set caster = null
    //set target = null
    //set hiddencaster = null
endfunction 

不過這樣一來CreateUnit那列會變得很長,所以是否這麼做還是看個人習慣。

CreateHiddenCaster

//如果不特意使隱藏施法者面向哪個目標,target可以填入null
//例如: call CreateHiddenCaster( GetTriggerUnit(), null )
function CreateHiddenCaster takes unit caster, unit target returns unit
    local integer HIDDEN_CASTER_ID = 'o000'
    local real X1 = GetUnitX(caster)
    local real Y1 = GetUnitY(caster)
    local real X2 = GetUnitX(target)
    local real Y2 = GetUnitY(target)
    return CreateUnit( GetOwningPlayer(caster), HIDDEN_CASTER_ID, X1, Y1, bj_RADTODEG*Atan2(Y2-Y1,X2-X1) )
endfunction
function Trig_Compound_Curse_Actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local unit target = GetSpellTargetUnit()
    local unit hiddencaster = CreateHiddenCaster( caster, target )
    call ShowUnit( hiddencaster, false )
    call UnitAddAbility( hiddencaster, 'A003' )
    call UnitAddAbility( hiddencaster, 'A005' )
    call UnitAddAbility( hiddencaster, 'A004' )
    call UnitAddAbility( hiddencaster, 'A006' )
    call IssueTargetOrder( hiddencaster, "slow"      , target )
    call IssueTargetOrder( hiddencaster, "faeriefire", target )
    call IssueTargetOrder( hiddencaster, "cripple"   , target )
    call IssueTargetOrder( hiddencaster, "curse"     , target )
    //set caster = null
    //set target = null
    //set hiddencaster = null
endfunction

DistanceBetweenPointsXY

其實和前面的AngleBetweenPointsXY大同小異,不過實用度更高,因為使用純JASS很容易遇到計算距離的問題:

function DistanceBetweenPointsXY takes real x1, real y1, real x2, real y2 returns real
    return SquareRoot((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2))
endfunction

這邊附上blizzard.j的函數,這個函數就是參考它做出來的:

function DistanceBetweenPoints takes location locA, location locB returns real
    local real dx = GetLocationX(locB) - GetLocationX(locA)
    local real dy = GetLocationY(locB) - GetLocationY(locA)
    return SquareRoot(dx * dx + dy * dy)
endfunction

MoveUnitDA

依照向量移動一個部隊,如果常做拋擲、擊退,或者常使用隱藏部隊充當動畫時會很常用:

function MoveUnitDA takes unit U, real dist, real angle returns nothing
    //call SetUnitPathing( U, false )
    call SetUnitPosition( U, GetUnitX(U) + dist * Cos(angle * bj_DEGTORAD), GetUnitY(U) + 下行接續
        dist * Sin(angle * bj_DEGTORAD) )
    //call SetUnitPathing( U, true )
endfunction

附上blizzard.j的函數,這個函數主要是參考它做出來的:

function PolarProjectionBJ takes location source, real dist, real angle returns location
    local real x = GetLocationX(source) + dist * Cos(angle * bj_DEGTORAD)
    local real y = GetLocationY(source) + dist * Sin(angle * bj_DEGTORAD)
    return Location(x, y)
endfunction 

MoveUnitDAWithPathing

依照向量移動一個部隊,計算碰撞體積,並且傳回是否碰撞:

function MoveUnitDAWithPathing takes unit U, real dist, real angle returns boolean
    local real COLLISION_CHECK_RANGE = 5.0
    local real x = GetUnitX(U)
    local real y = GetUnitY(U)
    call SetUnitPosition( U, x + dist * Cos(angle * bj_DEGTORAD), y + dist * Sin(angle * bj_DEGTORAD) )
    if DistanceBetweenPointsXY( GetUnitX(U), GetUnitY(U), x, y ) > COLLISION_CHECK_RANGE then
        call SetUnitPosition( U, x, y )
        return true
    endif
    return false
endfunction
綜合教學/jass入門教學/a4.定義函數.txt · 上一次變更: 2007年11月11日 3:16 pm 來自 wasabi
www.chimeric.de Creative Commons License Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0