11
\$\begingroup\$

So far in previous games I have used simple 2D collision with boxes then checking at pixel level for a collision.

If making a pinball game in nearly a lot of frames the ball will be in contact with a wall or another surface so is there another approach?

\$\endgroup\$

5 Answers 5

21
\$\begingroup\$

Back in the days (1990), old pinball games were made like this :

There is several layers for playfield (what you see when playing the game) :

enter image description here

and several layers for collisions :

enter image description here enter image description here

The left grayscale picture is a collision map for main game, right picture is a collision map for special area : pinball ramps.

White = free area for ball, color index there is 255.

Gray = ball will be "pushed away" from this zone. color index = angle of vector to add to ball position. light gray = 0 deg. dark gray = 360 deg.

Some pseudo code :

void do_ball_physics()
{
    while(1)
    {
         byte color = read_pixel_under_ball(ballx, bally); //one pixel read
         if(color == 255) //see remark below
            break;
         float vectorx = sin(color/255.0f * 2.0f * PI);
         float vectory = cos(color/255.0f * 2.0f * PI); 
         ballx += vectorx; //push ball away from one unit
         bally += vectory; //

    }
}

Some special color indexes can also be used for something else than collision, a custom color range (eg : 240 - 255) can be reserved for detecting special zones like spinners, triggers, bumpers, holes, ...

As you can see, this is very simple. There is only a few pixels "read" per frame. Because of this you can make the physics simulation run at a real high framerate eg : 200 fps. Using high framerate will smooth simulation and reduce "tunneling" (this happen when ball goes too fast and pass trough elements without colliding). That simplicity is also what make smooth pinball games possible on 386 computers (and even fast 286) back in the days (among some other tricks like color cycling, vga scrolling and sprite masking ...).

Today, most pinball games are no more made like this. Instead the playfield is a 2d/3d scene using polygons or sprites and collisions are made against some simplified lines, bezier curves, or spheres representing a simplified shape of visual playfield.

example (from visual pinball) :

enter image description here

Some game companies use their own physics engine but another, easier way is to use a physics engine like Box2D or Bullet. Most iPhone pinball games i saw were using a pre-existing physics engine + some 3d assets.

\$\endgroup\$
6
  • \$\begingroup\$ ... we're talking javascript and canvas here, so the slowest operation possible in this framework is ... drawing and reading pixels... especially on slowest devices. So 4/5 of this answer are simply history/irrelevant. But rationnality cannot compete with pictures. \$\endgroup\$ Nov 18, 2012 at 20:10
  • 3
    \$\begingroup\$ Collision maps can be stored in an array, why would you want to store them in some canvas ? As you said first part of the answer is mostly for history, but if you need to implement a pinball on a very low end cpu (eg: old gsm) this is still applicable. In modern times, i would rather suggest using a physics engine like jbox2d or do the physics by yourself with collisions against line segments or bezier curves (if you think you are able to write such a thing). \$\endgroup\$
    – tigrou
    Nov 18, 2012 at 23:32
  • \$\begingroup\$ Reading pixels in images is also very fast in modern browsers. Some of the first "omg JS is faster than C" demos were all image-processing kernels. \$\endgroup\$ Nov 19, 2012 at 0:08
  • 1
    \$\begingroup\$ Because of this pinball dreams remake : pouet.net/prod.php?which=24499 (not by me). Look in sources, collision map I talk about are there. \$\endgroup\$
    – tigrou
    May 19, 2015 at 19:38
  • 1
    \$\begingroup\$ Yeah I encountered that actually too, too bad it's all in 6502 assembler :) Any other good sources? I've been wondering how they did the flippers especially. \$\endgroup\$
    – Bemmu
    May 21, 2015 at 13:29
2
\$\begingroup\$

Pinballs have very rich sets of physics, not only holes or walls, but also reacting elements (hitting back) or uneven surface where the ball slows down and then gets it's speed back.

If you want to create a good pinball, the way to go is either to use a 3D collision detection, or self-tailored system with every collidable object having a method with distance and velocities parameters, returning changed velocities.

\$\endgroup\$
2
  • \$\begingroup\$ Why do you say 3D collision detection what befits does this have over 2D? \$\endgroup\$
    – John
    Nov 13, 2012 at 15:48
  • \$\begingroup\$ @John I imagine a good pinball as a 3D game with ramps etc. You could program these ramps in 2D, and scale the ball up when it goes over the ramp and down when it falls back yourself, but in this case it's still a 3D game, you just add Z dimension by yourself. \$\endgroup\$ Nov 13, 2012 at 15:53
2
\$\begingroup\$

I made a pinball game a while ago; it was pixel based as well. I had a collision map which just contained the collision data. An approximate collision normal was easy to find:

Take the area of collision map overlapping the ball, find the centre, form the vector from that point to the ball centre, then normalise.

Hope that gives you some ideas :)

\$\endgroup\$
1
\$\begingroup\$

First if you make a pinball game, you'll most likely need more bounding-CIRCLE-collision-detection than the bounding BOX one :-)
Given the complexity of the physic involved in a full fledged pinball, i would suggest to look on an existing 2D physic engine. Box2D has quite a reputation in javascript, there might be others but i didn't encounter any good (and free) one.
Rq1 : You certainly use (as i do) the classical split in your game between update and draw. And you use a timer (setInterval/setTimeout) and/or RequestAnimationFrame to call update, then draw, in a regular fashion. A pinball might be the type of game where you want to have one timer driving update, and another driving the draw, so you can adjust the rate of each independently, to work on a wide range of devices. Because you can't just drop (update+draw) if the device is too slow : if the time between two updates (dt) becomes too long, the physic engine might miss a collision.

\$\endgroup\$
0
\$\begingroup\$

You might take a look at visual pinball vs future pinball for the 2d vs 3d subject. If you play visual pinball (Everything is made in 2d) then play future pinball, or something like Zen Pinball you do feel the difference in how they play. I personally prefer the 3d, but your project may be better suited to 2d, Only you would be able to decide that

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .