开发者

Corona/Box2D detect collision with non-moving static objects

For posting reasons here's a simple version of what I'm trying to do.

On the screen I have a simple circle object that is static and doesn't move. The user can then drag and drop a straight line. If the line passes through that circle I'm hoping for the collision event to be triggered.

It appears that unless one of the objects are moving the collision is never detected. Can I detect the collision when the line is drawn?

Collision Event

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

Touch Event

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)

Create circle

local c = display.newCircle(50, 50, 24开发者_如何学编程)
physics.addBody(c, "static", { radius = 24 })


This page from the Corona SDK docs describes the bodyType property about halfway down the page. When describing "static" bodies, it says (my emphasis):

static bodies don't move, and don't interact with each other; examples of static objects would include the ground, or the walls of a pinball machine.

That means that one of the objects has to be something other than static.

Here's an idea, although I haven't tried it myself: (See update below.) Make the line dynamic when you first create it. Set it to static a few milliseconds later using a timer.performWithDelay function. If a collision event occurs in the meantime, you will know that you've got an overlap, and can set the bodyType back to static immediately. If you don't get a collision event, the bodyType will still be dynamic in the delayed routine, and you'll know you didn't have an overlap. In this case, you'll still need to set the line to static in the delayed routine.


UPDATE: Tested this, using your code as the starting point

I changed the collision event to always set both objects' bodyType to static:

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

Then I changed the addBody call for the line to add it as a dynamic body, with new code to setup a timer.PerformWithDelay function to check after a short time:

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

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

The results were, unfortunately, mixed. It works most of the time, perhaps 95%, but fails occasionally when drawing a line that starts outside the circle and ends inside, which should be an overlap, but is sometimes reported as no overlap. I wasn't able to figure out why this was happening. I'm posting this anyway, hoping that it gets you going, and also thinking that someone may be able to figure out the inconsistent behavior and educate us both.

Failing that, you could add an additional check for the "no overlap" case to check if either endpoint of the line is closer than the radius of the circle away from the center. That would be make things work, but I suppose it misses the whole point of letting the physics engine to the work.

Anyway, good luck!


Perform a raycast when you release your mouse press. This way you can keep both objects static, and know that they intersect via the raycast callback.

(I know that this is an old post, but it was the first hit on my Google search and is incorrect afaic)


Set the body type as kinematic, set it as a sensor, and update its position to the entity it's tied to every frame. Unlike static, kinematic can interact with static.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