Wednesday, May 31, 2017

Byte: Raspberry Pi - Using Variables & Loops student workbook (a.k.a. FLAPPY BAT!)

Student Workbook: Using Variables and Loops

In this lesson we are going to use Scratch to introduce how to use data variables and code loops to create more sophisticated, interactive computer programmes. To do this, we’re going to make a videogame called Flappy Bat. Create a new Scratch project.

Start > Programming > Scratch
File > Save As
New Filename: Flappy Bat [yourname][date]

Flappy Bat is a heroic tale of a bat trying to escape from a dark and menacing forest, while he is being chased by horrid, vampire bat fiends. We will start making the game by finding a suitable background for our Stage. Select the Stage in the objects pane and click the Backgrounds tab.

New background: Import
Nature > forest > OK

That’s an appropriately spooky forest, so delete background1 from the list on the Backgrounds tab by click the cross icon button. We won’t be needing that anymore.

Since we’re creating a game called Flappy Bat and not Flappy Cat, Scratch the Cat has to go. Select Sprite1 in the objects pane and click the Costumes tab. You can see here that Scratch has two costumes to animate his walk. While we don’t want these specific costumes, we do want a sprite that has at least two costumes to properly animate our player-controlled bat. Otherwise our bat won’t flap, which would be no good at all, since this game is Flappy Bat. Fortunately, there are two costumes that suit our needs, and we can use them to replace costume1 and costume2.

New costume: Import
Animals > bat1-a > OK
New costume: Import
Animals > bat1-b > OK

Once the bat costumes have been imported, delete costume1 and costume2 from the list. Sprite1 is now a bat! And the two costumes we’ve imported will allow him to flap when we animate him. Sprite1 isn’t a terribly inspiring name, though. Our Flappy Bat is a HERO! He needs a heroic name, like Derek. Can you honestly think of a more heroic name for a bat trying to escape from lethal bat fiends in a creepy forest?? Rename Sprite1 using the text field at the top of the coding pane.
Derek may be very batty and he may be exceedingly flappy, but if you look at the preview pane, you’ll notice one rather large problem with him. He’s HUMONGOUS. Derek frankly needs to go on a diet. Slim him down by right-clicking his sprite in the preview pane and selecting resize this sprite on the pop-up menu. Click and drag the arrow to resize Derek until he’s about the size of your index finger when you touch the screen.

Derek, our hero, unfortunately has enemies. Pursuing him through the forest will be four deadly vampire bat fiends. Add them to your project and save your progress.

New sprite: (Import Sprite from File)
Animals > bat2-a > OK
New sprite: (Import Sprite from File)
Animals > bat2-a > OK
New sprite: (Import Sprite from File)
Animals > bat2-a > OK
New sprite: (Import Sprite from File)
Animals > bat2-a > OK
File > Save

Pro-Tip: It’s a sensible idea to save your project every ten minutes or so – it would be a pain to have an unexpected power cut and lose your work!

You should now have four dark, fiendish bats menacing Derek in the preview and objects panes on the right of the screen. To make sure that these bats are also flappy (the game’s called Flappy Bat, it can’t have bats in it that aren’t flappy… we’re clear on that, right?), we’ll need to give them a second costume to animate their movement. We should also give these bat fiends terrifying names, like Geoffrey, George, Zippy and Bungle. Makes your blood run cold, doesn’t it? Brrr. These names will help us to give each bat their own characteristics and properties, and keep track of them more easily. Rename the Bat Fiends and add their second costumes to make them flap!

New costume: Import
Animals > bat2-b > OK
New costume: Import
Animals > bat2-b > OK
New costume: Import
Animals > bat2-b > OK
New costume: Import
Animals > bat2-b > OK

Use the mouse to drag the four bat fiends into random starting positions on the preview pane, and then use the same right-click à resize this sprite method we used on Derek earlier to slim down the four bat fiends. Depending upon how difficult you want to make the game, you can make the bat fiends about the same size as Derek, or make them larger if you want to increase the difficulty.

