• 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
— Mission-based 2D shoot 'em up —
With our base intermission support done, we can begin implementing the various sections. We're going to start with the planets section. This will display a bunch of planets, orbiting a central star. The planets themselves will be labelled and can be clicked on by the player. Later, missions will be connected to the planets. For now, we're just going to deal with the display, motion, and interaction.
Extract the archive, run cmake CMakeLists.txt, followed by make, and then use ./shooter3-15 to run the code. You will see a window open like the one above. Use the mouse to control the cursor. Click on a planet to select it, resulting in a green pulsing box outlining it. Its name will be shown at the top of the screen, in a larger font. There's nothing more to do for now. Once you're finished, close the window to exit.
Inspecting the code
Those who played Project: Starfighter will recognise this screen (and some other screens to come!). This screen will be where we select planets, to play missions. Clicking on a mission in future will affect the comms icon, and whether it can be selected. This screen is also not yet complete, but will be in future. For now, let's look at how it works.
Starting with structs.h:
We've added a struct called Planet, to hold our planet data. `name` is the name of the planet, `texture` the texture image it uses, `x` and `y` are its position. `orbit` is the current orbital position (technically also its position!). `speed` is how fast the planet is orbiting the star. `distance` is how far out from the star it is.
We've also added a struct to hold our intermission data:
The struct will hold just our list of planets, and a reference to the currently selected planet (selectedPlanet).
Now for planets.c, the new compilation unit that will handle all our planet section logic. A number of functions exists in this file. We'll start with initPlanets:
We're starting by clearing Intermission's selected planet, setting a variable called selectedPlanetPulse (the variable that controls the pulsing green square) to 0, and loading the texture for the star in the middle of the screen (starTexture). All good and simple.
Now for doPlanets:
We're looping through all our planets here (via Intermission's planet linked list), and increasing the value of each one's `orbit`, according to their `speed`. We're then calculating their positions (`x` and `y`) using some trigonometry, making use of the planet's `orbit` and `distance` variables (in short, we're making them spin around the near-middle of the screen). Next, we're testing if we've clicked on any of the planets, and setting Intermission's selectedPlanet to be that planet. Lastly, we're updating the value of selectedPlanetPulse, to make our green square pulse.
Easy enough, we're just making our planets orbit and checking if we've clicked on any.
Now for drawPlanets:
We start by drawing our star in the middle of the screen. Next, we loop through all our planets, and draw both their orbital path via drawCircle (feeding in the planet's `distance` as the radius), and next drawing the planet itself. Following that, we loop through all our planets a second time. This time, we're drawing their names. We're doing it this way so that planets don't draw over the label of another (even if it's only for a brief moment).
With the planets drawn, we're testing if we have a planet selected. If so, we're drawing a box around it. We start with the default position and size (applied to `r`, an SDL_Rect), and then modify these values based on the value of selectedPlanetPulse and a call to sin. With the box drawn, we finally draw the name of the planet at the top of the screen, in a larger font size.
The last function to look at is loadPlanets:
Just some standard JSON data loading going on here. Our planets start at a distance of 100 from the middle of the screen, and will increase by a small amount for each planet (the width of the planet itself, plus 8). The planet's `speed` is based on its `distance`, where the further out they are the slower they will orbit. We're also randomizing the value of `orbit`, so the planets don't all start perfectly aligned, which, while not wrong, would look a bit odd.
That's our planets all handled (for now). The last thing we need to do is incorporate it into our intermission screen. So, turning now to intermission.c, we've first updated logic:
We've added a switch statement, to test which `section` we're currently in. We're only handling IS_PLANETS right now, so we've added that clause, to call doPlanets.
We've also updated `draw` with a similiar change:
Here, we're calling drawPlanets.
There we go, our first section done. Once again, there are further changes to come, but most of this screen is done for now. We can view our planets, and select them.
In our next part, we'll look at the comms screen, where the player will receive their mission briefing. This will eventually be connected up to selecting planets, so that one can view the mission to be undertaken, and then start it.
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: