Алгоритм позволяющий отловить вход или выход из воды
Идея использовать цикл внутри каждого потока - nvc123
Обновление
Теперь построение региона происходит во время инициализации карты, а не после начала игры
+ алгоритм быстрее строит регион
+ алгоритм быстрее строит регион
Карта-пример прилагается
Время построения региона, при условии что вся карта будет заполнена водой:
64x64 - меньше секунды
128x128 - меньше секунды
256x256 - ~4 секунды
480x480 - ~15 секунд
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
Ред. nvc123
чтобы не приходилось копировать код с карты на карту а просто прописать
include "enter_water.j"
и заяви на публикацию
есть же таймеры
и можно просто в 1 потоке циклом всё сделать
без периодического триггера
из за периодического триггера так долго и работает
Ред. Hodor
А насчет loop и потока - я с этого и начинал, далее благополучно варкрафт завершал поток из за перегрузки, примерно на 750 цикле
nvc123 +когда я уничтожал таймер, то появлялся баг и он тупо прогонял if( IsTerrainPathable(pointX, pointY, regionType) == false ) по 10-20 раз, я уже с того времени переделал код, через 20-30 минут попробую переделать на таймерах
nvc123 а ещё после loop'ов, я сделал рекурсию через ExecuteFunc как аналог loop, но в этом случае варкрафт просто вылетел без ошибок во время инициализации
Мне кажется лучше давать триггеру ивенты чем вручную в глобалках создавать массив из таймеров по отдельности (т.к если создать таймеры при инициализации, то будет фриз на несколько секунд)
1 достаточно
Ред. Hodor
будет пол часа лепить регион
периода 0,03 вполне достаточно
и толку от многих таймеров?
всеравно они последовательно выполняются
причём обработка самих таймеров тратит дополнительное процессорное время
1 таймер с периодом 0,03 работает быстрее чем твоя система
без воды за 13
если на карте нету других действий выполняемых с самого начала при малом периоде (т.е. других подобных систем) то можно уменьшить период до 0,026
если допустимы незначительные лаги то можно увеличить количество операций с 4000 до 5000
Ред. nvc123
на них есть множество ограничений
не только по количеству операций но и по времени работы
если всёже хочешь использовать триггеры то период не нужен т.к. можно использовать TriggerSleepAction(0)
он сбросит счётчик количества операций и будет ожидать пока не появится свободное процессорное время
таким образом лагов не будет вообще т.к. чем сильнее нагружен процессор тем медленнее будет работать система
но в замен скорость работы раза в 3 медленнее чем у таймера