(xgm.guru/p/100/216551) - предыдущая тема.
Ранее хотел создать скилл в GUI, но послушав советы, понял, что лучшее будет написать его на Jass (да и давно пора его изучить, так как смогу создавать скиллы более гибко).
Написал код в Редакторе Триггеров. Скилл - все тот же сюрикен, летящий в определенную точку и возвращающийся назад, по пути дамажащий вражин. Но пока этот сюрикен даже лететь отказывается. Почитав статьи на форуме, да посмотрев всяких видосиков по теме jass, я понял, что я что-то не понял. А именно - как работают таймеры. Точнее, принцип понял, но как их засунуть за место привычного ожидания (Wait) - пока не разобрался. Это же касается использования хэш-таблицы, так как для таймера, она вроде как, маст хэв. Поэтому прошу хелпы, добрые люди. Вот код скилла, в нем есть неработающий таймер (он там один), и он отвечает за полет сюрикена в конечную точку. Прошу указать мне, где косяк.
З.Ы. - на всякий случай, прикрепляю саму карту.
function Trig_Suriken_Conditions takes nothing returns boolean
if ( not ( GetSpellAbilityId() == 'A01G' ) ) then
return false
endif
return true
endfunction
function InitTrig_Hash takes nothing returns nothing
set udg_Hash = InitHashtableBJ( )
endfunction
function Flyin takes nothing returns nothing
local timer ping = GetExpiredTimer()
local unit caster = LoadUnitHandle(udg_Hash,GetHandleId(ping),1)
local unit suriken = LoadUnitHandle(udg_Hash,GetHandleId(ping),2)
local location kursor = LoadLocationHandle(udg_Hash,GetHandleId(ping),3)
local location endfly = LoadLocationHandle(udg_Hash,GetHandleId(ping),4)
call SetUnitPositionLoc(suriken,PolarProjectionBJ(GetUnitLoc(suriken),10.00,AngleBetweenPoints(GetUnitLoc(suriken),endfly)))
call DestroyTimer(ping)
set ping = null
set caster = null
set suriken = null
set kursor = null
set endfly = null
endfunction
function Trig_Suriken_Actions takes nothing returns nothing
local timer ping = CreateTimer()
local integer countflyin = 1
local unit caster = GetSpellAbilityUnit()
local location kursor = GetSpellTargetLoc()
local location endfly = PolarProjectionBJ(GetUnitLoc(caster),2000.00,AngleBetweenPoints(GetUnitLoc(caster),kursor))
local real povorot = GetUnitFacing(caster)
local unit suriken = CreateUnitAtLoc(GetOwningPlayer(caster),'u001',PolarProjectionBJ(GetUnitLoc(caster),200.00,AngleBetweenPoints(GetUnitLoc(caster),kursor)),povorot)
loop
exitwhen countflyin == 100
if DistanceBetweenPoints(GetUnitLoc(suriken),endfly) >= 20 then
call SaveUnitHandle(udg_Hash,GetHandleId(ping),1,caster)
call SaveUnitHandle(udg_Hash,GetHandleId(ping),2,suriken)
call SaveLocationHandle(udg_Hash,GetHandleId(ping),3,kursor)
call SaveLocationHandle(udg_Hash,GetHandleId(ping),4,endfly)
call TimerStart(ping,0.10,true,function Flyin)
endif
set countflyin = countflyin + 1
endloop
call FlushChildHashtable(udg_Hash, GetHandleId(ping))
set ping = null
set caster = null
set suriken = null
set kursor = null
set endfly = null
endfunction
//===========================================================================
function InitTrig_Suriken takes nothing returns nothing
set gg_trg_Suriken = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Suriken, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Suriken, Condition( function Trig_Suriken_Conditions ) )
call TriggerAddAction( gg_trg_Suriken, function Trig_Suriken_Actions )
endfunction
Принятый ответ
Это достаточно неправильный код, везде BJ функции, location и т.д.
Сначала потренируйся просто переместить любого юнита в нужные тебе координаты.
Вместо location используй координаты "x" и "y"
К примеру:
Вычисление угла между координатами (в радианах)
a = Atan2(m.y - GetUnitY(u), m.x - GetUnitX(u))
//m.x и m.y это "конечная" точка, в которую юнит должен переместиться
Чтобы вычислить "x" смещение от места где стоит юнит с нужными тебе углом (угол "a" в радианах):
x = GetUnitX(u) + 2000. * Cos(a)
//Там где 2000. - это нужное тебе расстояние, можно записать как 2000.00 (без разницы)
Чтобы вычислить "y" смещение от места где стоит юнит с нужными тебе углом (угол "a" в радианах):
y = GetUnitY(u) + 2000. * Sin(a)
//Там где 2000. - это нужное тебе расстояние, можно записать как 2000.00 (без разницы)
Ну а потом
SetUnitX(u, x)
SetUnitY(u, y)
Далее уже можешь передвигать юнита каждые 0.03 секунды по 5 точек.
К примеру тот же код что выше - заранее вычисляешь им координаты где должен в итоге оказаться твой юнит
Или если у тебя уже есть готовые координаты, к примеру если юнит летит в точку кастования способности
И этим же кодом выше передвигаешь юнита по 5 точек каждые 0.03 секунды
А чтобы поймать окончание "передвижения" просто каждый раз сравнивай дистанцию, если она будет меньше 10, то уничтожай таймер и т.д
Там где 10 я имел ввиду кол-во точек на которое передвигается юнит + 5
К примеру тот же код что выше - заранее вычисляешь им координаты где должен в итоге оказаться твой юнит
Или если у тебя уже есть готовые координаты, к примеру если юнит летит в точку кастования способности
И этим же кодом выше передвигаешь юнита по 5 точек каждые 0.03 секунды
А чтобы поймать окончание "передвижения" просто каждый раз сравнивай дистанцию, если она будет меньше 10, то уничтожай таймер и т.д
Там где 10 я имел ввиду кол-во точек на которое передвигается юнит + 5
Вычисление дистанции между координатами
local real dx = m.x - x
local real dy = m.y - y
local real d = SquareRoot(dx * dx + dy * dy)
//Там где m.x и m.y - это конечные координаты
//А "x" и "y" - это текущие координаты юнита
`
ОЖИДАНИЕ РЕКЛАМЫ...
Чтобы оставить комментарий, пожалуйста, войдите на сайт.
Отредактирован Hodor
К примеру тот же код что выше - заранее вычисляешь им координаты где должен в итоге оказаться твой юнит
Или если у тебя уже есть готовые координаты, к примеру если юнит летит в точку кастования способности
И этим же кодом выше передвигаешь юнита по 5 точек каждые 0.03 секунды
А чтобы поймать окончание "передвижения" просто каждый раз сравнивай дистанцию, если она будет меньше 10, то уничтожай таймер и т.д
Там где 10 я имел ввиду кол-во точек на которое передвигается юнит + 5
Цыкл не нужен
В функции flyin после перемещения, пересохраняй позицию юнита suriken
Не видно действия запускающего функцию с инитиализацией хеша
для более плавного перемещения запускай таймер на 0.04сек
Насчет таймера - Borodach дал ответ