We’re going to create power-ups in our game that can increase our player’s speed, give them extra lives, and make them temporarily invincible. This tutorial builds on concepts covered in Detecting overlapping: No collisions and no physics required!
Step 1: Basic power-up collectable
Which objects do you want to use as power-ups? Find one, and right-click on it, then select Add Script.
First we need to make sure our object is collectable. To prevent from blocking or impeding the movement of our player, we’re going to use overlapping detection instead of collision detection. To detect overlapping, we need to disable the physics on the object, and have the object constantly check if it’s being overlapped by the player. For disabling physics, grab the “When created” block from Events, and the “set physics enabled false” block from Physics.
Then to check if something is overlapping, we’ll need the “Constantly” block from Events, the “if” block from Control Flow, “myself overlaps instance” from Sensing, and “first instance by tag” from Sensing. Snap those blocks together to make “Constantly: if myself overlaps first instance by tag”, and make sure to type the tag the player has into the tag block (you can get rid of the “instance Toucher” block, since we don’t need it).
Now that we’ve got the overlapping detection part done, we can move on to making the power-up action happen.
Step 2: Global variables to communicate between the power-up and the player
To let the player object know it has collected a power-up, we could send it messages (as demonstrated in Remotely trigger other game objects using messages), or we could simply update a variable that both objects can measure: we can use global variables for this purpose. A global variable is just like a property variable, except it’s scope extends beyond a single object in a single level. On the power-up object, we’ll create a global variable for the player’s speed, and have this power-up increase this number. Then on the player object we’ll make its velocity equal to the player’s speed global variable.
First, we’ll get the global variable updated on the power-up object. Grab the “set true/false i” block from the Global section of the Variables category, and drag it inside the “if” block. Change true/false to number, and rename i to “player speed”. Then drag a number block into the variable block, and set it to something faster than your current player’s velocity.
In this example, my player object is a plane that has an x-velocity of 200, so I’ve boosted “player speed” to 400.
The object should also destroy itself once it’s collected, so drag the “destroy myself” block (from Control Flow) underneath the global variable block.
Step 3: Speed boosts
To make the player actually do something when our global variable changes, we’ll get the player to measure this global variable and then increase its speed accordingly. Close the power-up script (make sure to save your changes), and open the player’s script.
Your player object may be completely different to the plane shown in this example, but this tutorial will work for any player script in any game (although you may need to make some common-sense tweaks).
First, find the “When created” block (it should already be inside your player script with blocks already inside it, but if you don’t have one, grab one from the Events category)…
…and then grab “set number player speed” from Variables and drag it inside this block. Set the value to whatever the player’s starting speed is (0 if standing still, 200 if moving right, -200 if moving left, etc.)
Now that we’ve given “player speed” a starting value, we can update our movement system to use this variable. Find the section of the player script that deals with movement, and swap out the number values with the global variable for “player speed”. In this example, the player’s y velocity is set to -200 when the mouse is clicked, and the x velocity is constantly set to 200, so the player constantly moves to the right, and moves up only when clicked.
By replacing the number in the “set x velocity” block with our “player speed” global variable, we can make the x velocity speed up when the player collects the power-up that we created. Drag the “player speed” block into the “set velocity x” block (this depends on the velocity you want to change — if you want to affect the y velocity instead, then drag it into the “set velocity y” block).
Look at that speed!
Step 4: Extra lives
To add power-ups that give the player extra lives, the player needs to already have a lives system in place. We need to upgrade the existing lives system to use global variables, just like we did with “player speed”. Go to your player script, and find the section that deals with lives.
In this example, the player script has collision detection which removes a life if the player touches a deadly obstacle. If the player has less than 1 lives left, the player is sent back to the first level.
(If you don’t have a lives system set up on your player, then you can copy these blocks — just make sure you have obstacles tagged as deadly.)
The problem with this lives system is that the lives are stored as a property variable. Let’s go and replace them with global variables. Grab a new “set true/false i” block from the Global section of Variables, and move it into where the property “set number lives” block is. Change true/false to number, and rename i to “lives”. Then you can replace all the rest of the property “lives” blocks (medium green) with global “lives” blocks (dark green).
If the script has any other property variables for lives, you’ll need to swap them out with the global variable for lives. Don’t forget to set how many lives the player starts with in the “When created” block.
Now that you’ve converted the player over to using global variables for its lives, we can create a power-up to add more lives.
Close the player script (make sure to save it), and return to the Level Editor. In the Scripts sidebar, find the script for your speed power-up, and make a copy of it.
Edit the copied script, and double-click on its name to rename it to something like “Lives Power-Up”. Click on “player speed” in the existing global variable block, and choose “lives” instead. Then grab an addition block (_+_) from Operators, and drag it into the space where the number is. On the left side of the addition block, place a “number lives” block (from the Global section of Variables), and on the right side of the addition block, place the number 1. This will increase the lives variable by 1.
Now return to the Level Editor, and apply this new script to objects you want to use as power-ups for increasing the player’s lives. In the below example, silver stars have been used for life power-ups. Remember that good game design shouldn’t make it too easy for the player to get through your game.
Step 5: Temporary invincibility
Our next power-up will make our player temporarily invincible. We’ll make another copy of one of our power-up scripts. This power up script will work by using a new global variable called “invincible?”, and setting that variable to true, then the player script will check this variable before the player takes any damage. If “invincible?” = false, then take damage.
Rename this copied script to something like “Invincibility power-up”. Get rid of the global variable block inside the script, and replace it with a new global variable block “set true/false i”.
Rename the global variable to “invincible?”, and drag a “true” block (from Operators) into it.
Return to the Level Editor, and edit the player script.
Find the “When created” block that sets all gives all variables their initial values. Grab “Set true/false invincible?” from Variables, and drag it inside the “When created” event block. Then grab “true” from Operators, drag it into the “set true/false invincible” block, and change true to false. This will make sure the player doesn’t starts the game already invincible.
Then find the part of the player script that deals with taking damage (there may be multiple parts, so check the whole script and apply the instructions below to each relevant part).
The blocks above deal with detecting collisions with objects that will damage the player by subtracting lives. We’ll wrap these blocks inside another if-statement that will check if the player is invincible or not. Grab an “if” block from Control Flow, and drag it above the rest of the blocks inside the “When I am touched get toucher” block. Then drag the other blocks inside the new “if” block.
Now grab “_=_” from Operators, and drag it into that “if” block. Then grab “true/false invincible?” from the Global section of Variables, and drag it into the left side of the “_=_” block. Grab “true” from Operators, drag that into the left side of the “_=_” block, and change true to false (by clicking on it).
Now those damager blocks will only work if the player is not invincible. If we were to play this game now, the player would become invincible once it collects the invincibility power-up, but then the player would remain invincible. We want the invincibility to only be applied temporarily, so we need to add blocks that will reset invincible to false after a certain amount of time.
Find a “Constantly” block, and place another “if” block inside it. In the example below, this script had a “Constantly” block already setting the camera position and the player’s velocity, so the new “if” block was added below those blocks.
Grab “_=_”, “true/false invincible?”, and “true”, and connect those blocks to the “if” block.
Now for the time delay block. Grab “100 milliseconds have passed” from Control Flow, and drag that inside the “if” block. Change 100 to 5000 (5000 milliseconds = 5 seconds).
Then grab “set true/false invincible?” and “true”, and drag those blocks inside the “5000 milliseconds have passed” block. Change the true block to false.
These blocks will constantly check if invincible = true, and if it does they will set invincible to false in 5 seconds.
When you test it out, you should notice the player is temporarily unaffected by “deadly” obstacles.
Step 6: Invisibility and flipping the world upside-down
For some interesting extra features, we’ll do a quick run down to demonstrate the kinds of cool things you can get power-ups to do.
The power-up script should have a global boolean (true/false) variable:
And just like before, the player script should constantly check for the global variable, and use the time delay block if you want to make the effect temporary:
“Set visibility of myself” is found under the Looks category.
Flipping the world:
This power-up script should also have a global boolean (true/false) variable:
And the player script should constantly check for the global variable, and use the time delay block if you want to make the effect temporary:
“Camera scale” is found under the Looks category.
Nice work. What other kind of power-ups can you create?