Skip to main content Link Search Menu Expand Document (external link)

Theme: auto

Health, Damage, and Player Death

Now we’ll add actual logic to HealthComponent.

First, add the following member data:

  • A float for the health

  • These two callback functions (remember you need to include <functional>):

    std::function<void(const Vector3&)> mOnDamage;
    std::function<void()> mOnDeath;
    

We last did callbacks back in Lab 6. One thing that’s a little different this time is the mOnDamage callback takes in a parameter this time, rather than no parameters.

Then add/change the following functions:

  • Make the constructor take in the starting health value (default to a value of 100.0f)
  • Add a setter for both callbacks
  • Add a GetHealth function which returns the health
  • Add a IsDead function which returns if health <= 0.0f
  • Add a TakeDamage function that takes in a float for the damage amount as well as a const Vector3& for the location the damage is coming from

The code for TakeDamage is nothing fancy, and pretty similar to what:

  1. Don’t do anything if already dead
  2. Subtract the damage amount from the health
  3. Call the mOnDamage callback if it’s set (passing in the location as a parameter)
  4. If dead, call the mOnDeath callback if it’s set

Pellets and Death

For the player’s HealthComponent, set the mOnDeath callback so that it forces the game to reload the level. Remember that the syntax for setting a callback is like this:

health->SetOnDeath([this] {
	// Code you want to run here
});

For the turret’s HealthComponent, set the mOnDeath callback so that it calls Die on the turret.

Now, in Pellet::OnUpdate:

  • If the pellet collides with the player, call TakeDamage on the player’s HealthComponent, passing in 100 for the damage and the pellet’s position as the location
  • Similarly, when detecting a collision against a collider, if the collider has a HealthComponent, first check whether the object is alive:
    • If it’s dead, ignore the collision (this is so the pellet doesn’t keep hitting a turret that’s dead)
    • Otherwise, deal 100 damage with the pellet’s position as the location

Confirm that if you get hit by a pellet, the level reloads. Similarly, confirm that turrets will die when hit by a pellet, and that any subsequent pellets go through the dead turret:

Falling and Death

Change the code in PlayerMove::Update that checks if the player’s z is too low, and instead of directly reloading the level, cause the health component to take Math::Infinity damage from the location of the owner.

There is no pit you can fall through in this level, but it’s hard to mess this up so it should be fine!

Turrets and Firing

Now that we actually have health, we can make the turrets do damage!

First, in the helper function that tries to acquire a target, do not acquire a target if it’s health component says it’s already dead.

Next, in UpdateFiring, if the target is still valid (meaning you didn’t switch to search) and the health component doesn’t say the target is dead, deal damage every 0.05 seconds. Make sure that when you initialy change to the Firing state, you reset the cooldown to 0.05.

Every time the turret deals damage, it should deal 2.5 damage and use the GetWorldPostion() as the location where the damage is coming from.

Confirm that if you stand in front of a firing turret for a few seconds, you die.

Testing the Input Replay

Finally, confirm that you can pass the input replay validation mode. You’re not required to pass validation mode for an A, but ideally it work so that we can quickly test the main mechanics. For best results, you should start the replay as soon as you load into the game (otherwise you may get unexpectedly killed since the pellets do not reset on starting the replay). It should look like this:

Once you’ve pushed your code, you should review the grading specifications to confirm you’ve satisfied them.