Module 4 Adding Danger & Challenge
Adding Danger & Challenge
Now your game needs an element of danger and challenge. This module shows you how to add doors to your game so you can send your player on a quest to find the keys they need to unlock these doors.
We’re also going to explain how to add to the challenge by giving your character lives, plus we’re going to introduce some baddies into the game to make things even more interesting. We’ll talk you through the basics of power-ups, too. This module is all about adding those special finishing touches that make a good game truly awesome!
Printable instructions - part 1 (PDF)
Printable instructions - part 2 (PDF)
No Youtube video above? Download it here!
- Keys & Locked Doors
- Moving Platforms
- Reset Zones
- Baddies
- Power Ups
Keys & Locked Doors
Keys & Locked Doors
We can use almost exactly the same code as the collision detection on the level sprites, but this time, rather than stopping the character from walking through the sprite, we want to store a record that we have collected a key.
Here, you can see the level 'collisionDetect' code but with the 'touchingFoot', 'touchingRight' and 'touchingLeft' removed.
Keys & Locked Doors
The key doesn't really mind which sensor touches it so the code will be the same for each situation. So, what do we do when it looks like we need to make the same code more than once? We make a new block! (in the 'More Blocks' section) This is so we only have to write the code once. In this case we’ll make a block called 'addToKeys'.
Keys & Locked Doors
This is where we’ll put instructions telling the game what to do when the character walks into a key. We can “call” this set of instructions from inside each 'if' statement in our 'collisionDetect' block, like this:
Keys & Locked Doors
Next, we need to fill out the instructions in our new 'addToKeys' block. But before we do this, we need to make a new kind of variable which we haven’t used before. This is called a 'list'.
Let’s start by making a new list in the 'data' section.
A pop-up box will appear, and as we want to be able to use this list in more than one sprite, we choose 'for all sprites'. We need to name our list, too; in this case our list is called 'keys'.
Keys & Locked Doors
What is a list?
"LISTS"
'A List' is pretty much what it sounds like. It’s a bit like a variable, but instead of having just one value, we can use a list to store lots of variables.
So, imagine you have lots of keys and doors in one of your game levels. We want to store the keys that have been collected so we know which doors can be opened. A list lets you do this!
Keys & Locked Doors
To keep things tidy we should store our Key identifier as a variable called 'keyID' (for this sprite only) and we can set it when the game starts.
Keys & Locked Doors
So the player doesn’t keep on collecting keys they already have. We add a piece of code to check if the key has been collected.
Make a 'checkKeyCollected' block in the key sprite and copy this code.
Keys & Locked Doors
We add a 'when I receive levelStart' block at the beginning of the level.
Keys & Locked Doors
So when finished, your key code should look like this.
Keys & Locked Doors
Now we have keys, we want to use them to open a door. First up, we need to build a door. Here we’re just using a block, but you can decorate your block however you like. Just remember the block/door should match the same colour as your key.
Keys & Locked Doors
To get through a door it needs to have two costumes. One when it’s shut and one where it’s open. Once you’ve drawn the purple block on the first costume, add a new costume and leave this one blank.
Keys & Locked Doors
Now we want to make sure that when the character walks into the door without a key, he can’t get through. So first let’s grab the same collision detection code we had in the levels.
Keys & Locked Doors
But we need to add a check to see if the player has a key to this. So, like we did before, we’re going to make a new custom block which we can call 'checkKeyIsOwned'.
Here we’re checking to see if the list 'keys' contains the value purple. If it does, it means that the player has collected the key and we should open the door. If not, it should remain closed.
Keys & Locked Doors
Now, we want to check what happens when the player walks into the door; we can change our 'collisionDetect' block to do this.
Again, we try and keep things tidy by storing the name of the key identifier in a variable 'For this sprite only'. We have also added a check to see if the player is on the correct level to show the door. Your final door script should look like this.
Keys & Locked Doors
One last thing, you need to reset the keys list when the game starts. So in 'game' add a 'when I receive initialiseGame' and add a 'reset all keys' block to that…
Moving Platforms
This will currently work in the exact same way as the level. But as this is a moving platform, we need to add some code to move it.
Moving Platforms
Let’s start in the same way we made the character move all that time ago, but let’s give it its own 'game loop' message to listen out for so it doesn’t get confused with when it should be moving and when it should be collision detecting. (This is very important because we want make sure it interacts with the character properly and moves Shaun when it should). We also need to add another couple of broadcast blocks to the game loop.
Moving Platforms
Here you can see we have added 'moveLevelItems' and 'movingPlatformCollisionDetect'. We will move the platform on 'moveLevelItems' so back in our platform, we want to add a 'when I receive' block and choose move level Items.
In here we want to add a 'change by 10' block from the motion section. This will now move the platform along the x axis by 10 pixels whenever the game receives the 'moveLevelItems' message, which is broadcast by the game in its forever loop.
But hang on! We don’t want the character to just go in one direction...
Moving Platforms
Here you can see we have added 'moveLevelItems' and 'movingPlatformCollisionDetect'. We will move the platform on 'moveLevelItems' so back in our platform, we want to add a 'when I receive' block and choose move level Items
In here we want to add a 'change by 10' block from the motion section. This will now move the platform along the x axis by 10 pixels whenever the game receives the 'moveLevelItems' message, which is broadcast by the game in its forever loop.
But hang on! We don’t want the character to just go in one direction.
We actually need it to come back again. The easiest way to do this is to have a variable which we call 'currentSpeed' (for this sprite only). So we’ll replace the ‘10’ in this piece of code so it looks like this
We can then change this variable to a negative number when the platform has got to the point where we want it to turn around, sending it in the opposite direction.
So, let’s look at getting that working. Firstly we’ll set up another variable (for this sprite only) and call it 'currentDir' - this will keep a track of whether the platform is going out or coming back to where it started.
Moving Platforms
First we should initialise it in by setting its value to 'out'.
Moving Platforms
We also want our platform to always start at 0 to make our maths easier. We can change its start position inside the costume rather than on the stage.
So, let’s add when I receive 'levelStart' and set x and y to 0.
Moving Platforms
Now in our when I receive 'moveLevelItems' block we want to add this code.
Moving Platforms
What it’s doing is firstly checking if the platform is going out, and if the distance between itself and the end point (in this case 120) is bigger than 2 (the same as the speed of the platform).
Here, we’re using a clever maths term called 'abs'. This will change any number to positive, so if you say 'abs of -10' it will give 10 and it will leave 10 as 10.
The reason we are doing this is because we don’t care what side the platform is of its end point, we just want to know how close it is.
So, if the distance is more than 2, we just want it to carry on travelling in the direction it was. If it’s less, we want it to change direction. We now set our variable 'currentDir' to back.
In the next 'if' we check to see the platform is supposed to be going back to its start point and if it has more than 2 pixels from 0 (where it started). If it does, set the 'currentSpeed' in the direction of -2, if not, turn around again.
Finally we change the x by the 'currentSpeed'.
In a nutshell, this moves the platform left and right.
We can also make the platform move up and down by changing all of the x values to y values but rather than replacing them, it would be good if we could make this platform customisable. So if we want to duplicate it, we can just change a few values when we set it up to change its behaviour, rather than change all of the code each time. Here we have put some new variables in place:
'axis', 'moveDistance' and 'mySpeed'.
These variables are for this sprite only.
Moving Platforms
This is what our 'initialseGame' and 'levelStart' blocks look like now.
Moving Platforms
This is our 'moveLevelItems' block. We have just replaced the numbers with variables and put in an option to travel along the 'x' axis or the 'y' axis.
Moving Platforms
Unfortunately, if you try jumping on your platform, you won’t move left and right with it... DOH!
So, that’s the next step we’re going to take a look at...
We need to make 2 variables for all sprites, which we’ll call 'groundMoveX' and 'groundMoveY'. We’ll use these to tell the character to move if the ground (or platform) they’re touching, is moving.
So, in our 'CollisionDetection'...
Moving Platforms
We want to add some 'if' blocks to each of the 'if touching' blocks.
In the foot sensor block we need to check if the axis is moving left and right, or up and down, and change either 'groundMoveX' or 'groundMoveY' accordingly.
In the left and right sensor check, we want to see if the platform’s current speed is going towards the character. If it is, we set 'groundMoveX' to the platform’s speed.
For example, if the character is on the left of the platform, we only want him to move if the platform is travelling left (pushing against him), and not if it’s travelling right.
Moving Platforms
Now, it’s all very well changing these variables but at the moment they don’t actually do anything to the character’s position. So this last bit is actually pretty simple. On our character sprite we want to add a few extra bits on to the end of the 'moveCharacter' block.
Here, the code is just changing the position of the character by 'groundMoveX' and 'groundMoveY'.
Moving Platforms
We need to make sure we reset our variables at the beginning of each frame. If we don’t, the character will continue moving after they have left the platform. So in the Game sprite, inside the 'when I receive resetFrameVariables' block, we want to add a 'set groundMoveX to 0' and 'set groundMoveY to 0'.
You should now have a moving platform which moves you when you stand on it and will push you if it touches you. Cool, huh?
Reset Zones
Now inside the 'if' blocks we want to add some way of making the character start the level again. So let’s broadcast a new message.
This now shouts that the character has walked into the ‘danger zone’. But what’s the point in shouting, if no one’s there to listen?
Reset Zones
Let’s make a receiver on the Game sprite. This will reset the level as soon as the game receives the 'hitResetZone' message.
But what about lives? What if we were to allow the player to restart a level a certain number of times but if they ran out of lives, they would have to start from the very beginning of the game? Makes things more exciting, doesn’t it?!
Reset Zones
Firstly let’s go to our 'Game' sprite and make a variable (for this sprite only) and call it 'lives'. In our 'initialiseGame' block we want to set a number of lives the player can have. Here we have said 5 to make the game interesting, but if you are feeling mean you can reduce the number you give them.
Reset Zones
Now, still in game, go to the 'hitResetZone' receiver where we’ll add some logic to check if the character has any lives left. If they do have lives left, remove one and restart that level. If they don’t have any lives left we want to start the game over again.
Reset Zones
So, back in our 'resetZone' we need to make a few adjustments so that this will work properly. Firstly, if the player touches the zone we need to hide it. Then, if you look at the code below, we add only show it again (in the 'when I receive levelStart') after a teeny weeny amount of time, otherwise the player will end up losing more than one life every time they touch it….which is a bit unfair, isn’t it!
So, here you can see the script which does this.
Reset Zones
Lastly we need to make sure that the character resets, when the level restarts instead of when the game starts. So in the character script change the 'when I receive InitialiseGame' to 'when I receive levelStart'.
Reset Zones
Let’s recap:
As soon as we detect a hit on the 'resetZone', we hide it, so that none of the other 'if touching' blocks will run.
We then broadcast the 'hitDeadZone' message. The game is listening to this and will remove a life. If the number of lives is 0 it will restart the game, if not, it will just restart the level.
When the 'resetZone' receives the 'levelStart' message, it will wait for a tiny bit, then show itself.
Baddies
Baddies are pretty much just a combination of two things we have done already.
1st, we want them to move on their own, just like the moving platforms.
2nd, we also we want them to make the character 'reset' if it touches them, like the reset zones .
So we basically just need to combine those two things together. Let’s start with a moving platform.
Duplicate the moving platform and call it something sensible (like 'baddie1Level1').
Baddies
Then, in the 'costumes' tab, change the look of the platform, so it looks like a baddie (we’re using a naughty pig).
Then grab the hit detection from one of the 'reset zones' and drag that on to your new baddie sprite.
Baddies
If you drag your baddie on the stage to that, the x and y position (top right of the scripts tab) is x:0 y:0.
Baddies
Then rather than adjust its position on the stage, adjust the position of the baddie sprite in the Costume tab. Then change the direction and distance it moves in the 'when I receive initialiseGame' block by altering the 'set moveDistance' block.
Baddies
We can add some code to make the baddie able to be jumped on - disabling it so the character won’t be affected by it.
Firstly lets make a variable (for this sprite only) and call it 'isActive'.
In our 'when I receive levelStart' block, inside the level check, we want to set 'isActive' to 'true'.
Baddies
Now we want to wrap everything in both our 'when I receive movingPlatformCollisionDetect' and 'when I receive moveLevelItems' in an 'if' block which checks if the sprite is currently active.
Baddies
Now in our 'movingPlatformCollisionDetect', in the 'if touching footSensor' we want to remove the 'broadcast hitDeadZone' and set the 'isActive' variable to 'false'.
Power Ups
Power ups can be used to add additional powers to the character, like extra lives, invincibility, the ability to jump higher or run faster. We won't go through all of the the possibilities of what all power-ups can do, but we can go through an example and you can then use this as a basis for your own power-ups if you want.
Power Ups
So, to begin with, we should make a global variable (for all sprites) and we can call it 'hasSuperJump'. Because we don’t want it to carry on from one level to another, we can reset it in the Game sprite 'gotoLevel' custom block like this.
Power Ups
Now we need something to collect which will give us this super power. So make a new sprite, we have used a balloon, but you can use anything you want that looks like something someone would really want to collect. Now we want the same collision detect script which we had in our level and once again, we want to strip out all of the stuff inside the if statements so we are left with this.
Power Ups
We also need to make a new variable, called 'timer' (for this sprite only).
Now we need to set our 'hasSuperJump' variable to true and 'timer' to 0 inside the 'if touching ...' statements.
We then wrap all of the contents of our level check 'if' in another 'if' to see whether or not the player has got 'superJump' yet or not. This is so they can’t keep getting the power-up if they already have it!
We also add an 'if' at the end, this is to check to see if the player has the 'superJump' power-up and if they do, to hide the sprite and count the timer up. Once the timer has reached 60 we set our has 'superJump' back to false.
Power Ups
We also want to add the following blocks to show and hide the sprite at the right time.
Power Ups
So, you can see that giving your character superpowers is actually the easy bit, it’s setting up the collectables which takes the time. But once you know how to do that, you can just change the logic of how something behaves when your super power variable is true. Have a play, try and make something which makes the character invincible.
Hopefully you have something by now that is a bit like this...