Можно ли как-нибудь периодически находить ближайший разрушаемый объект к точке X без постоянного перебора (лагает, объектов много) и без участия заранее созданных точек: точку Y мне необходимо создавать только тогда, когда ближайший объект уже найден.

Принятый ответ

Не давно показывал эту функцию
поиск декораций
function CheckDes takes nothing returns nothing
local destructable d=GetEnumDestructable()
if GetDestructableLife(d)>0 and cdb==false  and d!=null then
set cdb=TRUE
endif
set d=null
endfunction

function PCD takes real x,real y, unit u returns boolean//PointConteintDes
local rect r
local real d=50
set r=Rect( x - d*2, y - d*2, x + d*2, y +d*2 )
set cdb=false
call EnumDestructablesInRect(r,null,function CheckDes)
call RemoveRect(r)
set r=null
return cdb
endfunction
Я точно это проверял на карте в 1000 объектов у 4 источников одновременно, больше не было думаю условия одинаковые.. Но нужно будет переделать под ваши нужды в CheckDes мы по очереди перебираем все разрушаемые в нужно регионе, изначально функция создана для нахождения какой либо разрушаемого, но тут достаточно добавить пару глобалок на, темболее возле героя же будет не 500-1000 разрушаемых а например до 10, если это деревья
Obelick, если ещё какие либо ньюансы для нахождения этого близжайшего декора, мне легче показать как я себе представляю реализацию такой задачи, чем объяснить, но нужно больше исходных данных, особоенно волнуют вопросы
сколько может быть разрушаемых в радиусе 512 и какой интервал
quq_CCCP, а если не мемхаком, просто послать рубить деревья, а потом как то извлечь дерево записанное в приказе, хз на сколько это возможно GetDestructableOrder(), если ли такое вообще? но адрес в памяти точно такой имеется...
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
0
23
5 лет назад
0
Jack-of-shadow, да, верно. Чтобы компьютер захватывал сначала ближайшие клетки, а уже потом отдалялся от своей базы.
0
28
5 лет назад
0
как отсеивать в пике дудады, если условных пиков нет?
В фильтре пишешь условие, внутри которого и делаешь все необходимые действия, а codeAction скипаешь.
0
23
5 лет назад
0
PT153, для гуи нубов варианта получается нет?
0
28
5 лет назад
Отредактирован PT153
0
для гуи нубов варианта получается нет?
В JNGP должно быть такое, но лучше на JASS.

Я вот такое имею в виду.
function FilterFunct takes nothing returns boolean
    local destructable d = GetFilterDestructable()
    local integer T = GetDestructableTypeId(d)
    if T == ... then
        // ...
    elseif T == ... then
        // ...
    endif
    set d = null
    return false
endfunction

function SomeFunct takes rect r returns nothing
    call EnumDestructablesInRect(r, Filter(function FilterFunct), null)
endfunction

А вообще, предлагаю сделать так. Тем более, выполняется такое условие.
Точка X неподвижна.
Для каждого нужного объекта вычисляем ближайший деструктабл во время инициализации.
Детектим смерть деструктабла с помощью события на смерть виджета и условия, что деструктабл триггера не нулл. Пересчитываем для каждого объекта ближайший деструктабл.
При создании нового деструктабла для каждого объекта сравниваем его текущий ближайший деструктабл с новым. Если новый ближе, заменяем. Если нет, то ничего не меняем.
0
23
5 лет назад
0
Короче просидев вчера всю ночь и сегодня утро, так и не смог сделать ничего вразумительного. Попытался сделать по принципу поиска ближайшей дистанции: занес все точки и дудады в массив. Сравниваю дистанцию и нахожу минимальную. Вроде все работает, да не все. Дудадов очень много, цикл прерывается, не проходя через все.
Jack-of-shadow, я если честно не понял про твой пример. Точнее понял, но не понял, как реализовать. Допустим мы проходим по 200 дудадам, обрываем цикл, то как после его запустить и не проходить по уже пройденным декорациям?
0
25
5 лет назад
0
Obelick:
Делать небольшой рект, и смещать его вокруг точки. Тогда за раз будет обрабатывается не большое количество декора. А за 2 секунды можно безболезненно обработать огромные площади.
0
32
5 лет назад
0
Jack-of-shadow, 7 юнитов одновременно каждые 2 секунды пикают от 600 до 900 дуадов
Я до сих пор не могу поверить что в радиусе 500 от юнита может находится 600-900 дуадов
0
23
5 лет назад
0
Bergi_Bear, расстояние между клетками 512 ед. Я пикаю соответственно в большем радиусе.
0
30
5 лет назад
Отредактирован Clamp
0
Строишь короче такой Quadtree, заносишь в него все объекты, и те, что ищешь, и те, от которых ищешь, после чего простой триангуляцией по дереву реализуешь поиск.

