Hotel Havok was my final project for the first year of my course at university and it was my first attempt at creating a endless runner using STL. The game came out well overall and I learnt a lot about how STL worked from it. I took inspiration from games like Bit.trip and Cookie Run to create the gameplay loop.
This project was one of the most interesting experiences I’ve completed as implementing some of the mechanics used concepts I’ve never needed to calculate before.
Movement Mechanics
The movement mechanics at the players disposal is the key for moving forward past the obstacles. There are four different movement options; jumping, sliding, punching and pressing. These would let you get past the trolly, ladder, door and elevator respectfully. Most of the movement mechanics consisted of a simple change in sprite and a change to a Boolean value, but the jumping mechanic was more complicated than that.
The jumping mechanic required me to consider gravity and upward velocity which took me a while to wrap my head around.
void Character::Update(float deltaTime, SDL_Event e)
{
//If the current action being performed by the player is jumping, the jump velocity will be decreased by Gravity and the y position of the character is reduced by the jump velocity
if (m_current_action == JUMPING)
{
SwapTexture("Images/Player Jump.png");
m_jump_velocity -= GRAVITY * deltaTime;
m_position.y -= m_jump_velocity * deltaTime;
//Once the character's y position returns to the starting y position, the current action is set back to running and the position is set to the start positions.
if (m_position.y > startPos.y)
{
m_current_action = RUNNING;
SwapTexture("Images/Player Run.png");
m_position = startPos;
}
}
Obstacle Spawner
I created a kind of randomised obstacle spawner which would pick an obstacle, the obstacles being a trolly, ladder, door and elevator, and would send them towards the player. The player would then need to react to the obstacle in the correct way; a trolly needed to be jumped over, the door needed to be punched, the elevator could be shut and the ladder needed to be slid under.
if (m_canSpawn == true && m_spawnTimer > 0)
{
m_spawnTimer -= deltaTime;
}
//If the spawn timer is less than zero and there is no obstacle spawned, a random obstacle is selected and bool values are changed
if (m_spawnTimer < 0 && m_ObjSpawned == false)
{
m_canSpawn = false;
m_ObjSpawned = true;
Choice = ChooseObst(rand() % 5);
}
Score System
The program also uses a score system that affects the speed at which the background and obstacles move, ensuring that the player needs to remain focused as one mistake can end their attempt. This score is increased by successfully dealing with the obstacles presented to them and all obstacles give the same amount of points.
if (m_trolly->m_position.x > m_DespawnCoord)
{
m_trolly->m_position.x -= m_speed * deltaTime;
/*cout << m_trolly->m_position.x << endl;*/
}
else
{
m_canSpawn = true;
m_trolly->m_position.x = m_startPos.x;
cout << "Trolly moved!\n";
m_spawnTimer = m_ObstCooldown;
m_ObjSpawned = false;
m_score.UpdateScore(20);
}
Artwork
Lastly, the artwork for the background and all of the obstacles were created by me using a software called “Aseprite”.







The player sprites was from a sprite pack I purchased from Itch.io.