Ms. MIDP-Man: Technical stuff
I tried to keep the program structure simple. Nearly everything important is contained
in a class called MazeCanvas, which is a subclass of the MIDP 2.0 GameCanvas
class. Outside it is the MIDlet subclass, MsMIDPMan, whose only job is to start up a
MazeCanvas and shut it down when the game ends. I also have a small class called
MazeObject, which holds relevant information about mobile maze objects, such as
direction, speed, look and position. And finally I added a class called Blipper,
named for its use to play "blip" sounds when Ms. MIDP-Man eats a dot. Doing it in the same
game loop as the action resulted in jerky motion on at least one phone model, because of
some kind of system delay whenever a sound starts. So I decided to put all sound management
into a separate Thread subclass. This worked much better.
Like most other games of its time, the original used 8x8-pixel tiles for the backgrounds
(including the "font"). I identified all of the necessary building blocks and created my
own tile set, to be used for a TiledLayer object. But I don't save them as an
ordinary PNG image file. Instead I use a one-byte-per-pixel "raw" format, to make it
easier to set custom colors inside the game. Each maze is also a separate file, in which
the first 9 bytes hold the RGB values of the dot, outline and wall colors. The rest is just
the tile data in reading order, padded with three extra bytes at the start and end of
each row, so that the mobile objects have some room to move outside the maze when they
This is what the tile set image looks like when it's been given the colors of
the first level (magnified to 200% for clarity):
The first 20 tiles do not obstruct motion. I let the game characters move freely on
top of them, but any tile with a value above 20 is considered a wall (the only exception
being the door to the ghost house).
And this is my graphical sprite data (also magnified, and shown against a dark
background for clarity):
Each "frame" is 16x16 pixels. The game uses one Sprite object to hold all of
these, which I then rubber stamp in the appropriate place for each mobile object.
I could have used one Sprite per object and kept them all in a LayerManager,
but that seemed redundant.
The motion of the game characters is of course one of the most important parts of the game.
With the exception of when the ghosts go in and out of the house (which is simple enough
to be handled as a special case), everything is confined to an 8x8-pixel grid and can only
change directions at exact 8-pixel intervals. So when I move the characters, I have to make
sure that their steps always add up to 8-pixel multiples, or they will fall out of grid
alignment. (For example 1+2+1+1+2+1 for slow movement and 4+4 for very fast.) As
a side effect, I can only safely change speeds at perfect 8-pixel multiples as well --
like when the ghosts turn blue or become free-floating eyes. Then they have to wait until
the next 8-pixel multiple before their speed chatches up.
Few things could be simpler than the basic principle of motion for the ghosts and fruit:
find a random available direction, but not opposite to the one you had in the previous
step, except when that's the only alternative. (And the last "except" is just because I allow,
in theory, for mazes that have dead ends. The original Ms. Pac-Man has no such things, so
it's not an issue.) This somehow gives the illusion of "purpose" to the object's path.
For the ghosts I amend this rule with one that says that the new direction can't be
perpendicular to the previous one and lead away from Ms. MIDP-Man. (Scared ghosts
can't pick a perpendicular direction that leads closer to her.) It's not perfect,
but enough to make the game challenging.
Making the ghosts find their way back into to the house after they've been eaten was
a bit more difficult. Again, allowing in theory for more complicated mazes than in
Ms. Pac-Man, I solved it with the same homing algorithm I used in
Dungeon Dregs. I've called this the "bread crumb" technique.
The ghosts follow a trail (in a separate array the same size as the maze) back to the
front door of their house. Once there, moving inside can be handled as a separate case.
And finally, I have tested this game with excellent results on various small-to-medium-sized
screen Sony Ericsson phones (like the K610i on the main page), but if you intend to run it
on different brands, there are a few things you should keep in mind:
- Obviously it needs to support MIDP 2.0.
- Don't bother if the screen is smaller than 128x128 pixels. Then there won't be
enough vertical room for the intro sequence or not enough horizontal room for both the
score and the highscore.
- Not all phones can handle WAV files (sampled sounds). For example the Nokia 6230
will crash if you try. Then you need to remove some of the sound-playing method calls,
or replace the effects with MIDI files.
- Some cery old phones, although capable of running the game in theory, are just too slow.
Like the Nokia 6600. Then the default setting of 50 milliseconds per animation frame
must be adjusted up a bit (fewer FPS), and the game characters should take bigger steps to
compensate for this.
- I use GAME_B_PRESSED as the exit button. On for example the SonyEricsson K700i
this maps to the '9' key. Other phones may have a more logical choice.