Sunday, November 1, 1998

Finishing up Rocketship

.KEYWORD finishrocket
.FLYINGHEAD PROGRAMMING POWER
.TITLE Finishing up Rocketship
.DEPT
.SUMMARY In honor of John Glenn’s historic shuttle flight, we present the final version of programming technology editor Alan Jay Weiner’s Rocketship program. In this edition of PalmPower’s Programming Power column, Alan finishes the program, adding a goal (docking the rocket with a space station), a win or lose response, and some other out-of-this-world changes.
.AUTHOR Alan Jay Weiner
In my previous two columns, I worked on a small game for my son. This month we’ll finish it off by adding a goal (docking the rocket with a space station), a win or lose response, and some changes here and there.

Along with the changes to the Rocketship game, we’ll look at how I took a short cut with the animation, and why it won’t work for games with more intense animation. The full listing for the November installment of Rocketship is at http://www.component-net.com/pp-extras/rocket1198.html.

.H1 Sources for GCC
First let’s start with some great news for GCC users. Two readers sent copies of their port to GCC. I made a few changes in this month’s version to make it easier to port to GCC and I’ll have a GCC version available for download on my personal website at http://www.ajw.com.

This month we continue the Rocketship game, adding several new features and changing a number of things that already existed.

.H1 Changes to Rocketship
Let’s quickly go over the new things for this month. For porting to GCC, I changed some bitmap numbers. The application icon always has an ID number of 1000 and when dumping the bitmaps, this was annoying to deal with if there was also a bitmap with an ID of 1000. Additionally, I merged everything to a single source file. This was just easier to deal with all around. In reality, many of the small routines are in a library that I use for most of my applications. As you program you’ll create your own library of useful, little routines.

For game play, the biggest change is to add a goal and a response upon winning or losing. Since this is still a game for my son and he’s only four years old, the goal is rather simple — when the game starts, a small docking bay appears at the top of the screen. The goal is to dock the rocket with the docking bay. When the rocket reaches the docking bay or crashes into the rest of the docking ships either a smiling face or a frowning face appears.

This necessitated changing the start and reset sequences. Instead of starting a new game immediately upon game completion, it needs to display the final response and wait for to the user to reset for a new game. I implemented this as a state machine. The game is in one of the following states: ready to play, initializing the docking day, playing, or game over.

Up until now, we displayed bitmaps directly from the resources; opening the resources, display it, and closing it each time it’s displayed. To improve performance, this month I changed the program’s behavior so that it opens several bitmaps at the start of the game and leaves them open until the game exits, at which time they’re each closed.

.H1 New bitmap functions
I added three new bitmap functions:

.BEGIN_LIST
.BULLET GetBitmapPtr gets the bitmap resource and locks it down;
.BULLET ReleaseBitmapPtr unlocks and releases the resource;
.BULLET DrawBitmapPtr draws it on the screen.
.END_LIST

Using GetBitmapPtr, I open the bitmaps when the application starts. The bitmaps remain open until Rocketship exits.

.H1 Random number generator
When the game begins, a docking bay descends and moves back and forth, finally stopping at a random position.

To position the docking bay, I call SysRandom to get a random number. SysRandom returns a number ranging from 0 to 32767 (0x7FFF). This upper number is defined as sysRandomMax in the SysUtils.h header file.

For the rest of game play, I set a different random number generator seed when the program begins. I simply use the time in ticks.

.H1 Pausing for menus
When a user pops up the menu, the game should pause while he works the menu. This is now accomplished by checking which window we’re in. When we start a game, the program remembers the main screen’s window handle. When it goes to do background activity, it checks that the handle of the current window is that same main screen handle. As long as it is, we know the user hasn’t changed anything — he didn’t raise the menu, go to the "about" screen, or whatever. Consequently, if the window handle had changed, we’d know something had changed, so we should pause the game.

When the main form is opened (at the frmOpenEvent in MainFormHandleEvent) we call WinGetActiveWindow to get the main form’s window handle. When a nilEvent comes in (which we use for timing) we again call WinGetActiveWindow to see if we’re still on the main window.

.H1 Avoiding flicker in animation
I took a short cut when displaying bitmaps in Rocketship. Because I have so little movement on the screen, it was suitable to simply erase the old bitmap and display the new one. Normally that would cause flickering. Ideally, we’d draw the screen update to an off-screen window, and then copy that window into the real display. The technique is more than I can explain right now, but there’s a document on Palm’s web site which does explain it. You’ll find that document in the developer’s section at http://www.palm.com/devzone/docs/animation/animate.html.

.H1 Conclusion
This will be it for Rocketship for now. There’s lots of other great Programming Power topics to get into. Next month I’ll start in on the serial port.

.BEGIN_SIDEBAR
.H1 Product availability and resources
Source code and executable for this project is at http://www.ajw.com/PalmPower/ProgrammingPower/Nov98/Rocketship.zip.

Palm’s white paper on animation is at
http://www.palm.com/devzone/docs/animation/animate.html.
.END_SIDEBAR

.BIO Alan Jay Weiner writes software for PalmPilots. His email address is alan@ajw.com.
.DISCUSS http://www.component-net.com/webx?13@@.ee6c3f1