PDA

View Full Version : Pinball - The Basics?


Scoops
2005.08.19, 06:06 AM
I have been looking for some information on creating a pinball style game. I can't seem to find too much in the way of examples and guidance so I thought I would drop you all a line to see if you can help!

The basics of moving a ball and applying gravity to it seem straight forward enough. Of course things start to get tricky when the ball starts hitting bumpers and the like which will add speed and direction to the ball. Similarly, how could you implement the sides of the table which slope at various angles, flippers also provide a bit of a challenge too. I know it has all been done before but I am interested to get any new ideas on the matter.

Incidentally, is this the right forum for this? Moderators feel free to move to the correct place if needed!

unknown
2005.08.19, 07:22 AM
You should make an algo for checking if the ball hits a line from any two points, then construct your tabel from several of those.
Here is a way to find distance between a point and a line
http://astronomy.swin.edu.au/~pbourke/geometry/pointline/
If the distance > ballradius + linethickness then there is a collision

Andrew
2005.08.19, 07:22 AM
I found a couple of links for you:

http://mysite.verizon.net/~woodrails/physics/pinballphysics.html

http://www.acorn-gaming.org.uk/index.php3?p=Features/Coding/Pinb2

Andrew
2005.08.19, 07:32 AM
If the distance > ballradius + linethickness then there is a collision

The problem with this method is that it is possible for the ball to cross the line without ever stepping on it. In one frame, the ball is completely behind the line, while in the next frame, the ball is completely on the other side of the line. This would happen if the ball was travelling quickly, and the frame rate was very low (assuming frame rate independent animation).

ThemsAllTook
2005.08.19, 10:37 AM
(assuming frame rate independent animation).

Here's a better way to do frame rate independent animation: http://www.sacredsoftware.net/tutorials/Animation/TimeBasedAnimation.xhtml

You'll still have the same problem if your ball is moving fast enough, but much more control from the code, and 100% consistent behavior regardless of frame rate.

If you can manage it, accounting for the case where the ball moves completely through a barrier is a good thing to do, but the implementation of such a thing can get horribly complicated. Be prepared for a big math lesson.

- Alex Diener

unknown
2005.08.19, 11:31 AM
You could just do, if the balls displacement in this time step is > the minimum line thickness + ball radius, subdivide time.
Or even easier check for line intersection (ballx, bally, ballxpreviousframe, ballypreviousframe) barrer, if there isnt a mindist collision.

ThemsAllTook
2005.08.19, 12:19 PM
You could just do, if the balls displacement in this time step is > the minimum line thickness + ball radius, subdivide time.

That would certainly work.

Or even easier check for line intersection (ballx, bally, ballxpreviousframe, ballypreviousframe) barrer

This almost works, but you'd still have to somehow account for the case where the center of the ball just passes one of the line's endpoints, but with the added radius, the endpoint would pass through the ball. This is why it's difficult.

if there isnt a mindist collision.

A what collision?

Scoops
2005.08.19, 05:22 PM
Isn't it funny how you think animating a ball bumping around an enclosed space can't be too complicated!! If there is the possibility of the ball going through an object between frames, couldn't you pre-calculate the following position of the ball at the same time (basically a frame in advance) so you would know?

unknown
2005.08.19, 07:32 PM
This almost works, but you'd still have to somehow account for the case where the center of the ball just passes one of the line's endpoints, but with the added radius, the endpoint would pass through the ball. This is why it's difficult.

Its not so difficult that way, just if the resultant point D from the algorithm for the minimum distance between line A-B and point C, does not lie on the line segment A-B set it to the closest out of A or B.
That way you are testing for intersection of a circle with a thick line (diameter 2*linethickness) from A-B with circles at the endpoint (with radius linethickness).

mindist collision - minimum distance between a point and line < ballradius + linethickness

unknown
2005.08.19, 07:44 PM
If that made no sense at all run this program,
the length of the blue line is what you would use in collision detection,


// <applet code="Mindist.class" width="400" height="400"></applet>

import java.awt.Graphics;
import java.awt.Color;
import java.awt.event.*;

