Sometimes collisions work, sometimes they don't.

I'm building a maze game controlled via motion sensors. Think that old tabletop Labyrinth game.

When the ball strikes a wall at a low speed, it stops, but if it's at a high speed, it passes right through. This also means that if the ball has stopped, I can tip the laptop farther, and it will eventually go through the wall.

The collision detection is in a controller class that has a reference out to the CustomView used for rendering. The collision detection is called after the new dot position has been figured and the screen has been refreshed. There also seems to be a problem when two walls intersect- I can sometimes sneak the ball through the corner, although this could be related to the current problem. I've been banging my head against the wall for weeks on this, so I'm throwing it up here to see if anyone has any thoughts.

I'm obviously missing something really butt simple. But I've spent years avoiding game programming for just this very reason.

//left edge test
//lastX is to the left of the left side, and the curX is to the right of the left edge, and we're in line between the top and bottom
if (startToTheLeft && endToTheRight && (aboveBottom || belowTop)) {
center.x = wBounds.origin.x - radius; //move the center back to the left
} else //if our lastX is to the right of the left edge + width, and the curX is to the left of the left edge + width, and we're in line between top and bottom
if (startToTheRight && endToTheLeft && aboveBottom && belowTop) {
center.x = wBounds.origin.x + wBounds.size.width + radius; //move the dot to the right
} else //bottom edge
if (startBelow && endAbove && (pastLeft || beforeRight)) {
center.y = wBounds.origin.y - radius;
} else
if (startAbove && endBelow && (pastLeft || beforeRight)) {
center.y = wBounds.origin.y + wBounds.size.height + radius;
} else {
//we're on a corner- figure out how to fix that, will ya?
//test each corner, and move the ball to one of the edges?
//yeah, i like that. TL=top, TR=right, BL=left, BR=bottom
NSPoint bl = wBounds.origin;
NSPoint tl = bl; tl.y += wBounds.size.height;
NSPoint br = bl; br.x += wBounds.size.width;
NSPoint tr = br; tr.y = tl.y;
[d setColor:[NSColor purpleColor]];

It looks like you're using a simple intersection test to check for collisions. For fast-moving and/or very small objects, this will not work reliably. Your moving object is probably passing completely through the wall between two of your collision checks, in which case an intersection test at both points would return false.

What you'll need to do is somehow take into account the movement of your object between the two positions at which you perform your collision tests. Since you're working with a sphere, one thing you could do is extrude it into a capped cylinder, and test intersection between the cylinder and the walls. Another option would be to do multiple intersection tests per frame, each one working with a small enough timeslice that the object doesn't move far enough to pass completely through the wall.

I sympathize with you, because this is a somewhat difficult problem... In my free time, I'm working on implementing something very similar. I may write a tutorial on it at some point if I'm successful.

What I've done to fix the go through walls is capped the ball's speed lower, and increased the refresh rate- it's still using one-frame-per-update, but the updates are going a lot faster, and the graphics aren't really heavy, and the ball just moves less distance per update. It balances out.

It still has a flaw where walls overlap- the solution that I'll implement in the near future- I'm going to make the walls not overlap. Ever.