Dodge the mummy guardians to escape!
Due date: Suday, December 1st (11:59pm)
The goal of this project is do hands-on coding of a finite state machine and related game engine code in the context of game AI. Objectives:
Build finite state machine infrastructure for the Dragonfly game engine.
Create game specific states that use the infrastructure to provide actions appropriate for a pre-defined game.
Code select methods that provide for needed transitions between states.
Test the state machine infrastructure in the pre-defined game.
In Pyramid, you control the Hero, seeking to exit the already plundered tomb. Mummies wandering for all eternity can sense interlopers and seek them out, attacking them until the intruders are dead, dead, dead. Unfortunately for the Mummies, magical Ankhs are scattered throughout the crypt and cause them to cower in fear. Does the Hero make it to the exit safely? The only way to find out is to play ... Pyramid!
You are provided with the framework for the game, including the game world with obstacles, the hero that responds to keyboard control, mummies to be dodged and that cause damage, the ankhs that can be picked up, and the exit that causes the game to end. What is not implemented is the behavior (AI) for the mummies. You are to implement their AI in the form of a finite state machine.
You work solo for this project.
Development must be in C++ using either your game engine from Project 2 or the Dragonfly game engine from Project 1.
Tip! If you want to use your engine, you may want to make a static library out of your code. You do not have to do this, but doing so will keep your project 3 separate from your engine code. To do this:
With Visual Studio, you take your existing engine project and convert it into a static library via some project options. See this image.
With Linux or Mac, you compile all your .o
files together using the "ar" command. Example:
ar rcs libdragonfly.a Box.o Object.o ...
The result will be a static library you can link in to your Pyramid (or other game).
To prepare for the project:
Download the game framework code from one of:
Extract by unzipping. Tip! If you put it at the same directory level as Project 1 - Saucer Shoot, the accompanying Makefile and Visual Studio solution should allow compilation without changes.
Compile. Adjust any #include
and library directories as needed.
Windows link Step #3b, #3c, #3d
Linux link, Step #4 "Edit the Makefile"
Mac link, Step #4 "Edit the Makefile"
Run. Windows users will need to ensure access to the SFML dll
files.
Once successful, you should see a game screen similar to:
The player controls the Hero (in the upper left corner) with arrow keys. Running into the white Mummies will deplete health, depicted at the top of the screen. When health reaches 0, the Hero dies and the game exits. Running over a cyan Ankh starts a countdown timer from 10, but has no other effect at the moment. Running into the green Exit allows the Hero escapes and the game exits.
Create base classes that are used by all Dragonfly state machines.
StateMachine
State
This includes both .h
and .cpp
definitions. While these class could be in the Dragonfly engine, but it is ok to keep them in game code for this project.
Tip! See the class slide deck for more information.
Create Pyramid-specific classes for the Mummy derived from State
:
StateCower
StateAttack
StateSeek
StateWander
Stub all of the above out (meaning, make the full .h
files but just provide empty definitions in the .cpp
files) and make sure it compiles and runs.
In the Mummy
class, add attributes for each. e.g.,
// In Mummy.h.
private:
StateMachine m_machine;
StateCower m_state_cower;
and add methods to get a pointer to each state. e.g.:
// In Mummy.h.
public:
StateCower *getStateCower();
// In Mummy.cpp
StateCower *Mummy::getStateCower() {
return &m_state_cower;
}
In the Mummy constructor, set the state machine (m_machine
) owner and the initial state to the "wander" state (m_state_wander
).
In the Mummy eventHandler()
, handle the step event to update the state machine (m_machine
) each step.
Again, make sure this all compiles and runs before proceeding.
Tip! See the class slide deck for more information.
Each Mummy should exhibit the following behavior.
By default, the Mummy should be slowly wandering around the pyramid, pausing occasionally to do nothing. The Mummy appears white.
When the Hero is near enough to the Mummy, the Mummy senses the Hero (even through walls!) and seeks the Hero out. While seeking, the Mummy still wanders, but moves more quickly and stops less. The Mummy appears yellow. If the Hero goes out of sensing range, the Mummy goes back to wandering.
When the Mummy can sense and see the Hero (a direct line of sight with no walls in between), the Mummy moves quickly directly towards the Hero to collide and cause damage. The Mummy appears red. If the Hero can no longer be seen (e.g., the Hero dodges behind a wall), the Mummy goes back to seeking.
If the Hero has an Ankh, the Mummy cowers in fear, not moving. The Mummy appears cyan. Once the Ankh has expired, the Mummy resumes whatever it was doing before.
A general methodology for an agent that has artificial intelligence is the "sense-think-act" model. With this model, the agent senses information about the world (e.g., what can be seen or heard), then thinks about what to do (e.g., attack or flee) and then acts appropriately (e.g., run away from an enemy).
Tip! Before starting the AI implementation below, familiarize yourself with the code base.
Mummy sensing is done by implementing "seeing" and "sensing" capabilities in the Mummy.
A Mummy can "sense" the Hero if they are within a certain distance.
A Mummy can "see" the Hero if they are within the sense distance and there are no walls blocking line of sight.
Mummy thinking is done by using information from sensing to decided upon what state transitions to make in the Execute()
methods in each state.
If a Mummy can "see" and can "sense" Hero, then enter the attack state.
If a Mummy can "sense" but not "see" Hero, then enter the seek sate.
If a Mummy can neither "sense" nor "see" Hero, then enter the wander state.
Mummy acting is done by implementing actions that move the Mummy in the Execute()
methods in each state.
Wander action. Example: Move randomly. Stop often.
Seek action. Example: Increase speed, keep wandering but stop less.
Attack action. Example: Set the Mummy's direction towards the player and increase speed.
Tip! Draw a picture of the states and transitions before you implement them and refer to the picture while coding.
The exact actions taken when acting (e.g., how, exactly, a Mummy wanders and how fast) is up to you. Similarly for the implementation of seeing and sensing and the ranges. The behavior just needs to achieve the spirit of what is described for a Mummy.
Tip! The file game.h
has some game parameters you can use and adjust to suit the gameplay experience you desire.
It should be easy to see the Mummy states in the final game implemented (note, this is not always desirable for games but is fine for this project). This means Meaning wandering Mummies should be visible and the Hero should be able to move to trigger seeking and attacking behavior. The game does not have to be balanced (it can be too easy or too hard to get out).
However, if you are interested in using the Pyramid (with AI) as the foundation for a game, there are numerous possibilities to extend what is already started:
Add other kinds of undead, such as Zombies that only wander or Ghouls that are smart enough to go around obstacles to attack the Hero.
Add sounds, such as sound effects (footsteps) and music (background ambiance) to enrich the experience.
Add a treasure where the Hero must get the treasure before the exit spawns.
Make the pyramid a maze, where the Hero must navigate the maze to the center to get out.
Add darkness where only objects within a certain radius are visible to the Hero. Mummies can see in the dark, of course.
Again, all of the above are optional and not required.
Your assignment is to be submitted electronically via Canvas by 11:59pm on the day due. You must hand in the following:
.h
files.Important! Make sure to include all the original code, too, not just the code you added.
Important! Make sure your code is well-structured and commented. Failure to do so will result in a loss of points.
Important! You must include Dragonfly (whether your own or the downloaded version) when you submit. You do not need to submit the SFML files.
A README.txt
file explaining: platform, files, code structure, how to compile, and anything else needed to understand (and grade) your game.
Important! Make sure your name and WPI user name is included in the README file.
Before submitting, "clean" your project:
Build
-> Clean solution
make clean
This will remove all the .o
/.obj
files. Failure to do may mean you file is too big to submit!
Use zip
to archive your files. For example:
mkdir lastname-proj3
cp * lastname-proj3
// copy all the files you want to submit
zip -r proj3-lastname.zip lastname-proj3
// package and compress
To submit your assignment (proj1-lastname.zip
) via Canvas:
Open: Assignment - Project 3 Click:
Submit Assignment
Click:Choose File
Select the zip file:proj3-lastname.zip
Click:Submit Assignment
Important - you must click the Submit Assignment
button at the end or your file will not be submitted!
When successfully submitted, you should see a message similar to:
Submission
- Submitted!
Dec 3 at 11:51pm
States:
Wander - 20% : The white Mummy wanders in a reasonable fashion, stopping sometimes.
Seek - 15% : The yellow Mummy wanders more quickly, stopping less often.
Attack - 15% : The red Mummy moves quickly seeking collisions with the Hero.
Cower - 10% : The cyan Mummy stops, cowering in place.
Transitions:
Sense - 10% : A Mummy can sense when a Hero is within range.
See - 20% : A Mummy can see a Hero when within range and no obstacles block sight.
Cower - 5% : The Hero has the Ankh.
Resume - 5% : The Hero stops having the Ankh.
100-90. The submission clearly exceeds requirements. The game compiles and runs without problems. The Mummy states are all easily verifiable and the transitions work as expected. Actions during the states clearly work as required.
89-80. The submission meets requirements. The game compiles and runs without problems. The Mummy states are verifiable and the transitions mostly work as expected. Actions during the states work as required.
79-70. The submission barely meets requirements. The game compiles and runs but there be warnings. The Mummy states and transitions may not be easily verifiable. Actions during the states work may not work completely as required.
69-60. The project fails to meet requirements in some places. The game compiles but with warnings. The Mummy states and transitions are not verifiable or are missing. Actions during the states do not always work completely as required.
59-0. The project does not meet many of the requirements. The game either does not compile or crashes sometimes. Some Mummy states and transitions are missing. Actions during the states often do not work as required.