Есть основания полагать, что всякие события "входит в область" и поиски ближайших обжей работают через Quadtree как раз нативно.
0
28
5 лет назад
Отредактирован PT153
0
Во время инициализации создаём все необходимые точки через Object.create(), затем после создания всех деструктаблов вызываем Object.findClosestDestForAll(). При создании нового деструктабла нужно вызвать Object.updateDestForAll(), а при смерти - Object.findClosestDestForAll(). Как ловить смерть я уже говорил.
Детектим смерть деструктабла с помощью события на смерть виджета и условия, что деструктабл триггера не нулл.
Код
function GetDistanceDestPoint takes destructable d, real x, real y returns real
    local real dx = GetDestructableX(d) - x
    local real dy = GetDestructableY(d) - y
    return SquareRoot(dx * dx + dy * dy)
endfunction

struct Object
    readonly static real StartDistance
    readonly static rect World
    private static boolexpr filter
    
    static thistype array entities
    readonly static integer top = -1
    
    real x
    real y
    readonly destructable d
    private real distance = StartDistance
    private integer index
    
    static method create takes real x, real y returns thistype
        local thistype this = allocate()
        set this.x = x
        set this.y = y
        set top = top + 1
        set entities[top] = this
        set index = top
        return this
    endmethod
    
    method onDestroy takes nothing returns nothing
        local integer i = index
        if i < top then
            set entities[i] = entities[top]
            set entities[i].index = i
        endif
        set top = top - 1
        set d = null
    endmethod
    
    method updateDest takes destructable d returns nothing
        local real dist = GetDistanceDestPoint(d, x, y)
        if dist > distance then
            set this.d = d
            set distance = dist
        endif
    endmethod
    
    static method updateDestForAll takes destructable d returns nothing
        local integer a = 0
        loop
            exitwhen a > top
            call entities[a].updateDest(d)
            set a = a + 1
        endloop
    endmethod
    
    private static method FilterFunc takes nothing returns boolean
        //local destructable t = GetFilterDestructable()
        //if GetDestructableTypeId(t) == 'ATtr' then
        //    call TransmittedObject.updateDest(t)
        //endif
        //set t = null
        call TransmittedObject.updateDest(GetFilterDestructable())
        return false
    endmethod
    
    private static thistype TransmittedObject
    
    method findClosestDest takes nothing returns nothing
        set TransmittedObject = this
        call EnumDestructablesInRect(World, filter, null)
    endmethod
    
    static method findClosestDestForAll takes nothing returns nothing
        local integer a = 0
        loop
            exitwhen a > top
            call entities[a].findClosestDest()
            set a = a + 1
        endloop
    endmethod
    
    private static method OnInit takes nothing returns nothing
        local rect r = GetWorldBounds()
        local real dx = GetRectMaxX(r) - GetRectMinX(r)
        local real dy = GetRectMaxY(r) - GetRectMinY(r)
        set StartDistance = SquareRoot(dx * dx + dy * dy) * 2.
        set World = r
        set r = null
        set filter = Filter(function thistype.FilterFunc)
    endmethod
endstruct
Я же верно понимаю, что деструктаблы не двигаются?
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.