The example developed in this tutorial is a maze traversing game.
In the game, the player sees the world from a traditional, first-person point of view and walks around the maze. The objective is to solve the maze in a minimum amount of time. The game doesn't use any complicated geometry; everything is built using planes. The objects in the game are basically the floor and the maze walls. Two labels were also added to indicate the start and end of the maze. The end marker is animated, moving up and down the y axis. The scene has a background sky simulating a star field. The player is located where the main camera is, as s/he moves around the maze. The maze's floor is located in the xz plane. The figure below shows what the game looks like.
Figure: Normal view
As an aid to the player, there is a second camera, which is located high in the y axis and looks down on the maze. This camera can be used to view the maze from the top. It is complemented by a small square that indicates the player's location.
Figure: Top view
Another aid for the player is the ability to make walls semitransparent. By pressing the Fire button, the wall in front of the player is made semitransparent. The next time the player moves, the wall returns to the normal view.
Figure: Semitransparent wall
The game is designed for MIDP 2.0, and uses the GameCanvas
class. It contains a thread that is running continuously:
while(playing) { checkInput(); draw3D(); draw2D(); flushGraphics(); }
The method checkInput
will verify the state
of the keys and update the player's position if necessary. The player
can move forward and backward, and rotate to the right or left. The
player position will be used to update the main camera's location.
If the Fire button is pressed, the nearest wall in front of
the player will be selected and made semitransparent.
In method draw3D
, the scene graph is rendered
by binding the target, advancing the animation, and calling render(world)
, as follows:
try { g3d.bindTarget(g); binded = true; world.animate((int)(System.currentTimeMillis() - gameStart)); g3d.render(world); } finally { // release the target if (binded) { g3d.releaseTarget(); } }
The method draw2D
in turn will write text
to the upper and lower parts of the screen. It is important to do
the 2-D drawing after the 3-D rendering is ready, since upon clearing
the 3-D buffers the 2-D part will be removed. It is also important
not to mix 2-D and 3-D Graphics while the target is bound. Although
M3G does not forbid it, performing 2-D drawing commands onto a Graphics
object while bound has unpredictable results.