• 2D shoot 'em up
SDL2 Santa game tutorial 🎅
SDL2 Shooter 3 tutorial
The Legend of Edgar 1.36
SDL2 map editor tutorial [UPDATED]
TBFTSS: The Pandoran War - Amiga OS4 Port
— A simple turn-based strategy game —
The final core aspect of our combat is to handle the player units' death. Our ghost can currently hurt them, but not kill them. We'll be changing that in this part.
Extract the archive, run cmake CMakeLists.txt, followed by make, and then use ./sdl2TBS11 to run the code. You will see a window open like the one above, showing three wizards in a small room, surrounded by walls, as well as a white ghost. Play the game as normal. Allow one of your wizards to be killed. Notice how they leave behind a little tombstone where they died, and the wizard is no longer selectable; they've been removed from the game completely. If all your wizards die, the ghost will walk around by itself. Once you're finished, close the window to exit.
Inspecting the code
Adding in the player death handling is a very simple process, as we'll see.
Heading first, as always, to defs.h:
We've added in ET_TOMBSTONE, to represent the tombstone that is put in place when the player dies.
Next, let's take a look at objects.c, a new compilation unit we've created. This contains all the code to handle the tombstone. We're calling the file objects.c in case we wish to add more decoration, objects, and such in the future. Starting with initTombstone:
Not a lot to say about this function. We're setting the passed-in entity's type to ET_TOMBSTONE, marking it as `solid`, and setting its `texture`, `tick`, and `draw` fields.
The `tick` function is nothing special:
An empty function. Our doEntities function expects this to exist and be set for every entity, so we're assigning it (we could have always had doEntities test for NULL before calling, so I suppose this is just a matter of style).
The `draw` function comes next:
We're just rendering the tombstone the same way as other entities. Nothing special.
Now, let's move over to mage.c, to see how we're using our tombstone. We've updated the `die` function:
Before, this function was completely empty. Now, we're doing several things. We're setting the mage's entity's `dead` flag to 1, and calling addDeathEffect, passing in the mage's screen coordinates (so, much like what happens when a ghost is killed). After that, we're calling initEntity, and passing over "Tombstone" to have our entity factory generate us a tombstone. We're assigning this to a variable called `tombstone`. We're then setting the name of the tombstone entity to be the name of the mage who died, plus "(RIP)", and the `x` and `y` positions to be those of the dead mage. Right now, there's no way for us to see data about the tombstone, but we'll fix that when it comes to updating the HUD.
Pretty simple so far, right? Once the mage's `dead` flag is set, they will be removed from the game during the doEntities loop, so we need do nothing more but put the tombstone in the spot where they stood.
Two more things to change and we're done! Important ones, though. Let's jump over to player.c, where we've updated cyclePlayerUnits:
This function is currently controlled by the mouse wheel, and allows us to loop through all our mages without having to click on them. Since they live in an entity pointer array, they won't be removed when the `dead` flag is set. However, we can still test this flag to see if they are a valid selection.
To handle this, we're using a do-loop to keep cycling through our mages until we find one whose `dead` flag isn't set. We enter this loop after locating the currently active mage (in effect, we've added in 4 lines). This check is important to ensure we don't select a dead mage, and then try and control them.
One final change to make and we're done! Heading now to stage.c, we've updated endTurn:
Another do-loop! This one is again important. After calling resetUnits, we're checking if Stage's currentEntity is set. If so, we know that at least one unit for whose turn it is is alive. If they aren't, we'll swap turns again. What this means is that if all the ghosts are dead, the AI won't get a turn. Equally, if all the mages are dead, the player won't get a turn. This is actually just a temporary change until we put in better victory and defeat logic in. This is good right now, as it will stop our game from crashing if there are no wizards left for the player to control, always passing the turn back to the AI.
Another part done, and another important aspect of us game handled. Our mages can now be killed and the game can effectively end for the player. What we should do next is add some items to our game, for the player to collect. It's not uncommon to have items such as ammo pickups and health kits littering the battlefield, so in our next part we'll look into item handling.
The source code for all parts of this tutorial (including assets) is available for purchase:
It is also available as part of the SDL2 tutorial bundle: