#172431 - Aurelio - Fri Feb 05, 2010 9:17 pm
Hi!
I'm making a Pinball game for the DS, but i have some problems with collision.
I have a ball with x and y coordinates and vx and vy as components of the velocity.
I have a bitmap with a value for each pixel of the screen, 1 if the ball have to collide with this pixel, 0 if it haven't to collide.
Now the big problem is the response that I've to give to the ball coordinates and velocity.
Can you help me?
#172450 - TwentySeven - Sat Feb 06, 2010 10:40 pm
If you're just doing this simply, you'll need to map a "return" direction (a normal) for every solid point of the playfield.
So an upwards facing wall would have an up normal, etc. You use this then to do your reflection calculation on impact.
Positioning the ball post collision is easy, you can "cheat" there and just move it between where it was last frame and where it was when it collided until it no longer collides.. sort of like a rewind.
#172458 - keldon - Mon Feb 08, 2010 5:31 am
Use geometric operations to calculate the collision point ... It's 430am and I really shouldn't be up but I could knock together some code on Wednesday and explain how it works for your future reference.
For a "moving circle / line collision" it's something like:
- Create a transformation matrix from the line (see here)
- Create two circles from your pinball and connect them with a rectangle
- The two circles can be tested by their y values alone and the lines can be tested using a "line / line collision" function (which itself makes use of dot products)
#172471 - Miked0801 - Mon Feb 08, 2010 10:37 pm
Ah, the good old pixel vs Vector collision problem. We had this exact same argument when we last did a pinball mini-game. Vector based collisions are a better way to go. You get much more accurate reflections calculated much faster than pxiel based math - plus you avoid a lot of the what to do when a ball goes through a thin collision area problem along with the ball sticking to the collision surface issues due to double refelctions caused by roundoff.
#172487 - Aurelio - Tue Feb 09, 2010 6:28 pm
This is my actual collision code, it works, but this need a great memory(and maybe CPU too) usage.
This uses a map containing the coordinates(12bit fixed point) of pixels of a line in succession.
The code first check if there is a collision by simply checking if the ball is near the line, then, if there is a collision, it rotates the system of the velocities( by the angle between a point before of the one with wich the ball collided and another one after the one with wich the ball collided) , inverts vy, and then rotates back the system of the velocities.
I know, it's a bit confused, sorry.
I've uploaded the source in the last post
Last edited by Aurelio on Tue Feb 09, 2010 7:24 pm; edited 1 time in total
#172488 - Aurelio - Tue Feb 09, 2010 6:30 pm
Ops, a lot of post
Last edited by Aurelio on Tue Feb 09, 2010 7:23 pm; edited 1 time in total
#172489 - Aurelio - Tue Feb 09, 2010 6:32 pm
Ops, a lot of post
Last edited by Aurelio on Tue Feb 09, 2010 7:24 pm; edited 1 time in total
#172490 - Aurelio - Tue Feb 09, 2010 6:53 pm
Ops, a lot of post
Last edited by Aurelio on Tue Feb 09, 2010 7:23 pm; edited 1 time in total
#172491 - Azenris - Tue Feb 09, 2010 7:00 pm
You made the same post a few times. You might wanna delete/edit the content of them. Also you could have shown a snippet of the array instead of it all :p
_________________
My Homebrew Games
#172494 - Aurelio - Tue Feb 09, 2010 7:29 pm
Sorry, i had some connection problems...
I've uploaded the source here
#172509 - sverx - Wed Feb 10, 2010 11:23 am
Ciao Aurelio,
when the ball collide with a pixel you should find kind of a surface where your pixel belongs to and then calculate the bounce according to your ball angle and the surface angle. Can you calculate the surface angle starting from a given pixel?
#172511 - sonny_jim - Wed Feb 10, 2010 1:34 pm
I'm actually working on custom software for real pinball tables:
http://www.oddchange.com/freewpc/
It may not be relevant, but there may be some code in the kernel/ and common/ directories that may interest you, although it's more along the lines of ball tracking/scoring.
If you need any ideas for rulesets, I've got millions of them ;-)
_________________
Quote: |
Would that be the internet driver for the program?
|
#172524 - Miked0801 - Wed Feb 10, 2010 8:43 pm
Line seqment collision (2D)
1. Did the ball pass through a collision line? 2D magnitude of cross product (determinant) of (last ball position - base line position X line Vector) and (new ball position - base line position X line Vector). Compare signs. If they differ, the ball cross the line. This check should only be around 8 subtracts, 4 multiplies and a compare.
2. Did the ball pass through the actual line or pass its extents? The true way is to find the line segment intersection and see if it is within the line. A faster way is to compare the dot product of previous 2 vectors and see if the value is non-negative and less than the length of the segment (squared if the segment vector is not normalized). Again, 4 multiplies a couple addes and a couple compares.
3. You've collided, reflect or do whatever :)
#172525 - Aurelio - Wed Feb 10, 2010 9:01 pm
Yeah, the real problem is what to do when the collided with the line :S
#172530 - TwentySeven - Thu Feb 11, 2010 4:09 am
2d vector reflect?
#172533 - melw - Thu Feb 11, 2010 12:34 pm
One simple way of doing Pinball collisions is to think the ball to be a single dot and have a separate collision map you're comparing the ball coordinates against. The actual game graphics would be based on the collision map, having stuff also over the collision map borders - depending on the visible ball size.
This solution - even if not entirely elegant - is very light-weight what comes to maths. Although you still need to calculate separately what happens after a collision has occurred.
#172541 - Miked0801 - Thu Feb 11, 2010 8:13 pm
The problem with bitmap collision solutions are:
1. How do you reflect your velocity accurately? With vectors, its a very simple algorithm to do a reflection at any angle. You either are forced to leave walls X/Y axis aligned or store/calculate the wall angle for reflection (which defeats the purpose of the bitmap.)
2. If your ball/dot is moving faster than 1 collision unit per tic, then you either have to check each individual collision square the ball travels through with some sort of integer line trace (kinda slow), make your walls thicker than the max velocity of the ball (kludge), or make sure the velocity of the ball never gets too high (epic kludge).
3. Flippers? Without vectors, getting flippers to feel accurate at all is a major pain. You can fake the plunger if it's straight up/down, but again it requires math to get the acceleration part right, plus code to make sure you push the ball during the impact to prevent double/triple/... internal collision with the plunger while it is moving.
4. Space efficiency. Vectors will be much more space efficient most of the time compared to even a 1-bit bitmap. Of course that bitmap compressed may win, but that's another layer of complexity.
5. Extendable. Once you get a vector collision system working, the same system can be used for baseball games (stadium walls, bat/ball, etc.), RPG map tiles (sliding along vectors is sooo much easier to calculate than bitmap collision), and well any other sort of collision. The math is just that much better.
Advantages of bitmap:
1. Easy to draw and visualize the board and collision map. Easy to change. This is why it's so appealing. It allows you to get further quicker and change the board on the fly.
2.First pass collision code s trivial. What to do when a collision occurs is not.
Overall:
Once you get reflections from walls working with either system, the next big pain will be getting moving game objects to correctly interact with the ball. Vector math is the way to go hee with the infinite amount of angles are such that can be produced.
#172542 - Miked0801 - Thu Feb 11, 2010 8:18 pm
FYI, here the reflection code you need for walls:
BallVector is the direction of the ball before hitting the wall
WallNormal is the normal of the wall (must be a unit vector)
ReflectedVector = BallVector - 2 * WallNormal * (WallNormal dot BallVector )
note that this will work for 3D vectors as well if you wanted to do ramps or the like.
#172543 - Aurelio - Thu Feb 11, 2010 8:20 pm
Miked0801 wrote: |
FYI, here the reflection code you need for walls:
BallVector is the direction of the ball before hitting the wall
WallNormal is the normal of the wall (must be a unit vector)
ReflectedVector = BallVector - 2 * WallNormal * (WallNormal dot BallVector )
note that this will work for 3D vectors as well if you wanted to do ramps or the like. |
With * you mean cross product, right?
What I've to do with Reflected Vector?
EDIT: My, mistake, it's a normal scalar product. I need to subtract 2 * WallNormal * (WallNormal dot BallVector ) to each component of BallVector?
Last edited by Aurelio on Thu Feb 11, 2010 8:57 pm; edited 1 time in total
#172546 - Dwedit - Thu Feb 11, 2010 8:53 pm
Those look like scalar multiplication to me.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."
#172548 - TwentySeven - Thu Feb 11, 2010 10:49 pm
The difficulty of Bitmap flippers thing is a good point.
#172550 - keldon - Fri Feb 12, 2010 6:15 pm
It looks like it's too late; but I posted some useful code for collision detection [here]. I haven't updated my server so you will not be able to load the examples unless I upload them, but the code displayed should give you some info (if it's not already been said).