Instead of having a fixed set of mazes to play, the maze is randomly
generated every time a game is started. The maze is generated using a depth-first
search algorithm. Each row of the maze is stored in bits of a long value where
walls are 1s and spaces are 0s. That limits the maximum width of the maze
to 64. The algorithm starts with a maze that has all walls up, and it creates
a path between the spaces. The Maze
class contains the
maze generation code, and it also builds the necessary planes. For simplicity,
the maze is always square.
Square planes describe all the geometry in the world. The Plane
class
takes care of building standard squares located in the plane xy with vertices
from (-1, -1) to (1, 1). The square itself is made out of four triangles so
that it is double sided. This is important since the player can see the walls
from the front or the back. The Plane
class takes a Transform
object
that modifies the plane, making it suitable for the game. The createMesh
method
generates the actual Mesh with the desired location, rotation, and scaling
transformation.
The floor is built using a Transform
that rotates
the plane 90 degrees to locate it in the xz plane, and scales it to fit the
desired size. The floor's appearance is a mosaic-like texture that is repeated
ten times. Since the floor is large in terms of the scene, and the texture
is repeated many times, perspective correction is enabled.
The walls are built in the createPlanes
method
of the Maze
class. Each wall is a plane translated and
scaled to its designated position. Vertical walls are also rotated 90 degrees
on the y axis. The decision was made to give some sort of lighting to the
walls, making the lower part lighter that the higher part. There are several
ways to achieve this, for example by attaching a Material
and
using lights, or setting vertex colors to a similar, lighter shade in the
lower part. Another choice, and the one used here, is to use a gradient texture
that is lighter in the lower part. The texture is repeated across the length
of the wall. In parallel, an Appearance
was constructed
that uses the same texture but contains a CompositeMode
using
ALPHA_ADD-blending. This texture will be used when making a semitransparent
wall.
The start and end marks are located at the beginning and end of the maze. Each mark is textured using a rectangular image containing the "Start" and "End" labels. The textures contain an alpha channel for the area outside the text and their blending mode is set to ALPHA.
The location mark uses a texture clamped to the square and is set as not renderable. Whenever the game is set to use the top view, the square is made renderable and it is moved to the camera's position.