XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Академия: форум для вопросов> Jass
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Закрытая тема
 
Alibek
Choops
offline
Опыт: 12,699
Активность:
Помогите оптимизировать функцию
Тему создаю здесь, т.к. дело касается в основном jass
вобщем возникли несколько вопросов и проблем
1)почему моя функция выполняется в цикле только один раз, будто я использовал в конце return, да и вообще если использовать другую функцию с GetLastCreatedUnit(), то юнита нету в нем...как например в у меня в триггере юниту дается время 5 сек...но эта функция невыполняется
2)ну и конечно же эта функция необошлась без утечек, я так понимаю...я надеюсь вы поможете ее облегчить и оптимизировать
вобщем выкладываю мапу...в мапе тупо кликайте много-много раз esc
Прикрепленные файлы
Тип файла: w3x SnS(Alibek).w3x (18.0 Кбайт, 16 просмотров )
Старый 28.11.2009, 22:58
bee
vjass.optimizer
offline
Опыт: 16,615
Активность:
Alibek, зачем ты создаеш триггеры с периодическим событием? для этого есть таймеры
local timer t = CreateTimer()
local integer id = GetHandleId(t)

call SaveRealBJ(0.00, <номер ячейки>, id, <Глобалка хештаблицы>) // BJ Функция
call SaveReal(<Глобалка хештаблицы>, id, <номер ячейки>, 0.00) // Оптимизированная
...


call TimerStart(t, 0.03, true, function blablabla)

set t = null
GUIишные (т.е. BJ функции) и нативки различаются только местами аргументов.
если у тебя есть JNGP то нажми ЛКМ, зажав предворительно Ctrl
Старый 29.11.2009, 01:56
Alibek
Choops
offline
Опыт: 12,699
Активность:
Bee, понятно спс...но возникла еще одна проблема...
я ипользовал переодически триггер и сохронял все данные в этотже триггер
затем в действиях переодического триггера я выгружал данные так
local real x = LoadRealBJ(0, GetHandleId(GetTriggeringTrigger()), udg_SnS_HT)
теперь у меня таймер...как теперь сохронять данные?
Старый 29.11.2009, 08:45
RazArt

offline
Опыт: 11,197
Активность:
Alibek,
Код:
local timer t=GetExpiredTimer()
local real x = LoadReal(udg_SnS_HT, GetHandleId(t), 0)

Если я правильно вопрос понял..

А вообще выглядит примерно так:

Код:
function Explode takes nothing returns nothing
    local timer t=GetExpiredTimer() //Получаем таймер, вызвавший данную ф-цию
    local unit u=LoadUnitHandle(udg_Hash, GetHandleId(t),1) //Загружаем нужного нам юнита

    call ExplodeUnitBJ(u) //И взрываем его :)
    call FlushChildHashtable(udg_Hash, GetHandleId(t)) //Удаляем записи таймера

    call DestroyTimer(t) //Обнуляем переменные и “разрушаем” таймер
    set t=null
    set u=null
endfunction

function Trig_Explode_Actions takes nothing returns nothing
    local timer t=CreateTimer() //Создаём новый таймер
    local unit u=GetSpellAbilityUnit() //Заносим в переменную юнита-кастера

    set udg_Hash=InitHashtable() //Инициализируем хеш-таблицу, если ранее это действие не выполнялось
    call SaveUnitHandle(udg_Hash, GetHandleId(t), 1, u) //Сохраняем ссылку на юнита “внутри” таймера
    call TimerStart(t, 5.00, false, function Explode) //Запускаем таймер

    set t=null //Обнуляем переменные
    set u=null
endfunction
Старый 29.11.2009, 10:04
Alibek
Choops
offline
Опыт: 12,699
Активность:
RazArt, спс...получилось
а теперь ответьте...почему непашет функция в цикле???
Старый 29.11.2009, 10:45
RazArt

offline
Опыт: 11,197
Активность:
В каком цикле? Код давай :)
Старый 29.11.2009, 10:57
Alibek
Choops
offline
Опыт: 12,699
Активность:
RazArt, в мапе...триггер с событием отлавливания esc есть цикл...а в игре он создает только один снаряд
Старый 29.11.2009, 15:37
RazArt

offline
Опыт: 11,197
Активность:
-.- Кооооод
Старый 29.11.2009, 16:15
Alibek
Choops
offline
Опыт: 12,699
Активность:
RazArt, мля...
Код:
function Trig_Actions takes nothing returns nothing
    set bj_forLoopAIndex = 1
    set bj_forLoopAIndexEnd = 10
    loop
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
        set bj_lastCreatedUnit = CreateUnitAtLoc(Player(0), 'hpea', GetUnitLoc(gg_unit_hfoo_0000), 0.00)
        call SnS (bj_lastCreatedUnit, GetRandomReal(0, 360), GetRandomReal(10,750), 5, GetRandomReal(50,200))
        call UnitApplyTimedLifeBJ( 5.00, 'BTLF', GetLastCreatedUnit() )
        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop

