Dana Vrajitoru
I355/C490/B590 3D Games Programming
I355/C490/B590 Homework 10
Due Date: Wednesday, November 20, 2024.
In this homework we will continue Lab 10
to implement the game Monster Run. Here is an an
example (http://www.cs.iusb.edu/~danav/teach/b583/monsterGL/) of
the intended result.
In this game, the player advances on a path where it can find tiles
containing either nothing special, or a treat (candy or pumpkin) or a
monster. They must start from the starting position and will win the
game when they reach the finish position. Here are the rules of the
game:
- The player advances by rolling a die and moving forward by the
resulting number of tiles.
- If the new position contains a treat, the player can take it or
ignore it. If they take it, it can be used in a monster fight as a
power up. Candy gives 1 point, pumpkins give 2 points.
- Only one treat at a time can be carried, so the player can choose
to ignore the currently available treat and keep the one they already
have.
- If the player lands on a monster tile, they can choose to run
away, in which case they go back 3 tiles.
- The player can also choose to fight the monster, with or without
the powerup that they carry. If they use the powerup, it is
consumed. This choice must be made before the fight.
- In case of a fight, the player rolls the die again to decide the
outcome.
- The monster's power is of 2, 4, or 5, depending on the type of
monster (1, 2, or 3).
- If the roll plus the powerup (or 0) add up to the monster's power
or more, the player wins the fight and their score is increased by the
difference.
- Otherwise they have lost and they need to go back a number of
tiles equal to the difference between what they rolled + powerup and
the monster's power.
- After this the player restarts from the initial roll to move.
- When the player is moved back either by fleeing from a fight, or
by losing a fight, its state goes back to idle. Thus, they cannot take
advantage of a powerup on that tile, nor have to fight a monster until they move again.
The game can be summarized by the following finite state machine,
where R = player's roll (the die in GameMaster), PU
= player's powerup, MP = monster's power, store = stored powerup.
Ex. 1. Implement the functionality of the game by doing the
following:
- Add all the necessary states in GameMaster in
the enum State list based on the finite state
machine.
- Complete the function SetButtons to show the 1, 2, or 3
actions available in each state. For example, in the state where you
landed on a monster, the buttons should display the 3 options: Roll &
use the powerup, simple roll, or run away.
- Complete the function Action1 that contains the action
associated with the first button in each state.
- Add two more functions Action2 and Action3 that
contain the functionality of the second and third buttons in each
state and associate them with the actions on those buttons.
- In the function Update, add a switch statement
based on the state and perform all the transitions that don't require
an action from the user. For example, if clicking Roll from
the idle state takes you to a state moveRoll, and if you want
to move without having to press a button, then in Update, if
the state is moveRoll, then move the player by the amount of
the die, then change to the appropriate state based on the tile you
land on, and call SetButtons again.
- Make sure that the score is updated and displayed properly and
that the info text displays the necessary information after each
action.
Here are some implementation suggestions:
Add attributes in GameMaster for the stored powerup, for
the powerup to use in a fight, the score, the monster's power.
Add a function MoveBy that moves the player by a given
number of tiles. This function would have to update the value
of playerPos, make sure it's not outside the bounds of
the tiles array, and then call PlacePlayer with the
new position. Note that when moving, if the result should be a tile of
a negative index, then you should place the player back at the
starting position 0. Similarly, if the resulting tile number is larger
than or equal to the size of the array of tiles, then you should place
the player on the last position.
For bigger actions, it's probably better to define a separate
function. For example, you could define two functions
called MoveAction and FightAction to handle those
actions. Then you can call them in the appropriate places from the
Action functions.
The FightAction function would roll the die and then
decide whether the fight is won or lost. In case of a win, it would
update the score with the difference between the player's hit (powerup
plus die) and the monster's power. In case of a loss, it would have to
move the player back by the amount of the difference.
The MoveAction function first moves the player by that
number of places and then based on the type of tile it lands on, goes
into another state: monster, powerup, or idle. The buttons and info
are updated accordingly.
Ex. 3. (optional) Any additional features at your discretion
for up to 3 extra credit points. For example, if you want to make the
player move continuously from one tile to the next, you can look up
the function
Vector3.MoveTowards to help with that.
Turn in to Canvas: a zip file with the
script GameMaster.cs and a Windows or WebGL build.