Collision Detection Pinball

Started by
5 comments, last by JWone 20 years ago
Hello @ll, I have difficulties with the 2D collision-detection for a pinball game. The Main things are working fine, but.. I use some of the algorithms described in an article on GameDev for collision-detection and response. But I can’t handle “double-collisions”. With this I mean the situation, if the ball is rolling to a corner of the pinball-table and in one frame (I work with a fix frame rate) i.e. the ball hits the right and the lower wall. My algorithm detects a collision with both walls. But my collision-response is only working with one collision in one frame. And I don´t know how to handle such collisions in a corner. Another problem is that I’m not sure if my collision-detection will work, if the ball hit’s exactly the corner. Can anybody help or show me a good article about such stuff? Maybe you have some code which I can read? Most of the articles that I found are about 3D collision detection. But I search for 2D collision-detection and response articles. Although I’m interested how to improve my game-loop… I’m lucky for any help.. Regards, Jan
Advertisement
Are you saying that when the ball hits NEAR a corner you can respond to the first collision, but the second collision (that is, the second corner) occurs before the next frame is rendered and is therefore missed?

Just trying to get clarification...
I am apart of a crew writing a Pinball game for BREW cell phones. We came across this problem-- here is how we solved it:

First off, what started it was a bug we had. At the corner of two walls, a ball tended to fall thru the corner. The way we were accounting for the ball''s radius was to extend the walls forward by the size of the ball''s radius. Thus walls overlapped each other at corners. If it happened that the ball tested collision detection with one wall, and hit it, but in a place BEHIND the other wall, it would bounce off that and end up behind the 2nd wall.

Instead, we needed to test collision against both walls, and see which it hit first, then bounce off of that.

So, when we tested, we stored the results in an array. We stored the location of contact, and the generated reflection vector and velocity.

We then tested which happened closer, and removed the other from the array.

This array became useful when we came across your problem. We''ve got a circular loop at part of the map, and it requires about 6-8 bounces in a turn to get thru. Simply by adding each succesive collision, and changing the ballPos/Vec in-between collision checks (to represent it coming from its last point of collision) we were able to handle this.
@smitty1276: No I only hit one corner, not two corners. I mean the ball hit''s in one corner, but it hit''s two walls in one frame. I think "keless" did get it right what I mean..


@keless: I think you have had exactly my problem. Did I get this right that you first collect all collision-detection results, and then you store them inside an array? Then you check which collision occurred at first in this array and in this order you execute one collision-response after another?

The idea that I know have to implement this is the following: In my collision-detection algorithm for each pinball-obstacle I work with a normalized time to describe the collision-time in one frame. No I would have to execute all the collision-detections for all pinball-obstacles on the pinball table. The collision result with the shortest “normalized-collision-time” is the collision for which I should execute the collision response at first. After I executed the collision response for this first detected collision, I would have a new current ball position. So I would have to test again all obstacles against collisions as long until there is no collision. So in the worst case I would have to check again and again all obstacles on the pinball-table against collision. I think this will cost a big amount of computing-time..

You say you handled something like this on a mobile phone? Does it work? Do you have an upper limit for i.e. the ball in a corner that bounces again and again from one wall to another? Do you say after for example 10 collisions in one frame BREAK, and you work with the actual current ball position and speed vector?

Regards, and thanks so far..

Jan
Hello @ll,

I still have trouble with my collision-detection algorithm. Here I show my collision-detection code for a pinball-"wall"-object. I try to implement a pinball-game in J2ME, for this I use a math-library called MathFP for floating point operations, that’s why the code at some parts looks at bit strange..

The algorithm that I use to detect collisions is from an article here on GameDev. But in this article they only describe how to detect collisions between a quickly moving sphere passing through a plane. More exact they only detect collisions on one side of a plane with an infinite expanse. On my pinball-table there are walls that have a finite expanse. I although want to detect collisions on both sides of the wall.

And with this algorithm I still have the “corner-problem” which I described in this Forum-thread before. Is there anybody who can help me? How can I improve my collision detection? How can I improve my Game-Loop to handle “double-collisions” or “corner-collisions”?

Regards,
Jan

public boolean collisionDetection(Ball ball){      Point newPos = new Point();      Point oldPos = new Point();      newPos.fx = ball.fx;      newPos.fy = ball.fy;      long avYSpeed = MathFP.div(((ball.fySpeed -Statics.FGRAVITY) + ball.fySpeed), MathFP.toFP(2));      oldPos.fx = ball.fx - ball.fxSpeed;      oldPos.fy = ball.fy - avYSpeed;      MathVector pos = new MathVector(Point.sub(newPos,lp)); //lp      long curDist = MathVector.vectorDotProduct(pos, normalV);      pos = new MathVector(Point.sub(oldPos,lp)); //lp      long oldDist = MathVector.vectorDotProduct(pos, normalV);      //check if it was touching on previous frame      if( MathFP.abs(oldDist) <= Statics.FBALLRADIUS )      {        collPos = new Point(oldPos);        u = 0;      }      //check if the ball penetrated during this frame from top      if( oldDist > Statics.FBALLRADIUS && curDist < Statics.FBALLRADIUS )      {                u = MathFP.div((oldDist - Statics.FBALLRADIUS),(oldDist - curDist)); //normalized time        collPos = new Point(Point.add(Point.mul((MathFP.toFP(1)-u),oldPos),Point.mul(u,newPos))); //point of first contact      }      //check if the ball penetrated during this frame frum lower side      else if( oldDist < -Statics.FBALLRADIUS && curDist > -Statics.FBALLRADIUS )      {        u = MathFP.abs( MathFP.div((oldDist + Statics.FBALLRADIUS),(oldDist - curDist))); //normalized time        collPos = new Point(Point.add(Point.mul((MathFP.toFP(1)-u),oldPos),Point.mul(u,newPos))); //point of first contact      }      //check if collPos is on boarder      if((collPos!=null)&&(collRect.isOn(collPos)))      {        return true;      }      else{        u = Statics.FONE; // FONE == MathFP.toFP(1)        collPos = null;      }    }    return false;  }  


[edited by - JWone on March 24, 2004 8:43:40 AM]
Here are so many professional game developers, isn’t there anybody that could give me a hint...???

Regards,
Jan
I didn't really take a look at your code, but it seems by your description that you need to handle multiple collisions at once. This could be a semi-complex problem when working with arbitrary complex polyhedra, but in this case it should be rather easy.
For a paper on the subject of resolving multiple contact-points, take a look at http://isg.cs.tcd.ie/giangt/EGIrl2003.pdf


--
MFC is sorta like the swedish police... It''s full of crap, and nothing can communicate with anything else.

[edited by - tok_junior on March 26, 2004 5:49:28 AM]

This topic is closed to new replies.

Advertisement