Алгоритм позволяющий отловить вход или выход из воды
Идея использовать цикл внутри каждого потока - 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 медленнее чем у таймера
Ред. Hodor
Если добавить ивент на вход до CreateRegion(), то он не будет работать.
Поэтому там нормально всё, триггеры после библиотеки инициализируются, значит и после CreateRegion()
CreateRegion() нельзя делать при объявлении глобалки, не знаю почему, но фаталит
Ред. nvc123
PT153, UrsaBoss, блок global предназначен для объявления переменных
в нём нельзя вызывать функции
это не только в jass
это в любом структурном яп так
Ред. Hodor
Тем более jass не совсем яп, это какой то костыльный скрипт, vJass хоть немного делает его похожим на ЯП
jass вполне нормальный структурный яп
если по твоему jass плохой яп то попробуй асм