In this chapter we are using GB Studio version 4.1.3 to make a simplified version of Missile Command: a cannon at the bottom of the screen will fire projectiles at objects falling from the sky, with the goal of protecting the planet’s surface. We’ll achieve this using the “Launch Projectile” and “Attach Timer Script” commands.
You can find the project’s source code at the end of this article, where you’ll also be able to reuse the PNG tiles I’ve created or review the entire project if you have any questions.
“The Shot”
Let’s begin with the most fun part: the shooting. The idea is that the cannon fires towards where we are pointing with the cursor. Normally, we would need to calculate the length of the two sides of the triangle formed and then find the arctangent, but since we are clever and lazy developers, thanks to Maltby, we can simply use the new “Launch At” function in the Launch Projectile command. We’ll click on “Target actor” and set the Player as the target.
If you’ve never used the Launch Projectile command before, can you guess what it does? That’s right, it shoots projectiles. It’s the most commonly used command when we want our character to shoot projectiles. You need to select the sprite for your shot, who is shooting it, in which direction it’s going, which collision group it belongs to, and which group it can hit.
Here’s how we would proceed:
- Create a new scene.
- Set the scene type to “Adventure” to take advantage of zone entry triggers (more on that later).
- Add an actor to serve as the cannon at the bottom of the screen, for example, at coordinates x=9 and y=16.
- Go to the scene’s “On Init” section and add the command “Set Actor Collision disable”; we don’t want the Player (cursor) to interfere with our shots.
- Add the command “Attach Script to A Button” and inside, place the command “Launch Projectile” and set the properties for the projectile as desired (I’ve set them as shown in the picture).


The important part is to select “Launch At” under the “Source” section of Launch Projectile and choose “Player” as the target
- Finally, add a “wait” command of 0.5 after the “Launch Projectile” command to avoid overwhelming the screen with too many projectiles if using DMG mode, plus it adds a touch of difficulty.
Now, if we try running the project, we should have a functional cannon that shoots towards the cursor. It would be a good idea to add a collision line from position (0,17) to (19,17) to prevent the cursor from reaching these areas, which would make it unrealistic to shoot downward.
“The Meteorite”
Now we arrive at the second fun part: the object to shoot at. We’ll make an actor appear at a specific position and move in a straight line toward our planet. We’ll place our new actor, for example, at position x=4 and y=1 (but later we’ll move the sprite higher in the Sprite Editor so it appears from the top of the screen rather than suddenly in the middle).

In the actor’s properties, we’ll assign a collision group “1” and get to work creating the commands that will determine what happens when our shot hits it. The idea is that it disappears with a visual effect (we’ll use another projectile for that). To do this, go to the “On Hit” tab for Group 3 (or the one you assigned to your projectile) and add the following commands:
- “Variable set to true,” selecting a new variable called Meteor1_destroyed. (This will be used in the next step to know when the actor can be replaced).
- “Deactivate” and “Self,” so it disappears from the scene.
- (Optional) Launch Projectile with the meteorite as the source, a very short lifetime, and directed upwards. The idea is for the object to disappear and show a visual effect representing its destruction. I used these parameters (see photo).
- Finally, “Play Sound Effect,” which will play when the meteorite is destroyed. Everyone loves sound effects!

Now we’re done with the script inside the actor, but there’s still one important part left: the movement and respawn of the meteorite. To do this, go back to the main scene script in “On Init” and use two commands that shouldn’t scare us: “Attach Timer Script” and the “Random” function. The Timer Script is a valuable resource for repeating a process multiple times. You specify how often it repeats, and inside, you can add all the processes that will occur each time it triggers.
Here’s how we could implement it:
- Add the command “Attach Timer Script.” Set the interval to 0.5 seconds (this is fine since it will only act if the meteorite is destroyed). Inside “On Tick,” write everything that should happen.
- Start with the “If variable is True” command and select the previously mentioned variable, Meteor1_destroyed.
- Inside the condition, the first thing is to use the command “Set variable to False” for Meteor1_destroyed, to revive it.
Now comes one of my favorite resources: “Random.” We can give a variable a random value within the range we need. How exciting! What value will it get?
- Next, add the “Math Functions” command, create a new variable (meteor_randomx), and set its “Value” to “Random” between 0 and 18 so it can appear at any position on the horizontal axis.
*If you need more help on how to use Random values or just want to see another example, check out this article: GB Studio: Getting Started with Games – Chapter 1 – GB Studio Central - After that, use the command “Set Actor Position,” set the actor to Meteor, and click the “#” symbol to select a variable instead of a fixed value. The variable, of course, will be meteor_randomx.
- Finally, use the command “Activate Actor” and activate the meteorite, which we’ve likely
deactivated after firing. Then, with the “Actor move relative” command, move the Meteor actor 18 positions along the Y-axis (0,18).This command will move the specified number of spaces on the X and/or Y axis from its current position, regardless of where it is.