We’re now ready to start coding the actual game itself. A good place to start is with scripts for the dastardly bat fiends, for two good reasons. Firstly, their behaviour is automated and practically identical, so once we’ve written the script for one of the bat fiends, we can simply duplicate it to the other sprites. Secondly, as the bat fiends’ movement is randomised, it gives us a good opportunity to get to grips with how to use random functions and loop blocks, before we code Derek’s rather more sophisticated script later.

Geoffrey, curse his rotten, putrid soul, is the leader of the foul pack of fetid fiends after Derek’s life essence, so we will start with him. Geoffrey will not rest, chasing Derek around the forest for eternity, unless our hero can somehow manage to escape. Select Geoffrey on the objects pane and click the Scripts pane to begin writing his main script.

when GreenFlag clicked                

The forever block is U-shaped, with an up arrow at the bottom, indicating that this is a loop. Any code dragged and dropped inside the U-shape will run in an infinite loop until a condition elsewhere in the project is reached that globally stops all the scripts. Let’s test that the loop works by making Geoffrey move. Add this code inside the forever block.

next costume                                     (now Geoffrey will flap every time the code goes around the loop)
move 10 steps                                  
if on edge, bounce                          (this stops him getting stuck on the edge of the screen)

Click on the green flag in the Scripts tab and watch Geoffrey go! Goodness me, that looks tiring! Give Geoffrey a bit of a rest between each flap by adding in a short delay at the bottom of the forever loop.

wait 0.1 secs

You can customise this wait value to increase or decrease the speed at which Geoffrey flies, but we’ll leave it at 0.1 for now, because there’s a better way of making Geoffrey’s movement around the screen less predictable and harder to avoid. This involves using Operators to generate to generate random numbers. Replace the 10 in the move 10 steps line using the pick random command from the Operators code category. The line needs to look like this:

move pick random 1 to 10 steps

Geoffrey will now fly faster and slower at random after every flap. It’s a definite improvement, but it’s still quite easy to avoid a bat flying straight and level. Add a turn command into your forever loop underneath the next costume line.

turn Clockwise 15 degrees

When you test the script this time, you should see that Geoffrey now starts flying in circles, and if you leave the script running, he’ll probably end up bouncing his way around the edge of the stage, before occasionally going back to flying in circles. We can fix this navigational problem and make his flight more realistic by using the pick random operator. Change the turn block to following.

turn Clockwise pick random -15 to 15 degrees

Much better! Far more fiendishly flappy and swoopy! Now that Geoffrey’s main script is complete, we can duplicate it (by right-clicking on the finished script) once each for George, Zippy and Bungle. Once you’ve dragged and dropped copies of the script onto the sprite icons for the other three bat fiends in the objects pane, we can customise each bat to make them behave slightly differently.

Make George lazy by tweaking the values in his forever loop to the following:

turn Clockwise pick random -15 to 15 degrees
move pick random 1 to 5 steps
wait 0.2 secs

Zippy, as his name implies, is fast, but he doesn’t really know what he’s doing, because he’s honestly a bit clueless… Poor guy!

turn Clockwise pick random -55 to 55 degrees
move pick random 6 to 5 steps
wait 0.04 secs

And dear old Bungle, he once flew head first into a tree, and it’s left him really rather confused about things. Not even he knows where he’s going to lurch next.

turn Clockwise pick random -40 to 40 degrees
move pick random -40 to 40 steps
wait 0.6 secs

Click the green flag above the preview pane to behold a malevolent maelstrom of fearsome, ferocious and fiendish flapping! Derek’s going to have his have his work cut out trying to escape from the deadly clutches of that lot! Before we can start on Derek’s script, we need to bind a key that we can use to reset and restart the game. Add the following script to Bungle’s Scripts pane.

when space key pressed
point in direction 90
go to x: 150 y: -15
stop all

Duplicate the new reset script and drag it into the objects pane for the other three bat fiends, changing their reset coordinates so that they don’t bunch up or overlap.

go to x: 90 y: -140
go to x: 0 y: 100
go to x: -120 y: -150

