-
-
Notifications
You must be signed in to change notification settings - Fork 2
Chapter 14
This chapter examines how to develop a maze-based game, where the character is to collect all the coins in a maze whilst avoiding a ghost. The chapter expositions algorithm on how to generate random mazes using a depth-first algorithm, as well as finding the shortest path to the character from the ghost using a breadth-first algorithm
As suggested by the book the following features have been added:
- Added a menu screen
- Added more audio effects
- Added a timer to the UI
- Increasing ghost speed with time
- Hero health points
- Added more ghosts
- Implemented a larger maze
Bonus features:
- camera/character alignment
- camera zoom
- camera boundaries with zoom
Instead of using Tiled to create several maps a unique map may be generated each time a new level starts. Such procedural content generation greatly adds to replayability.
The general undertaking is as follows:
- Create a rectangular grid of rooms, all surrounded with walls
- Remove walls between rooms such that every room may be reached.
- Select a room as a starting location; mark it as connected and add it to the list
- While there are still rooms remaining in the list:
- Let
currentRoom
be the most recently added room from the list - If
currentRoom
has any unconnected neighbors- let
nextRoom
be a random unconnected neighbor ofcurrentRoom
- remove the walls between
currentRoom
andnextRoom
- mark
nextRoom
as connected; and - add
nextRoom
to the end of the list
- let
- If
currentRoom
does not have any unconnected neighbors, remove it from the list
- Let
- Remove additional random walls to create multiple paths to rooms.
This depth-first algorithm creates a random path through the maze for as long as possible and then starts anew.
The ghost follows the shortest path to the character. All rooms that are one square away will be checked first, and so forth. This is a breadth-first search algorithm. Pseudocode for the algorithm:
- Identify
startRoom
andtargetRoom
. - Set
currentRoom
equal tostartRoom
. - Mark
currentRoom
as visited, set its previous room tonull
, and addcurrentRoom
to a list. - While the list is not empty, do the following:
- Set
currentRoom
to the first element in the list and remove it from the list. - For each unvisited neighbor (called
nextRoom
) ofcurrentRoom
,- set
nextRoom
's previous room tocurrentRoom
. - end the algorithm if
nextRoom
istargetRoom
; and - if
nextRoom
is nottargetRoom
, then marknextRoom
as visited and addnextRoom
to the end of the list.
- set
- Set
A new camera functionality was added to BaseActor
, the ability to zoom:
fun zoomCamera(zoom: Float) {
if (this.stage != null) {
val camera = this.stage.camera as OrthographicCamera
camera.zoom = zoom
bindCameraToWorld(camera)
camera.update()
}
}
This required an update to the bindCameraToWorld
function, as it now also must take into account the zoom level:
private fun bindCameraToWorld(camera: OrthographicCamera) {
camera.position.x = MathUtils.clamp(
camera.position.x,
(camera.viewportWidth * camera.zoom) / 2,
worldBounds.width - (camera.viewportWidth * .9f) / 2
)
camera.position.y = MathUtils.clamp(
camera.position.y,
(camera.viewportHeight * camera.zoom) / 2,
worldBounds.height - (camera.viewportHeight * .9f) / 2
)
}
No new imports