//===========================================================================
function InitTrig_Trig takes nothing returns nothing
    set gg_trg_Trig = CreateTrigger(  )
    call TriggerRegisterPlayerEventEndCinematic( gg_trg_Trig, Player(0) )
    call TriggerAddAction( gg_trg_Trig, function Trig_Actions )
endfunction


Alibek добавил:
SnS эта та Функция...которая двигает снаряд

Alibek добавил:
т.е. тот который выше помогали оптимизировать
Старый 29.11.2009, 16:32
Alibek
Choops
offline
Опыт: 12,699
Активность:
мда вопще никто типа незнает причину...
вот код оптимизировал...посматрите можноли чтонибуть еще зделать сней?
Код:
function SnS_Actions takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit u = LoadUnitHandle(udg_SnS_HT, GetHandleId(t), 0)
    local real ti = LoadReal(udg_SnS_HT, GetHandleId(t), 1)
    local real h = LoadReal(udg_SnS_HT, GetHandleId(t), 2)
    local real r = LoadReal(udg_SnS_HT, GetHandleId(t), 3)
    local real fu = LoadReal(udg_SnS_HT, GetHandleId(t), 4)
    local real x = LoadReal(udg_SnS_HT, GetHandleId(t), 5)
    local real x0 = LoadReal(udg_SnS_HT, GetHandleId(t), 6)
    local real y = LoadReal(udg_SnS_HT, GetHandleId(t), 7)
    local real time = LoadReal(udg_SnS_HT, GetHandleId(t), 8)+1
    local real p = r / (20.00 * ti)    
    set x = x + ( x0 / (ti*20.00 / 2.00) )
    set y =(-1.00*(x*x)) + h
    call SetUnitPositionLoc( u, Location(GetLocationX(GetUnitLoc(u)) + p * Cos(fu * bj_DEGTORAD), GetLocationY(GetUnitLoc(u)) + p * Sin(fu * bj_DEGTORAD)) )
    call SetUnitFlyHeight( u, y, 0.00 )
    call SaveReal( udg_SnS_HT, GetHandleId(t),5, x )
    call SaveReal( udg_SnS_HT, GetHandleId(t),7, y )
    call SaveReal( udg_SnS_HT, GetHandleId(t),8, time )
    if time >= ti*20 or (GetUnitState(u, UNIT_STATE_LIFE) <= 0) == true then
       call FlushChildHashtable( udg_SnS_HT, GetHandleId(t))
       call DestroyTimer(t)
    endif
    set t = null
    set u = null
endfunction

function SnS takes unit u, real ti, real h, real r, real fu returns nothing
    local timer t = CreateTimer()
    local real x = SquareRoot(h)*-1
    local real x0 = SquareRoot(h)
    local real y = 0
    local real time = 0
    call TimerStart( t, 0.05, true, function SnS_Actions )
    call SaveUnitHandle( udg_SnS_HT, GetHandleId(t),0,u )
    call SaveReal( udg_SnS_HT, GetHandleId(t),1, ti )
    call SaveReal( udg_SnS_HT, GetHandleId(t),2, h )
    call SaveReal( udg_SnS_HT, GetHandleId(t),3, r )
    call SaveReal( udg_SnS_HT, GetHandleId(t),4, fu )
    call SaveReal( udg_SnS_HT, GetHandleId(t),5, x )
    call SaveReal( udg_SnS_HT, GetHandleId(t),6, x0 )
    call SaveReal( udg_SnS_HT, GetHandleId(t),7, y )
    call SaveReal( udg_SnS_HT, GetHandleId(t),8, time )
    set t = null
    set u = null
endfunction
Старый 29.11.2009, 22:16
Killer574
Временно присутствующий.
offline
Опыт: 3,373
Активность:
Alibek, например оптимизировать создание сотен локаций в строке
call SetUnitPositionLoc( u, Location(GetLocationX(GetUnitLoc(u)) + p * Cos(fu * bj_DEGTORAD), GetLocationY(GetUnitLoc(u)) + p * Sin(fu * bj_DEGTORAD)) )
Старый 29.11.2009, 23:06
bee
vjass.optimizer
offline
Опыт: 16,615
Активность:
Alibek, привыкай быть профессионалом, используй перемещение с помощью x / y.
call SetUnitX ( воин , x )
call SetUnitY ( воин , y )
Старый 29.11.2009, 23:42
Enein
Silenced by ZlaYa1000
offline
Опыт: 43,453
Активность:
привыкай быть профессионалом, используй перемещение с помощью векторов
Старый 29.11.2009, 23:45
Alibek
Choops
offline
Опыт: 12,699
Активность:
у меня
call SetUnitPositionLoc( u, Location(GetLocationX(GetUnitLoc(u)) + p * Cos(fu * bj_DEGTORAD), GetLocationY(GetUnitLoc(u)) + p * Sin(fu * bj_DEGTORAD)) )
значит если заменять call SetUnit то будет так?
call SetUnitX ( u , GetLocationX(GetUnitLoc(u)) + p * Cos(fu * bj_DEGTORAD) )
call SetUnitY ( u , GetLocationY(GetUnitLoc(u)) + p * Sin(fu * bj_DEGTORAD) )
или както подругому...вопщем скажите как будет выглядеть для моего случая...услышу ответ и тему можно закрыть
Старый 01.12.2009, 20:34
ScorpioT1000
Работаем
online
Опыт: отключен
так.
Старый 01.12.2009, 20:43
ShadoW DaemoN