public class Mindist extends java.applet.Applet {
int dragMode;

Vect2D a, b, c;
Vect2D d, e;

public void init() {
a = new Vect2D((int)(Math.random()*400), (int)(Math.random()*400));
b = new Vect2D((int)(Math.random()*400), (int)(Math.random()*400));
c = new Vect2D((int)(Math.random()*400), (int)(Math.random()*400));

addMouseListener(new ML());
addMouseMotionListener(new MML());
}

public void paint(Graphics g) {
// D is the minimum distance from line A - B to point C
// E is the minimum distance from line segment A - B to point C

double u = ((c.x-a.x)*(b.x-a.x)+(c.y-a.y)*(b.y-a.y))/(new Vect2D(b.x-a.x, b.y-a.y).absSqrd());

d = new Vect2D(a.x+u*(b.x-a.x), a.y+u*(b.y-a.y));
if(u < 0)
u = 0;
else if(u > 1)
u = 1;
e = new Vect2D(a.x+u*(b.x-a.x), a.y+u*(b.y-a.y));

g.setColor(Color.white);
g.fillRect(0, 0, 400, 400);
g.setColor(Color.black);
g.drawLine((int)a.x, (int)a.y, (int)b.x, (int)b.y);
g.setColor(Color.black);
g.fillOval((int)a.x-2, (int)a.y-2, 4, 4);
g.fillOval((int)b.x-2, (int)b.y-2, 4, 4);
g.fillOval((int)c.x-2, (int)c.y-2, 4, 4);
g.setColor(Color.red);
g.drawLine((int)c.x, (int)c.y, (int)d.x, (int)d.y);
g.setColor(Color.blue);
g.drawLine((int)c.x, (int)c.y, (int)e.x, (int)e.y);

g.drawString("A", (int)a.x+5, (int)a.y+5);
g.drawString("B", (int)b.x+5, (int)b.y+5);
g.drawString("C", (int)c.x+5, (int)c.y+5);
}

class ML extends MouseAdapter {
public void mousePressed(MouseEvent e) {
dragMode = 0;
if((Math.abs(e.getX()-a.x) < 5) && (Math.abs(e.getY()-a.y) < 5))
dragMode = 1;
else if((Math.abs(e.getX()-b.x) < 5) && (Math.abs(e.getY()-b.y) < 5))
dragMode = 2;
else if((Math.abs(e.getX()-c.x) < 5) && (Math.abs(e.getY()-c.y) < 5))
dragMode = 3;
}
}

class MML extends MouseMotionAdapter {
public void mouseDragged(MouseEvent e) {
if(dragMode == 1) {
a.x = e.getX();
a.y = e.getY();
repaint();
}
else if(dragMode == 2) {
b.x = e.getX();
b.y = e.getY();
repaint();
}
else if(dragMode == 3) {
c.x = e.getX();
c.y = e.getY();
repaint();
}
}
}
}

class Vect2D {
double x, y;

public Vect2D(double x, double y) {
this.x = x;
this.y = y;
}

public Vect2D dup() {
return new Vect2D(x, y);
}

public void mult(double n) {
x *= n;
y *= n;
}

public double absSqrd() {
return x*x+y*y;
}

public double dot(Vect2D b) {
return x*b.x+y*b.y;
}
}

Andrew
2005.08.19, 10:48 PM
Or you could just use OpenPL, the Open Physics Library. It's a physics simulation API with a style similar to OpenGL or OpenAL... just kidding! It doesn't exist... yet ;)

unknown
2005.08.19, 11:36 PM
haha you fooled me!
http://newtondynamics.com is an open source physics library, kinda tricky though havent really got the hang of it yet.. soon though, once ive done all this other stuff.