Now we’ll have a meteorite that falls toward our planet each time it’s destroyed. But what happens if we don’t manage to shoot it down before it reaches the surface? That’s what we’ll create next.
“You Missed”
You failed, and the meteorite has reached the surface. How about a good shake to get us back on track? We’ll check if the meteorite has made it to the end of its path:
- After the “Actor Move Relative” command, use the “If variable is False” command, checking for Meteor1_destroyed. If it’s false, it means we didn’t destroy it, so inside the condition, we’ll include everything that happens:
- Use the “Camera Shake” command and, if you like, maybe add a sound effect too. (The Camera Shake command is another favorite of mine; it creates a shake of customizable intensity).
- “Deactivate Actor” to deactivate the meteorite so more can appear with our Timer Script, and set the variable “Meteor1_destroyed” to “True.”
Finally, just add the “Variable set to True” command for Meteor1_destroyed at the start of our program (just below where we disabled player collisions) along with a “Deactivate Actor” command for the meteorite, so that right at the start of the game, it will appear unexpectedly thanks to our Timer Script.

With this, we now have a fully functional game! But if you want to embellish it with details like points, lives, and informative text, keep reading.
Turning it into a Game
The greatness is in the small details. In this section, we’ll add some indicators or decorative elements. We’ll introduce new variables to store the score and remaining lives. It will be easier to understand if we organize everything into Event Groups:
- First, add an “Event Group” at the start of your main scene’s “On Init” script and call it something like “init positions,”, it should look like this:

- Next, create another Event Group called “init values,” where we’ll reset all our variables.
- Create a “score” variable and set it to 0. Create two more variables that will be used to split the score into two pairs of digits. In my case: “score(ten,uni)” and “score(tho,hun)”. We will explain how to use them later.
- Create a “lives” variable and set it to 2.
- As we did with the score, we will create a new actor to represent the lives and we will also set the animation speed to None. And then, we will assign the sprite to the variable $lives. The thing is to open the sprite editor and arrange the different frames of the sprite in order: for example in frame 0, the sprite will be empty. In frame 1, one life icon will appear and in frame 2, two life icons will appear.
- Finally, create a “restart” variable and set it to “False.” This will allow the “start” button to restart the game only when we actually run out of lives.

A wise piece of advice is to try to stay organized. It will make finding errors or understanding the project easier if you come back to it years later.
- We will add a new actor which will serve as a visual aid to know when we can press the START button to start the game or even to warn when our game is over. We will simply create a sprite with a text that shows “Press Start” in frame 0 and Game over in frame 1.
- After the group event, we will add a pause in the script using the “Pause Script until button pressed” command, so the game doesn’t start until we press, for example, the “start” button.
- After this command, we will add a small group of commands that will take place if the “start” button is pressed. We will achieve this using the “If Button Held” command, where the “start” button will be used. Inside, we will write the following:
- “Seed random number generator”: It’s a good idea to ensure the random variable works correctly.
- Play Sound Effect: Add a sound effect that indicates the start of the game.
- Play Music Track: Add an exciting background music track to create some excitement for the game. In my case, I used both SFX and music from free assets provided by our friend Beatscribe (visit his Itch.io profile where you’ll find high-quality music and sounds):
- “Seed random number generator”: It’s a good idea to ensure the random variable works correctly.
- Finally, we will remove the “Press Start” actor, simply by using the command “deactivate actor”.
High Score:
If we want to keep track of points for destroying each meteor, we’ll go back to the “On Hit” script, group 3 within our Meteor Actor, and add the following:
- “Increment variable”: Add 1 to the “score” variable to increase the score.
- Here we will perform the calculation required to separate a number that can reach up to 4 digits in two pairs of 2 digits. On the one hand we would have the variable $score(ten,uni) which would be equal to score%100 and the variable $score(tho,hun) which would be equal to $score/100.
- We will use the Set Animation Frame command again but this time to represent numbers. Therefore we will have to set each frame of a sprite to show numbers from 00 to 99 (it is laborious but then you can reuse it for other projects).
- So the actor responsible for displaying thousands and hundreds will be placed in the frame dependent on the variable $score(tho,hun) and the one for tens and units on the variable $score(ten,uni).
- Finally, optionally, I wanted to add another “Switch” as a “level up” mechanic, increasing the meteor’s movement speed according to the number of points. In my case, I used the “Actor set Movement Speed” command and gradually increased it by 0.125 at scores of 5, 10, 20, 30, 50, etc.

