Добавлен , опубликован
Способ реализации:
Версия Warcraft:
Алгоритм позволяющий отловить вход или выход из воды
Идея использовать цикл внутри каждого потока - nvc123
Обновление
Теперь построение региона происходит во время инициализации карты, а не после начала игры
+ алгоритм быстрее строит регион
Карта-пример прилагается
Время построения региона, при условии что вся карта будет заполнена водой:
64x64 - меньше секунды
128x128 - меньше секунды
256x256 - ~4 секунды
480x480 - ~15 секунд
Алгоритм в виде подключаемой библиотеки:
Событие на вход в воду:
function TriggerRegisterEnterWater takes trigger whichTrigger, boolexpr filter returns event
Событие на выход из воды:
function TriggerRegisterLeaveWater takes trigger whichTrigger, boolexpr filter returns event
cJass
library CustomRegion initializer Init
{
    define regionType = false //false - вода, true - земля
    
    private region CustomRegion;
    private float maxX;
    private float minX;
    private float maxY;
    private float minY;
    private float pointX;
    private float pointY;
    private bool b = true;
    
    public void Run()
    {
        int i = 0;
        loop
        {
            if( IsTerrainPathable(pointX, pointY, PATHING_TYPE_FLOATABILITY) == regionType )
            {
                RegionAddCell( CustomRegion, pointX, pointY );
            }
            
            pointY = pointY-32.;
            if( pointY < minY )
            {
                pointX = pointX-32.;
                pointY = maxY;
            }
            
            i++;
            
            if( pointX < minX )
            {
                b = false;
                break;
            }
            exitwhen( i == 5600 )
        }
        if( b )
        {
            ExecuteFunc("CustomRegion_Run");
        }
    }
    
    private void Init()
    {
        maxX = GetRectMaxX(bj_mapInitialPlayableArea);
        minX = GetRectMinX(bj_mapInitialPlayableArea);
        maxY = GetRectMaxY(bj_mapInitialPlayableArea);
        minY = GetRectMinY(bj_mapInitialPlayableArea);
        pointX = maxX;
        pointY = maxY;
        CustomRegion = CreateRegion();
        
        ExecuteFunc("CustomRegion_Run");
    }
    
    event TriggerRegisterEnterWater(trigger whichTrigger, boolexpr filter)
    {
        return TriggerRegisterEnterRegion( whichTrigger, CustomRegion, filter );
    }
    
    event TriggerRegisterLeaveWater(trigger whichTrigger, boolexpr filter)
    {
        return TriggerRegisterLeaveRegion( whichTrigger, CustomRegion, filter );
    }
}
vJass
library CustomRegion initializer Init
    globals
        private region CustomRegion
        private real maxX
        private real minX
        private real maxY
        private real minY
        private real pointX
        private real pointY
        private boolean b = true
    endglobals
    
    public function Run takes nothing returns nothing
        local integer i = 0
        loop
            if IsTerrainPathable(pointX, pointY, PATHING_TYPE_FLOATABILITY) == false then
                call RegionAddCell( CustomRegion, pointX, pointY )
            endif
            
            set pointY = pointY-32.
            if pointY < minY then
                set pointX = pointX-32.
                set pointY = maxY
            endif
            
            set i = i + 1
            
            if pointX < minX then
                set b = false
                exitwhen true
            endif
            exitwhen( i == 5600 )
        endloop
        if b then
            call ExecuteFunc("CustomRegion_Run")
        endif
    endfunction
    
    private function Init takes nothing returns nothing
        set maxX = GetRectMaxX(bj_mapInitialPlayableArea)
        set minX = GetRectMinX(bj_mapInitialPlayableArea)
        set maxY = GetRectMaxY(bj_mapInitialPlayableArea)
        set minY = GetRectMinY(bj_mapInitialPlayableArea)
        set pointX = maxX
        set pointY = maxY
        set CustomRegion = CreateRegion()
        
        call ExecuteFunc("CustomRegion_Run")
    endfunction
    
    function TriggerRegisterEnterWater takes trigger whichTrigger, boolexpr filter returns event
        return TriggerRegisterEnterRegion( whichTrigger, CustomRegion, filter )
    endfunction
    
    function TriggerRegisterLeaveWater takes trigger whichTrigger, boolexpr filter returns event
        return TriggerRegisterLeaveRegion( whichTrigger, CustomRegion, filter )
    endfunction
