Corona / Box2D обнаруживают столкновения с неподвижными статическими объектами - PullRequest
3 голосов
/ 08 октября 2011

Из соображений публикации приведу простую версию того, что я пытаюсь сделать.

На экране у меня есть простой круговой объект, который статичен и не двигается. Пользователь может затем перетащить прямую линию. Если линия пройдет через этот круг, я надеюсь, что событие столкновения будет запущено.

Похоже, что если один из объектов не движется, столкновение никогда не обнаруживается. Могу ли я обнаружить столкновение при прорисовке линии?

Событие столкновения

function onHit(e)
    print("hit");
end
Runtime:addEventListener("collision", onHit)

Событие касания

local startX = 0;
local startY = 0;
local endX = 0;
local endY = 0;

function onTouch(e)
    if(e.phase == "began") then
        startX = e.x
        startY = e.y
    elseif(e.phase == "moved") then
        endX = e.x
        endY = e.y
    elseif(e.phase == "ended") then
        local line = display.newLine(startX, startY, endX, endY)
        line:setColor(100, 100, 100)
        line.width = 2
        physics.addBody(line, "static", {   })
    end
end
Runtime:addEventListener("touch", onTouch)

Создать круг

local c = display.newCircle(50, 50, 24)
physics.addBody(c, "static", { radius = 24 })

Ответы [ 2 ]

1 голос
/ 09 октября 2011

Эта страница из документации Corona SDK описывает свойство bodyType примерно на полпути вниз по странице. При описании «статичных» тел говорится (мой акцент):

статические тела не двигаются, а не взаимодействуют друг с другом ; Примерами статических объектов могут быть земля или стены автомат для игры в пинбол.

Это означает, что один из объектов должен быть чем-то отличным от static.

Вот идея, хотя я сам ее не пробовал: (См. update ниже.) Сделайте строку dynamic при первом создании. Установите его на static через несколько миллисекунд, используя функцию timer.performWithDelay. Если в это время происходит столкновение, вы будете знать, что у вас есть перекрытие, и можете немедленно установить bodyType обратно в static. Если вы не получите событие столкновения, bodyType все равно будет dynamic в отложенной процедуре, и вы будете знать, что у вас не было перекрытия. В этом случае вам все равно нужно будет установить строку на static в отложенной процедуре.


ОБНОВЛЕНИЕ: Протестировано, используя ваш код в качестве отправной точки

Я изменил событие столкновения, чтобы всегда устанавливать оба объекта 'bodyType в статическое состояние:

function onHit(e)
    print("hit")
    e.object1.bodyType = "static"
    e.object2.bodyType = "static"
end

Затем я изменил вызов addBody для строки, чтобы добавить ее в виде dynamic, с новым кодом для настройки функции timer.PerformWithDelay для проверки через короткое время:

physics.addBody(line, "dynamic", {   })

timer.performWithDelay(10, 
    function()
        if line.bodyType == "dynamic" then
            print ("NO OVERLAP")
            line.bodyType = "static"
        end
    end)

Результаты были, к сожалению, смешанными. Он работает большую часть времени, возможно, 95%, но иногда терпит неудачу, когда рисует линию, которая начинается вне круга и заканчивается внутри, что должно быть перекрытием, но иногда сообщается, что оно не перекрывается. Я не смог понять, почему это происходит. В любом случае, я пишу об этом, надеясь, что это поможет вам, а также думаю, что кто-то сможет выяснить противоречивое поведение и научить нас обоих.

Если это не удастся, вы можете добавить дополнительную проверку для случая «без перекрытия», чтобы проверить, находится ли какая-либо конечная точка линии ближе, чем радиус окружности от центра. Это могло бы заставить вещи работать, но я полагаю, что в этом нет смысла позволять физическому движку работать.

В любом случае, удачи!

0 голосов
/ 08 мая 2015

Выполните raycast, когда вы отпустите нажатие мыши. Таким образом, вы можете сохранять оба объекта статичными и знать, что они пересекаются с помощью обратного вызова raycast.

(я знаю, что это старый пост, но он был первым попаданием в моем поиске в Google и неверно задан)

...