Derek will also need a reset script, so duplicate the script one final time and set our hero’s starting coordinates.

go to x: -220 y: 0

With the coding for the bat fiends now finished, this is now good point to create the two variables we need to track the player’s score and whether the game has ended. Select the Variables category in the coding pane.

Make a variable > score (For all sprites) > OK
Make a variable > gameover (For all sprites) > OK

We now have two global variables that can be referenced and modified by any of the sprites in the game. At the moment, we only need to use them with Derek, but other sprites could modify the values later in the extension challenges later.  Add the following two lines to the when space key pressed script to reset the global variables.

set score to 0
set gameover to 0

Next we need to make Derek respond to player commands. We can do this by adding four very simple scripts to accept inputs from the keyboard.

when down arrow key pressed
change y by -12
when up arrow key pressed
change y by 15
when left arrow key pressed
change x by -10
when right arrow key pressed
change x by 10

If you press the arrow keys now, you should find that Derek responds to your commands! He won’t flap yet, but we’ll fix that with our final script.

when GreenFlag clicked
set score to 0
set gameover to 0

This sets up the core of Derek’s main script. From now on everything goes inside the forever block. Note that we need to reset the score and gameover variables to stop unscrupulous players from using the stop all button and the mouse to cheat their way to a high score by interrupting the code loop! Our first order of business within the forever loop is to make sure Derek is animated properly. After all, he is supposed to be the Flappy Bat the game is named for…

next costume
change score by 1
wait 0.05 secs

If you run the code now, Derek will flap his wings when he moves and the player’s score gets incremented by one every time the player avoids being touched by one of the bat fiends after the completion of a full run through the code loop. Before we add collision detection between Derek and the other sprites, we need to add a touch of realism to the game. A hero like Derek would never get stuck on the side of the screen and stay put when he’s being chased by mortal enemies, and he also needs to fly faster forwards than backwards, because a hero never retreats! Sadly though, Derek is still subject to the force of gravity, so we need to reflect this in the way that he moves. Add three more blocks to the bottom of our forever loop.

move 5 steps
change y by -3
if on edge, bounce

You can always tweak these values if you find later that the game is too hard. Our game is almost finished! The final stage is to use several if statements to add collision detection between Derek and the bat fiends, and check the gameover variable to see whether the game still needs to continue running. To avoid confusion, add each if statement at the bottom of the forever loop. Use the touching ? conditional check in the Sensing category to see if any of the bat fiends have caught Derek. If they have, it’s curtains for our hero!

if touching Geoffrey ?
                set gameover to 1
if touching George ?
                set gameover to 1
if touching Zippy ?
                set gameover to 1
if touching Bungle ?
                set gameover to 1

Lastly, we can use two final if statements and comparison Operators to check the values in our two global variables and tell the player using a say speech bubble from the Looks category if they have won or lost the game.

if gameover = 1
                say GAME OVER! Derek was killed by a bat fiend! for 5 seconds
                stop all
if score > 1000
                say CONGRATULATIONS! Derek escaped from the bat fiends! for 5 seconds
                stop all

It’s all up to you, now… Can Derek make a heroic escape, or will he meet a gruesome fate at the fangs of the terrible, vampiric bat fiends?!? Good luck, Flappy Bat-Hero. FLAP HARD. FLAP FAST!

What Next?

Congratulations! You’ve just made a devilishly addictive Scratch game! But how could you make it better? Here are some things that you could try…

·         Can you alter the game’s difficulty by changing the movement speeds of the player bat or the bat fiends?
·         Can you add a variable to the game to give the player a number of lives?
·         Can you add sounds whenever the player loses a life or wins the game?
·         Can you change the script so that the player gets an extra life when their score passes a certain value?
·         Can you change the script to alter the size of the bat fiends (or the player bat) as the player’s score increases?
·         Can you tell the player the name of the bat fiend which caught them?
·         Can you find a way of turning the player bat into a dragon, which can eat the bat fiends, if the player score goes over 1000? (Challenging!!)
Post a Comment