offline
Опыт: 37,078
Активность:
Alibek, ну очевидно код не оптимизирован:
  1. Если занести значение GetHandleId(t) в переменную, можно неплохо сэкономить на вызовах функции.
  2. Так как GetExpiredTimer() вызывается всего два раза, в локальную переменную записывать не обязательно.
  3. Создавать локальные переменные, которые используются 1 раз - моветон.
  4. GetWidgetLife(u) чуть быстрее, чем GetUnitState(u, UNIT_STATE_LIFE).
  5. Если в функцию SnS параметр fu поступает в градусах, то почему бы сразу не перевести его в радианы, чтобы не делать два лишних умножения в таймере.
  6. Локации использовать нельзя. Нигде. Разве что для GetLocationZ(loc). И то, пока близзы не добавят аналог этой функции без локаций.
  7. Для перемещения дамми-юнитов, перемещения на малых расстояниях, или перемещения без необходимости проверки на пафинг - используй SetUnitX, SetUnitY вместо SetUnitPosition.
  8. Опять же, ti в обработчике таймера умножается 3 раза на 20, лучше сразу умножить на 20.
  9. Зачем сохранять в хеш-таблицу значение y, если оно нигде не используется, а вычисляется в обработчике таймера?
  10. Если в обработчике fu не изменяется, то, я думаю, было бы неплохо сохранить значения синуса и косинуса этого угла.
После всех манипуляций, код будет примерно таким:
function SnS_Actions takes nothing returns nothing
    local integer hid = GetHandleId(GetExpiredTimer())
    local unit u    = LoadUnitHandle(udg_SnS_HT, hid, 0)
    local real ti   = LoadReal(udg_SnS_HT, hid, 1)
    local real r    = LoadReal(udg_SnS_HT, hid, 3) / ti
    local real x    = LoadReal(udg_SnS_HT, hid, 5) + (LoadReal(udg_SnS_HT, hid, 6) / (ti / 2.0))
    local real time = LoadReal(udg_SnS_HT, hid, 8) + 1

    call SetUnitX(u, GetUnitX(u) + r * LoadReal(udg_SnS_HT, hid, 4))
    call SetUnitY(u, GetUnitY(u) + r * LoadReal(udg_SnS_HT, hid, 7))
    call SetUnitFlyHeight(u, (-1.0 * (x*x)) + LoadReal(udg_SnS_HT, hid, 2), 0.0)

    call SaveReal(udg_SnS_HT, hid, 5, x)
    call SaveReal(udg_SnS_HT, hid, 8, time)
    set u = null

    if (time >= ti) or (GetWidgetLife(u) <= 0.405) then
        call FlushChildHashtable(udg_SnS_HT, hid)
        call DestroyTimer(GetExpiredTimer())
    endif
endfunction

function SnS takes unit u, real ti, real h, real r, real fu returns nothing
    local timer   t   = CreateTimer()
    local integer hid = GetHandleId(t)
    call TimerStart(t, 0.05, true, function SnS_Actions)
    call SaveUnitHandle(udg_SnS_HT, hid, 0, u)
    call SaveReal(udg_SnS_HT, hid, 1, ti * 20.0)
    call SaveReal(udg_SnS_HT, hid, 2, h)
    call SaveReal(udg_SnS_HT, hid, 3, r)
    call SaveReal(udg_SnS_HT, hid, 4, Cos(fu * bj_DEGTORAD))
    call SaveReal(udg_SnS_HT, hid, 5, SquareRoot(h) * -1)
    call SaveReal(udg_SnS_HT, hid, 6, SquareRoot(h))
    call SaveReal(udg_SnS_HT, hid, 7, Sin(fu * bj_DEGTORAD))
    call SaveReal(udg_SnS_HT, hid, 8, 0)
    set t = null
endfunction
Старый 02.12.2009, 08:09
Alibek
Choops
offline
Опыт: 12,699
Активность:
ShadoW DaemoN, черт Гениально
благодарен бесконечно
Тему к костям мамонта
Старый 02.12.2009, 16:04
Закрытая тема

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 23:07.