Breakable Walls

I’m working on a game that uses physics as a main piece of gameplay, and I recently added an object that speeds you up. I just noticed that at a high enough speed, the player will pass through walls. I visited the discussion “Edges Seem Porous” and tried the fixes suggested there: using chains, setting body.bullet to true, and I already move by using applyForce, not changing position directly. The problem persists. I even tried turning physics.continuous to true. Still doesn’t work. I was wondering if anyone had experienced something similar, and if so, how you fixed it (or if it just isn’t solvable). Thanks in advance!

@JakAttack with my limited experience with physics, I believe the bullet setting in the physics object might be what you are looking for. Its suppose to prevent fast moving object from tunneling.

@Briarfox, I mentioned in my earlier post, I tried that but it didn’t seem to work.

@JakAttak I tried setting up a physics edge and a physics circle. I have the circle going towards the edge at a linear velocity of 500000 and it bounce off. I’m not sure if there’s a max velocity and it’s really moving at that speed. Everything is set at default except gravityScale=0. I think the applyForce is pushing it thru the wall. If you use applyForce then maybe you need to reverse the force upon a collision or else the appleForce just pushes it through the wall.

Well to test I went into the physics lab and set the defaultGravity to physics.gravity() * 50

This caused some of the objects (those falling from high up) to fly straight through the wall, even those using chains.

@JakAttak Gravity is also a force that goes in one direction (down) . So that will force it thru the wall also at a high speed.

@JakAttak - Does the collide event ever get called for the 2 objects? Could you send us some example code?

@Zoyt here’s a small example:

function setup()
    pos = vec2(WIDTH/2,HEIGHT/2)
    body = physics.body(POLYGON,vec2(-40,-40),vec2(-40,40),vec2(40,40),vec2(40,-40))
    body.position = pos
    body.bullet = true
    
    physics.continuous = true
    
    floor = physics.body(EDGE, vec2(0,0), vec2(WIDTH, 0))
    wall1 = physics.body(EDGE, vec2(WIDTH, 0), vec2(WIDTH, HEIGHT))
    ceil1 = physics.body(EDGE, vec2(WIDTH, HEIGHT), vec2(0, HEIGHT))
    wall2 = physics.body(EDGE, vec2(0, HEIGHT), vec2(0,0))
    holding = nil
end

function draw()
    background(50,255)
    fill(255) stroke(255) strokeWidth(5)
    rectMode(CENTER) rect(body.position.x, body.position.y, 80,80)
    if holding then
        local dist = vec2(holding.x,holding.y):dist(body.position)
        body:applyForce((vec2(holding.x,holding.y)-body.position)*(dist/250)-body.linearVelocity/10)
        body:applyForce(body.linearVelocity * 1.1)
        stroke(255,0,0)
        line(body.position.x, body.position.y, holding.x, holding.y)
    end
end

function touched(t)
    if t.state == BEGAN and body:testPoint(vec2(t.x,t.y)) then
        holding = t
    end
    if holding ~= nil then 
        holding = t 
    end
    if t.state == ENDED then 
        holding = nil 
    end
end

@JakAttak If I comment this line, it seems to work. The rectangle rubber bands close to my finger and doesn’t go thru any wall.

        --body:applyForce(body.linearVelocity * 1.1)

@dave1707 - I think he’s trying to prove his point about fast moving bodies going through walls. This is very odd…

@Zoyt OK, that was my mistake. I was running his code on my iPad1 and I couldn’t get it to break thru the walls. I switched to the iPad Air and it went thru the walls right away. My Air was charging so I was using the iPad1 before.

Yup. I’m lost on what to do. I tried setting the walls to polygons, and they’ll still break through almost no matter what, but the thicker they are, the hard it is to do.

That’s the thing, I can’t seem to find a way to get it not to go through the walls when speeding up.

I tried using physics.iterations thinking that would make it check more, but that didn’t work either.

@John, any idea why it doesn’t seem to work?

@JakAttak I took your code and made it as small as possible to show the problem. Keep hitting the replay button. Sometimes it goes thru the wall, sometimes it doesn’t. Maybe with this size it might be easier to find a solution.


displayMode(FULLSCREEN)

function setup()
    body = physics.body(POLYGON,vec2(-40,-40),vec2(-40,40),vec2(40,40),vec2(40,-40))
    body.x=100
    body.y=500
    body.gravityScale=0
    body.linearVelocity=vec2(100,0)
    body.bullet=true
    wall1 = physics.body(EDGE, vec2(WIDTH, 0), vec2(WIDTH, HEIGHT))
    physics.continuous=true
end

function draw()
    background(50,255)
    fill(255) 
    rectMode(CENTER) 
    body:applyForce(body.linearVelocity*1.1)
    rect(body.position.x, body.position.y, 80,80)
end

You should move this to the beta section, since it appears to be a beta issue. Just edit the first post and change it. :slight_smile:

@JakAttak @John I ran the above code and saved the x position of the rectangle in a table as it moved across the screen. On thing I noticed is the linearVelocity never gets above 3840. Like that’s the max speed. Anyways, I noticed that when the rectangle goes thru the wall, it’s at a certain x value. When it doesn’t go thru the wall, it has a different x value. The values are always the same when it goes thru and when it doesn’t. So it looks like it depends on the position of the rectangle and the wall when the collision check is done. If it’s too far past the wall at the collision check, it goes thru. I guess it’s similar to the other problem where 2 exact physics runs will produce 2 different results.

@Zoyt, will do.

@dave1707, thanks. Hopefully it can be sorted it without too much trouble.

@JakAttak @Zoyt @John @Simeon I ran my program several times changing the size of the rectangle so I could see the different x values as the rectangle moved across the screen. The results that I saw was:

The rectangle would go thru the wall if it’s center point was less than the wall and it’s leading edge was also less than the wall during the draw() just before the wall. On the next draw(), the center point of the rectangle was beyond the wall. So the rectangle continued.

The rectangle would stop at the wall if it’s center point was less than the wall during the draw() and the leading edge of the rectangle was beyond the wall. This resulted in a collision so the rectangle stopped.

So depending on the speed of the rectangle, it could be completly less than the wall during one draw() and the next draw() it would be passed the wall at which point it wouldn’t stop. I don’t know how often a collision is checked, but if it’s checked at each draw(), then this would explain why some collisions work and others don’t.