![]() | |
PC Games
• Orb Tutorials
• 2D shoot 'em up Latest Updates
SDL2 Quest game tutorial
SDL2 Versus game tutorial
Download keys for SDL2 tutorials on itch.io
The Legend of Edgar 1.37
SDL2 Santa game tutorial 🎅
Tags • android (3) • battle-for-the-solar-system (10) • blob-wars (10) • brexit (1) • code (6) • edgar (9) • games (44) • lasagne-monsters (1) • making-of (5) • match3 (1) • numberblocksonline (1) • orb (2) • site (1) • tanx (4) • three-guys (3) • three-guys-apocalypse (3) • tutorials (18) • water-closet (4) Books ![]() Firmware HF-Tech's chips have changed the world. Embedded into the heads of over 90% of the world's population, they have cured autism, dementia, provided intelligence boosts, and helped to ease some of the more mundane tasks in life. Daniel Blair, hacker and Workshop member, however is not convinced that everything is as rosy as it seems. But is he looking in all the wrong places..? |
— Simple 2D quest game — Note: this tutorial assumes knowledge of C, as well as prior tutorials.
Introduction We're able to explore our world fully, and see how our exploration progress is going on the HUD we've added. It would be good if the Quest Log could be made more useful; being able to see which islands we've discovered, how many towns there are yet to find, and how much of each town we've explored would be great. So, in this part we're going to get to work on displaying this information in the Quest Log. Extract the archive, run cmake CMakeLists.txt, followed by make, and then use ./quest12 to run the code. As before, you can move around with the WASD control scheme. Open the Quest Log by pressing Tab. Use A and D to switch sections (the Quest and Inventory sections will be empty), and W and S to move up and down through the list items. Note how as you explore the world, the islands and towns sections show information about what we've uncovered. When you're finished, close the window to exit. Inspecting the code We have four sections on our Quest Log, but we will only be focusing on the Islands and Towns sections in this part. When we come to adding in quests, we will revist the others. There's quite a few new additions and updates that we'll need in order for the Quest Log to display our islands and towns (though thankfully this won't be nearly as involved as the previous part!). Everything in this part is done in questLog.c, so no need to go jumping around other files this time (we added everything in the previous part). So, let's start with openQuestLog:
We're initialising a number of new variables in this function. `show` is used to determine the section that we're currently viewing. itemNumber is the currently selected item in the list we're viewing, while itemNumberTotal is the total number of items in the active list. scrollTimer is used to control how fast we move through items when holding down W and S. highlightedTown and highlightedIsland are pointers to the town and island that we currently want to highlight on the map. Nothing taxing. So, let's move onto the updates to `logic`:
We're now testing the value of `show`, to see how we want to do, depending on which section is currently active. If it's SHOW_ISLANDS, we'll call doIslands. If it's SHOW_TOWNS, we'll call doTowns. Otherwise, we're setting both itemNumber and itemNumberTotal to 0, since the other sections don't do anything, and there are no items in them. Before we get to doIslands and doTowns, we've also made an update to doControls:
As we can now cycle sections, we've added in checks for our WASD controls. Pressing A or D will decrease or increase the value of `show`, cycling around when we fall below 0 and hitting SHOW_MAX. Any time these keys are pressed, we're resetting itemNumber, itemNumberTotal, highlightedTown, and highlightedIsland. We're also resetting the control key itself, so changing sections requires a key press. We can scroll up and down the list of items any time scrollTimer is 0. When pressing W or S we're decreasing or increasing itemNumber, and also resetting the scrollTimer value, to add a delay to the next move. Again, quite simple. Next, let's look at how doIslands works:
This is the function that will be called whenever we're on the Islands section. Here, we're ensuring that itemNumber is within the range of 0 and the number of islands in our world (numIslands), and also setting itemNumberTotal to this value. Next, we're looping through all our islands, setting selectedIsland to the item at the list index (`i`) that matches itemNumber. If the island is `discovered`, we also set it as the highlightedIsland. Our islands are stored as a linked list, hence the search loop. If our islands were stored as an array, we could jump directly to that index. Next, we have doTowns:
This works in a very similar way to doIslands, except we're checking all the towns in the Overworld (by looping over all the enities in the world, and checking their `type` - note that we only incremenet `i` if we encounter a town). The town will become the highlightedTown if it has been `discovered`. That's all our logic dealt with, so we can move on to the rendering. Starting with `draw`, we've made some tweaks:
Once again, we're testing the value of `show` to see what we want to display. We'll call drawIslands or drawTowns, depending on the section we're currently viewing. We'll start with drawIslands:
When it comes to drawing our islands (and towns) we'll want to display a certain number of items (NUM_DISPLAY_ISLANDS and NUM_DISPLAY_TOWNS). The items selected will be some of those that come before our current item and some that come after. We'll calculate this, and place the results into two variables called `start` and `end`. Next, we'll loop through all our islands, and display the name of those that are relevant to the current view (i.e., their place in the list falls between `start` and `end`, inclusive). In short, this means that as we scroll up and down our list, we'll be able to see which items come before and after the current, much like you'd select in other list UIs. If the current island is the one we have selected (selectedIsland), we'll highlight it with a coloured background. If it's yet to be `discovered`, instead of its name we'll print a series of question marks (and also make the text color, governed by `c`, grey). Otherwise, we'll draw the name of the island as expected. All this results in a list that we can scroll up and down, and will show which islands are known to us. Next, we have drawTowns:
As you can see, this works much in the same way as the islands, except that we're now displaying the names of the towns. Here, we'll also display a series of question marks if the town has yet to be `discovered`, and highlight the currently selected item in the list. However, something else we're doing is displaying a percentage to the right of the town name. This will show how many buildings have been visited in that town, so we know whether we've entered all of them, or if we need to return there to max out our exploration total. A nice feature to have, I'm sure you'll agree. It would be annoying to not know which towns have been fully explored yet. Next we have the changes to drawMap:
We're doing two new things here - we're making a call to highlightedIsland, and we're also testing if highlightedTown is not null, and calling highlightEntity if so. This means that if we have a town selected in our town listing (highlightedTown will be set in doTowns), we'll mark it on the map with a pulsing rectangle, in the same way we do with the player. Finally, let's look at highlightIsland:
If you're thinking this code looks familiar, it's because it was first added in Part 3 (and removed shortly thereafter). This code is largely the same as what existed back then, only that we're manipulating the colour of the island according to the value of `pulse`. Our RLE rectangles will have their alpha adjusted, so that they subtly flash their colour, rather than appearing solid. This will help to identify smaller island, with a gentle change of colour.
We're done! Our Quest Log now shows us information about the towns and islands we've visited and have yet to discover. This enables us to know exactly how much we've yet to find, and where to find it, which is another great quality of life win. It's also going to be come in very handy when we implement quests, as we will be able to see where we need to go while undertaking them. It's finally time we made a start on the quests. In the next part, we'll take a look at what needs to go into supporting a quest system in our game, and what other changes will be needed to the Quest Log, in order to make it all work. Purchase The source code for all parts of this tutorial (including assets) is available for purchase, as part of the SDL2 tutorials bundle: From itch.io |