What you're experiencing is a very, very common problem with physics engines. Basically, your object is falling between the cracks that your framerate provides. First it's approaching the wall and then it's inside of the wall, without registering a collision!
There are two solutions to this problem:
Ducktape it - Use a smaller timestep, which is effectively a higher framerate. If you up the framerate to 60 fps, there are now 6 frames between "before the wall" and "inside the wall". Why is this a ducktape solution? Because your framerate might still not be high enough and you can't up it forever.
Fix it properly - Don't base your physics on just the current position.
I'm not going to bother explaining the first solution, it's simple enough. If that works for you, great! Many games have shipped with that solution in place.
However, I really want to explain the second solution.
Let's say we have the following situation:
Here, the red ball wants to bounce off the wall. We can see its direction denoted by the blue line. However, this isn't its direction, but its velocity, which is direction * speed
. So, what we have here is the ball's current position and the ball's future position, which would be position + (direction * speed)
.
Now we can deflect our ball using the wall's surface normal:
The important thing to note here: the ball hasn't moved yet. As far as the ball is concerned, it is still in front of a wall.
The code should now look this:
- Ball updates its direction and speed, if necessary.
- Ball calculates its velocity from direction and speed.
- Ball calculates its future position from position and velocity.
- Scene uses Ball's position and future position to determine that Ball will collide with Wall.
- Wall reflects Ball's velocity over its surface normal to create a new future position, a new direction and a new speed for Ball.
- Ball sets its position to future position and updates its direction and speed.
Now your Ball can never fall through the cracks. Even better: multiple objects can collide with Ball and it will hopefully all resolve to 1 future position. However, this will require multiple passes of collision resolving by the Scene.
For further reading, look for "sweep test".