October 23, 1995
Due in quiz sections November 9, 1995
For this project, you may work by yourself, or in groups of two or three. If you work in a group, just hand in one completed assignment with everyone's name on it.
On Nov 9, we'll have the quiz sections in the lab, and have a demo day. (We need to see these in operation to evaluate them for grading. Plus it will be fun to wander around and see what everyone has done.)
Hints: start by considering what the objects are, how they can be arranged in class hierarchies, and how they interact.
One obvious class is class Ball. An instance of Ball should have a location and a velocity. There are also various kinds of things that balls can bump into: walls, the flippers, a scoring thing, and a black hole into which the ball drops when the turn is over. There should be a class for each of these. Some of these classes will have several instances (e.g. two flippers). It will be useful to make a superclass Bumper of all of these, that holds behavior common to all the things that you can bump into.
Finally, you will want a class PinballGame. An instance of PinballGame should hold all the state of the game.
For input, the left and middle mouse buttons can control the left and right flippers, while the right button can give the standard window commands. (If you are running on a Macintosh, which has a one-button mouse, you may want to have the single button move both flippers instead.) In addition, you can put some buttons at the bottom of the game for any additional commands you need, such as "launch a ball" and "quit". Part of the assignment is for you to design the exact interface, however.
Here is a suggestion for the main loop of the game:
LOOP
if the left mouse button is pushed
ask the buttons at the bottom of the screen if they have been pressed;
if so perform the appropriate action.
if there is an active ball:
update the ball's velocity
move the ball
for each bumper: ask the bumper to wake up and check for contact with
the ball
END LOOP
To update the ball's velocity and to move the ball, use the normal laws of
physics: the velocity should increase by the acceleration due to gravity;
the location should change by the velocity times the time increment.
If the ball has hit a bumper, different things will occur depending on what kind of bumper it is. Walls should make the ball reflect off. Flippers should make the ball reflect off also -- plus if the flipper is moving it should increment the ball's velocity. Hitting a scoring bumper should increment the score. Hitting the gutter at the bottom should make the ball disappear. A good object-oriented design for this is to send a message to the bumper, with the ball as an argument -- and let each bumper implement this in an appropriate way:
bumper wakeUpWith: ballThe flippers should implement "wakeUpWith:" by checking if the appropriate mouse button is pushed. If the button is pushed and the flipper isn't flipped already, flip it, and also check to see if it hits the ball while flipping. If the button isn't pushed but the flipper is flipped, then it should return to its rest position.
What you don't need to do: your physics should be plausible, but you don't need to make a precise simulation of physics -- mostly it should make a good game. You don't need to make a pinball window that works correctly with the windowing system -- rather you can just write into the graphics part of the window. Even if you do want to integrate your game properly with the window system, I suggest to begin with you just start it up by evaluating some code in a workspace. (Debugging a window that is part of the window system can be annoying, since if you get a bug while the window is displaying, you'll get a debugging window. If the debugging window opens on top of the bad window, when you close the debugging window the bad window will try to redisplay again ... etc. You can get around this, but you might as well not worry about it to start off.) If you do this simplified implementation, you should implement your own Button class rather than using the built-in buttons, since you won't be trying to integrate with all of the Smalltalk windowing system.
Finally, your game doesn't have to be fast -- it's ok to have an underwater version of a pinball game. I would also suggest not using double buffering or any sophisticated display techniques to start with -- just erase and redraw the ball and flippers on the screen. You can improve the appearance later if you want.