mnajera
2005.08.20, 01:53 AM
Just to add my two cents (I'll admit to not fully reading each of the replies):

I've always wanted to make a pinball game, but I've never fully understood the math behind it. Quite recently, I've come to the understanding that you can replicate basic pinball physics with simple line-to-line intersections.

To model a point object bouncing off of a wall: the wall becomes one line, and the points present point plus velocity becomes the second line. If there is a collision, the point is set to the velocity represented by the resulting third line. I was able to create quite realistic physics with this simple model. lineTest.jpg (http://www.lalelulalo.com/misc/lineTest.jpg)

I actually started working on this problem again when I realized I could not correctly model the physics of the standard "wood board" game. woodBoard.jpg (http://www.lalelulalo.com/misc/woodBoard.jpg) . Using this new line-to-line physics model, the game works wonderfully.

Because a pinball can simply be thought of a single point with a radius, the "collision lines" just need to be put at a set distance from the actual geometry, and the look and feel is perfect. Modeling a ball bouncing off of curved walls (a curve can be "tesselated" into several straight lines) is simple enough. My next problem is how to handle the flippers. My current solution is to proceed as normal for collisions against the flipper, with the exception that I rotate the balls original position coordinate around the flippers pivot at the same angle that the flipper has travelled that timestep.

Please excuse me if haven't been so much answering questions as I have been thinking out loud... !

In a nutshell: you can do pinball with line-to-line collisions.

AnotherJake
2005.08.20, 02:20 AM
(I'll admit to not fully reading each of the replies)
Tsk, tsk... You must read or you'll get nailed every time around here. ;)

What you're talking about is already closely mirroring the second link (http://www.acorn-gaming.org.uk/index.php3?p=Features/Coding/Pinb2) that Andrew put up.

unknown
2005.08.20, 10:27 AM
mnajera nice particle effects thing looks really cool,
Similar to what I said too:
Or even easier check for line intersection (ballx, bally, ballxpreviousframe, ballypreviousframe)

mnajera
2005.08.20, 10:49 AM
mnajera nice particle effects thing looks really cool,
Similar to what I said too: You can try it out for yourself here:
physTest.zip (http://www.lalelulalo.com/misc/physTest.zip) . The three different colored particles fall from the top, and you can drag the endpoints of the lines to whereever you want to create a relaxing waterfall of color.

(Only "well-defined" collisions count, meaning that the start and endpoints have to be clockwise... or something.)

Please let me know if this program doesn't work on your machine!

unknown
2005.08.20, 12:59 PM
Because someone was thinking outside the box you need to invert the y axis of the mouse location. They decided to make the coordinate system the same as the standard maths one and not the tried and tested origin at top left, I dont understand why but it sucks because it makes portabilty awkward and graphics programming more confusing.

mnajera
2005.08.20, 01:38 PM
Because someone was thinking outside the box you need to invert the y axis of the mouse location. They decided to make the coordinate system the same as the standard maths one and not the tried and tested origin at top left, I dont understand why but it sucks because it makes portabilty awkward and graphics programming more confusing.Well, I thought you only had to invert (or NOT invert) the y coordinates in fullscreen (or NOT fullscreen) mode. But, did the program run okay otherwise? Here's a quick inverted version:
physTestInvert.zip (http://www.lalelulalo.com/misc/physTestInvert.zip) .

Also, the "B" key toggles bounds checking. With bounds checking enabled, a simple box-to-box test is performed for each particle to each line, and the program doesnt perform the full line collision test for boxes that don't collide, making it much faster, but straight line collisions aren't detected.

unknown
2005.08.20, 01:42 PM
That works like a charm, Why dont you extend the bounding box of the particles used by the velocity so that they do. It will mean a couple more checks per frame but you wont get any particles going through lines.

http://www.geocities.com/ed72678954/boxy.jpg
So those 3 stray particles that went through the line dont occur.

mnajera
2005.08.20, 02:01 PM
That works like a charm, Why dont you extend the bounding box of the particles used by the velocity so that they do. It will mean a couple more checks per frame but you wont get any particles going through lines. That might work, along with forcing the condition that a bounding box always extends a few pixels beyond the "real" box.

This kind of thing is important (going back to the original pinball discussion) because instead of lots of particles colliding with a few lines, you would have one particle (the ball) colliding with the hundreds of lines that make up the pinball table.

The other big problem occurs at the endpoints and intersections between the two lines. Try collecting some of the particles in a cup, and see what happens at the edges. A collision against one line will sometimes place a particle behind another line.

unknown
2005.08.20, 02:13 PM
The error is most obvious with a very acute cup, you could fix that slicing time into sections until you have the exact time (with some slight unceartainty) of the collision, then doing the bouncing code from that time and then integrating the rest of the frame (allowing for more collision test so you can have several per frame, watch this though you might want to have a maximum collision per frame incase you get stuck in an infinite loop).

Also there is too much friction or they dont keep thier origional velocity after collisions so you cant make a curved ramp that they jump out of at the end.

PowerMacX
2005.08.20, 06:23 PM
haha you fooled me!
http://newtondynamics.com is an open source physics library, kinda tricky though havent really got the hang of it yet.. soon though, once ive done all this other stuff.

Nope, not open source, just free.