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) :
and several layers for collisions :
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 :
byte color = read_pixel_under_ball(ballx, bally); //one pixel read
if(color == 255) //see remark below
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
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) :
Some game companies use their own physics engine but another, easier way is to use a physics engine like
Bullet. Most iPhone pinball games i saw were using a pre-existing physics engine + some 3d assets.