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

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

Ответ
 
Xipxop
Круче варика, только c++!
offline
Опыт: 7,646
Активность:
Действия над всей группы, оптимальный способ
Все добрый вечер!
Делая свой скилл который должен в расстоянии от 300 до 350, должен пихнуть назад юнита.
Так вот, проблема в том, что мои знания реализации Пика всей группы, без лагов и без юзания глобальных переменных, на этом заканчиваются...
Код:
function Trig_TotemPitasenya_Timer takes nothing returns nothing
    local timer t=GetExpiredTimer()
    local integer h=GetHandleId(t)
    local unit totem=LoadUnitHandle(HASH, h, 1)
    local real x=GetUnitX(totem)
    local real y=GetUnitY(totem)
    local unit pick
    local group g=CreateGroup()
    local group g2=CreateGroup()
    local real xP; local real yP
    local real angle
    
    if(GetUnitState(totem, UNIT_STATE_LIFE)>0) then
        GroupEnumUnitsInRange(g, x, y, 350, function GroupBool)
        GroupEnumUnitsInRange(g2, x, y, 300, function GroupBool)
        GroupRemoveFromGroup(g, g2) //удаляет из одной группы другую групу
        DestroyGroup(g2)
        loop
            pick=GroupPickRandomUnit(g)
            exitwhen pick==null
            xP=GetUnitX(pick); yP=GetUnitY(pick)
            angle=bj_RADTODEG * Atan2(y - yP, x - xP)
            xP=xP + 1 * Cos(angle * bj_DEGTORAD); yP=yP + 1 * Sin(angle * bj_DEGTORAD)
            if !IsTerrainPathable(xP,yP, PATHING_TYPE_WALKABILITY) then
                SetUnitX(pick, xP); SetUnitY(pick, yP)
            endif
        endloop
    else
        DestroyTimer(t)
    endif
    
    DestroyGroup(g)
    g=null
    g2=null
    t=null
    pick=null
    totem=null
endfunction


Эта функция вызывается каждые 0.05 сек, таймером.
Как оптимизировать ту часть которая пикает всех игроков?
Конечно можно сделать так, чтобы действия над юнитами были занесены в отдельную функцию, но в ней я не буду иметь доступа к двум локальным переменным: x, y

Пожалуйста, скажите радикальный способ, без использования глобальных переменых! Если вы напишите на cJass, то можете немного объяснить.

И еще одно, если есть уже готовые успешные скилы, работающие с групами, то можете их привести в пример? или кинуть сам скил, буду рад изучить таковой!
Заранее благодарю!
Старый 29.09.2013, 22:39
HolyMoon
Hly shit!
offline
Опыт: 6,986
Активность:
Xipxop, что-нибудь типо
 local group tmp_group = CreateGroup()
 local unit tmp_unit = null
   call GroupEnumUnitsInRange(tmp_group, x, y, 350, function GroupBool)
   loop
      exitwhen CountUnitsInGroup(tmp_group) == 0
         set tmp_unit = FirstOfGroup(g)
         // actions
         call GroupRemoveUnit(tmp_group, tmp_unit)
   endloop
Старый 29.09.2013, 22:48
Xipxop
Круче варика, только c++!
offline
Опыт: 7,646
Активность:
блин, я ж забыл удалять юнита из группы...
Но всеравно кто знает способ по лучше чем этот?
Этот способ хоть и годный, но он как никак вызывает некие задержки
Старый 29.09.2013, 22:56
Hate
конь вакуумный
online
Опыт: 43,033
Активность:
он там вызывать задержки может если вы карту захламили и/или у вас там под несколько тысяч юнитов и/или у вас комп это калькулятор
Старый 29.09.2013, 23:12
DioD

offline
Опыт: 45,134
Активность:
function Trig_TotemPitasenya_Timer takes nothing returns boolean

inline GLOBAL static final group g = CreateGroup()

if FilterUnit() == null then
groupEnumUnitsInRange(g,x,y,300, function Trig_TotemPitasenya_Timer)
else
KillUnit(FilterUnit())
endif
return false
endfunction
Старый 30.09.2013, 12:17
Hanabishi
COOL STATUS
offline
Опыт: отключен
Что-то вы мутите непонятное. Глобальные переменные использовать можно и нужно. Зачем постоянно создавать и удалять группу, если можно использовать одну глобальную?
Если надо перебор группы в одной функции, то:
globals
    group myGr = CreateGroup()
endglobals


function SomeFunc takes nothing returns nothing
    local unit f
    
    call GroupEnumUnitsInRange(myGr, x, y, rad, null)
    set f = FirstOfGroup(myGr)
    
    loop
    exitwhen(f==null)
        //действия с юнитом f
        call GroupRemoveUnit(myGr, f)
        set f = FirstOfGroup(myGr)
    endloop
    
    call GroupClear(myGr)//для перестраховки удалённых из игры, в нашем случае можно и убрать
    
    set f = null
endfunction
Однако, перебор циклом не самый производительный вариант.
Старый 30.09.2013, 13:38
quq_CCCP
Я белый и пушистый!
offline
Опыт: 93,279
Активность:
Hanabishi, и чего все не юзайют for group ? Типа переменные локальные туда не передаются, да и пофиг, есть же темповые глобалки....
Старый 30.09.2013, 13:45
Hanabishi
COOL STATUS
offline
Опыт: отключен
quq_CCCP:
Hanabishi, и чего все не юзайют for group ? Типа переменные локальные туда не передаются, да и пофиг, есть же темповые глобалки....
Автор просил в одной функции, он получил. Для спелла метод пойдёт любой, главное без утечек сделать.
ForGroup тоже не самый быстрый, нужно делать через фильтр )
Старый 30.09.2013, 13:48
adic3x

offline
Опыт: 108,439
Активность:
exitwhen CountUnitsInGroup(tmp_group) == 0
set tmp_unit = FirstOfGroup(g)
actions
call GroupRemoveUnit(tmp_group, tmp_unit)
Изыди, Сатана!
    set tmp_unit = FirstOfGroup(g)
    exitwhen tmp_unit == null
    // actions
    call GroupRemoveUnit(tmp_group, tmp_unit)
Вариант на cJass:
for (unit u; UnitInRange(x, y, 350.)) { // Или UnitsInRange, точно не помню
    KillUnit (u);
}
ADOLF добавил:
ForGroup тоже не самый быстрый, нужно делать через фильтр )
Кстати наоборот, перебор циклом юнитов в группе быстрее, мы проводили исследования.

Отредактировано ADOLF, 10.03.2015 в 16:20.
Старый 30.09.2013, 14:03
Hanabishi
COOL STATUS
offline
Опыт: отключен
Кстати наоборот, перебор циклом юнитов в группе быстрее, мы проводили исследования.
Помнится от цикла отказался в силу ограничения количества итераций в варе. По производительности тут на самом деле разница между методами микроскопическая, при нынешних компьютерных мощах.
Старый 30.09.2013, 14:12
Hate
конь вакуумный
online
Опыт: 43,033
Активность:
это уже предпочтения на уровне "какой рукой"
Старый 30.09.2013, 21:12
Ответ

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

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

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

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



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