Continue or Restart the Game:
Almost there! We just need to add a few commands within our “Timer Script,” right after the commands included in the condition “If meteor1_destroyed = False”. The idea is that when the meteor is not destroyed and reaches the planet’s surface, it should subtract lives and check if we still have any lives left to continue the game.
- First, we will use the “Variable Decrement” command to reduce the “lives” variable by 1.
- Next, we will compare the “lives” variable to see if it’s less than 0 (if ($lives < 0)), because if that’s the case, the game will be over. Inside this condition, we will write the following:
- First, we will add the “Stop Music” command to stop the music and cut the mood a bit, followed by a “Play Sound Effect” with a discouraging sound effect for our embarrassment.
- We will change the value of the “restart” variable to True. This way, our start button (which we will modify below) will behave differently when “restart” is True.
- We will also reset the meteor’s movement speed to 1 (in case we’ve surpassed a level during the game). This will be “Actor (meteor) Set Movement Speed” to 1.
- Now we will assign the value 0 to the informational text sprite to show “game over” instead of “press start”.
In the “Else” section within the condition “If ($lives < 0),” we will handle the situation where we failed to stop the meteor but still have lives remaining. If there are still lives left, instead of “game over” we will perform the same process as before but this time it will be frame 0 which shows “Press Start”.

- Immediately after, we will activate the text actor that will show “Game over” or “Press Start” depending on the case.
- We will update the actor’s frame representing the lives using the Set Animation frame command and make it depend on the $lives variable.
- Now, we will place the famous “Pause script until button pressed” and choose “Start” as the button to press in order to continue. After that we will deactivate the actor Text.
Next comes an important step: we are going to add a specific script for the situation where we run out of lives (so, we have changed the “restart” variable to True). It would go like this:
- We will add the command “If variable is True,” setting the variable in question to “Restart,” and inside, we will add the necessary commands to reset the game:
- We will set the “restart” variable back to false. (variable set to false)
- We will reset the score to zero. (Variable $score set to Value 0)
- We will have 2 lives again. (Variable $lives set to Value 2)
- And we will use the commands again to update the Lives actor frame and the two score actors after recalculating the two digits again.
- We will set the “restart” variable back to false. (variable set to false)

That’s it, everything is done! Taking advantage of the “adventure” scene mode, we can add a series of trigger zones (by clicking the “Add Trigger” icon) with which we will change the cannon’s sprite so that it appears to move according to where we aim. This is a widely used technique that is achieved by modifying the animation speed of the Cannon Actor to 0 and using the “Set Actor Animation Frame” command with the different frame values within the Sprite editor for each trigger zone.
*If you need help with managing sprites, take a look at this other article: GB Studio: Getting Started with Games – Chapter 1 – GB Studio Central


I hope you’ve managed to get this far successfully. Remember that you can download the project’s source code from https://rubenretro.itch.io/cannon-defense, and don’t forget that on the GBStudio Discord channel, there is a wonderful community that will be happy to help you with any questions.
Best regards to everyone, and see you soon!
This article is part of a series: Getting Started with Games