endlibrary
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
28
и никаких лагов
library CustomRegion initializer init{
    define regionType  = PATHING_TYPE_FLOATABILITY
    
    private region CustomRegion
    private float maxX
    private float minX
    private float maxY
    private float minY
    private float pointX
    private float pointY
    //debug
    private timer time;

    private void run(){
        timer t=GetExpiredTimer();
        int i=0;
        loop{
            if( IsTerrainPathable(pointX, pointY, regionType) == false ){
                RegionAddCell( CustomRegion, pointX, pointY )
            }
            
            pointY = pointY-32.
            if( pointY < minY ){
                pointX = pointX-32.
                pointY = maxY
            }
            
            i++;
            if(pointX < minX){
                DestroyTimer( t );
                //dubug
                BJDebugMsg(R2S(TimerGetElapsed(time)));
                BJDebugMsg("end");
                
                exitwhen true;
            }
            exitwhen (i==4000);
        }
    }

    private void init(){
        timer t=CreateTimer();
        maxX = GetRectMaxX(bj_mapInitialPlayableArea)
        minX = GetRectMinX(bj_mapInitialPlayableArea)
        maxY = GetRectMaxY(bj_mapInitialPlayableArea)
        minY = GetRectMinY(bj_mapInitialPlayableArea)
        pointX = maxX
        pointY = maxY
        CustomRegion = CreateRegion()
        //degug
        time=CreateTimer();
        TimerStart(time, 100500, false, null);
        
        TimerStart(t, 0.03, true, function run);
    }

}
480*480 полностью заполненную водой заносит за 18 секунд
без воды за 13
если на карте нету других действий выполняемых с самого начала при малом периоде (т.е. других подобных систем) то можно уменьшить период до 0,026
если допустимы незначительные лаги то можно увеличить количество операций с 4000 до 5000
18
nvc123 аааа, точно. Можно же было каждый поток по максимуму выжать, ща перезалью код
28
UrsaBoss, и не стоит использовать условия триггеров
на них есть множество ограничений
не только по количеству операций но и по времени работы
если всёже хочешь использовать триггеры то период не нужен т.к. можно использовать TriggerSleepAction(0)
он сбросит счётчик количества операций и будет ожидать пока не появится свободное процессорное время
таким образом лагов не будет вообще т.к. чем сильнее нагружен процессор тем медленнее будет работать система
но в замен скорость работы раза в 3 медленнее чем у таймера
library waitRegion initializer init{
    define regionType  = PATHING_TYPE_FLOATABILITY
    
    private region CustomRegion
    private float maxX
    private float minX
    private float maxY
    private float minY
    private float pointX
    private float pointY
    //debug
    private timer time;
    
    private void run(){
        int i=0;
        trigger t=GetTriggeringTrigger();
        loop{
            if( IsTerrainPathable(pointX, pointY, regionType) == false ){
                RegionAddCell( CustomRegion, pointX, pointY )
            }
            
            pointY = pointY-32.
            if( pointY < minY ){
                pointX = pointX-32.
                pointY = maxY
            }
            
            i++;
            exitwhen pointX < minX;
            if(i==5000){
                i=0;
                TriggerSleepAction(0);
            }
        }
        DestroyTrigger( t );
        //dubug
        BJDebugMsg(R2S(TimerGetElapsed(time)));
        BJDebugMsg("trigg end");
    }

    private void init(){
        trigger t=CreateTrigger();
        maxX = GetRectMaxX(bj_mapInitialPlayableArea)
        minX = GetRectMinX(bj_mapInitialPlayableArea)
        maxY = GetRectMaxY(bj_mapInitialPlayableArea)
        minY = GetRectMinY(bj_mapInitialPlayableArea)
        pointX = maxX
        pointY = maxY
        CustomRegion = CreateRegion()
        //degug
        time=CreateTimer();
        TimerStart(time, 100500, false, null);
        
        TriggerAddAction(t, function run);
        TriggerRegisterTimerEvent(t, 0, false)
    }
    

}
18
nvc123 в перезалитом ресурсе тебя указать как как автора оптимизированного кода?
21
Если зарегистрировать событие на вход в воду еще до инициализации системы, то когда система будет готова к использованию, триггер обновится или останется с недоднланным регионом?
18
ScopteRectuS библиотеки инициализируются раньше чем триггеры
18
ScopteRectuS:
UrsaBoss, но регион то не сразу генерируется.
нужно протестить, пока что не могу, я ресурс переоформляю
21
оптимизированная версия от nvc123 генерируется от 13 до 18 сек.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.