["GAME PROGRESS 7 4 % 149 22 Generate the moves def generate_moves(): Next you need to write a function to generate global move_list, dance_length, count a sequence of moves to display on the screen. global show_countdown, say_dance You need to use a for loop to generate four count = 4 random numbers ranging from 0 to 3, where move_list = [] each number represents one of the moves you say_dance = False set up in Step 15. Each move generated will be for move in range(0, dance_length): added to two lists\u2014move_list and display_list. rand_move = randint(0, 3) Replace pass under def generate_moves() from Step 13 with this code. This assigns values move_list.append(rand_move) 0, 1, 2, or 3 at random to display_list.append(rand_move) the variable rand_move. show_countdown = True This line adds each countdown() new move to the end return of the list of moves. 23 Game over This line tells the function If the player makes a mistake, you need a \u201cGAME OVER!\u201d draw() to display the message to pop up. You can do this by adding an else branch value in count to create to the if not game_over statement. By doing this, if game_over the countdown. becomes True, the dancer and squares will vanish and be replaced by the \u201cGAME OVER!\u201d message. Add this code to the draw() Don\u2019t forget to save function immediately above the return statement. your work. This code runs if game_over is True. if show_countdown: This line draws screen.draw.text(str(count), color=\\\"black\\\", the score in the topleft=(CENTER_X - 8, 150), fontsize=60) top-left corner. else: This line draws \u201cGAME screen.clear() OVER!\u201d in black at the screen.blit(\\\"stage\\\", (0, 0)) center of the screen. screen.draw.text(\\\"Score: \\\" + str(score), color=\\\"black\\\", topleft=(10, 10)) screen.draw.text(\\\"GAME OVER!\\\", color=\\\"black\\\", topleft=(CENTER_X - 130, 220), fontsize=60) return","150 DANCE CHALLENGE 24 Generation test generate_moves() It\u2019s time to test your new functions and see if they are working. Add a call to generate_moves() just above the definition of update() def update(): from Step 13. Save the file and run it. You should see a countdown pass appear and then your dancer demonstrating a sequence of four moves. The word \u201cDance!\u201d should be displayed when he\u2019s finished, The global variable but don\u2019t start dancing yet! You still need to add the code that current_move identifies checks if the moves entered by the player are correct. which move you\u2019re dealing with. 25 Get the next move def next_move(): You need a way to move along the list of moves the computer global dance_length, current_move, moves_complete generated. This will let you compare the first move the player if current_move < dance_length - 1: This condition is enters to the first move in the current_move = current_move + 1 True if there are computer\u2019s list, and so on through still some moves the list. You also need to know when else: to check. you\u2019ve reached the end of the list. moves_complete = True To do this, use the global variable current_move to identify which return move you\u2019re dealing with. Replace pass under def next_move() The else block runs This code moves from Step 13 with this code. if there are no more current_move on moves to check. to the next move. 26 Score on each move 9 8 You now need to add some code to the on_key_up() function. When the player presses a key, the game needs to check whether the arrow key that\u2019s been pressed matches the move the game is currently checking. If it does, the player scores a point and current_move is updated to the next move on the list. If it doesn\u2019t, the game is over! Add this code to the on_key_up(key) function that you started in Step 17. Be careful to add it in the right place. if key == keys.UP: This block runs if the update_dancer(0) player presses the if move_list[current_move] == 0: correct key. score = score + 1 next_move() If the player else: makes a mistake, game_over = True game_over is set to True. elif key == keys.RIGHT: update_dancer(1)","GAME PROGRESS 8 7 % 151 if move_list[current_move] == 1: EXPERT TIPS score = score + 1 next_move() Event handling else: Dance Challenge uses an event handler game_over = True function called on_key_up() to react to a player pressing an arrow key. You elif key == keys.DOWN: shouldn\u2019t put the code to deal with key update_dancer(2) presses inside the built-in update() if move_list[current_move] == 2: function in this case because it will score = score + 1 run too frequently. If you pressed a next_move() key down just for a second, update() else: would tell the game you had pressed game_over = True it hundreds of times. This probably wouldn\u2019t match the dance sequence, elif key == keys.LEFT: so the game would finish right away. update_dancer(3) if move_list[current_move] == 3: Don\u2019t worry! score = score + 1 I\u2019ll handle it. next_move() else: game_over = True return 27 Keep going! I am out of control! To make the game more challenging, a new set of moves needs to be displayed every time the player This line runs if you successfully completes a dance sequence. Replace complete every move pass in the update() function from Step 13 with in the current list. the code below to do this. This line generates a new series of moves def update(): and displays them. global game_over, current_move, moves_complete if not game_over: if moves_complete: generate_moves() moves_complete = False current_move = 0","152 DANCE CHALLENGE 28 Test the game Score: 0 Pygame Zero Game Before you add the finishing touches to your game, test it. Save your code and then run it. Try getting the GAME OVER! first sequence of moves right to increase your score to four, then deliberately make a mistake with the second sequence. What do you see on the screen? You passed the first test! 29 Start the music 30 Stop the music At the moment, your dancer has nothing to You don\u2019t want the music to keep playing after dance to, which isn\u2019t much fun. Add a command the game has finished. So you need to add an else in your program that will play the audio file you branch to your first if statement in the update() saved in the music folder earlier. Type this code function to stop the music if the game is over. Add under the command you typed in Step 24. This this code to what you typed in Step 27. will tell Pygame Zero to start playing the music file until it\u2019s told to stop. If the player is still if not game_over: dancing at the end of the song, it will loop around and play the song again. if moves_complete: generate_moves() generate_moves() music.play(\\\"vanishing-horizon\\\") moves_complete = False def update(): current_move = 0 31 Ready to play Your code is now complete, so get your else: dancing shoes on! Save the file, run it from the command line in Command music.stop() Prompt or Terminal window, and see how long you can keep on dancing! If game_over is True, this line stops playing the audio file.","GAME PROGRESS 1 0 0 % 153 Hacks and tweaks It\u2019s you against me now! You can play around with the code to make the game even more interesting. But only if you\u2019ve got enough energy left after all that dancing! Can you give me a hand? \u25b3 Create your own character \u25b3 Play against a friend! Make your own dancer by using the 8-bit editors available You can play this game against a friend. Change the online, or use the additional images provided in the Python code so that all the odd-number sequences add to Games Resource Pack. You could have more than four dance player 1\u2019s score, and the even-number ones add moves to make more interesting and harder sequences. Just to player 2\u2019s score. It should show both scores at the add some code under the on_key_up() function in Step 17 top of the screen, and must also display a message to assign keys to each of the extra moves. that tells which player needs to play next, just before the countdown begins. Add some code to the on_key_up() function so that one player uses the keys W, A, S, and D to enter their moves, while the the other uses the Up, Left, Down, and Right keys. Shuffle mode is my favorite! if (rounds % 3 == 0): dance_length = dance_length + 1 \u25b3 A longer dance \u25b3 Change the music You can make the game more challenging. Each time you You can change the game music by downloading complete three sequences, increase the dance_length by one. audio files from www.creativecommons.org. To find out how many rounds have been completed, divide Remember to look for the .ogg format. You the number of sequences danced by three. If the remainder is don\u2019t have to pay for the music, but you should zero, then three sequences have been successfully completed acknowledge the creator in your game by adding since the last check, so add 1 to dance_length. You can use a line of code that displays the name of the track Python\u2019s modulo operator to work out the remainder. Modulo and its creators on the \u201cGAME OVER!\u201d screen. is written using the % symbol, so 4 % 3 will give you the remainder on dividing 4 by 3.","","Happy Garden","156 H A P P Y G A R D E N The counter displays the number of seconds the How to build garden has been happy for. Happy Garden Pygame Zero Game Gardening may seem like a relaxing hobby, but not in this game! Can you Garden happy for: 16 seconds help a flower-loving cow keep all the plants watered? Look out for the scary fangflowers as they try to zap the cow. How long can you help it keep the garden happy? What happens When the game starts, a cow with a watering can appears in the garden, but there is only one flower. Every few seconds another flower appears or an existing flower begins to wilt. Use the arrow keys to move the cow to the wilted flowers and press the Space bar to water them. If any flower remains wilted for more than ten seconds, the game ends. But if the garden is happy for more than 15 seconds, one of the flowers mutates into a fangflower and tries to zap the cow. \u25c1 Cow The cow is the main character in the game. Its aim is to keep all the flowers watered. \u25c1 Fangflower This large carnivorous plant moves around the garden and tries to zap the cow.","HOW TO BUILD HAPPY GARDEN 157 If a flower remains wilted for more than ten seconds, the game ends. The blooming flowers continue to appear at random positions on the screen as the game progresses. \u25c1 Keep moo-ving! There are a lot of different elements in this game. The code uses several functions to keep track of them all.","158 H A P P Y G A R D E N How it works Start The code begins by setting up the Actors\u2014the cow and the flowers\u2014in the garden. It then checks if any of the Add the garden and the cow; flowers have been wilted for more than ten seconds, generate and add the first flower and if the cow has been zapped by a fangflower. If any one of these conditions is True, the game ends. If not, the program checks for the other conditions. Has the flower Y A good shower been wilted for more Y always makes than ten seconds? me happy! N End Is the cow next to Show water coming out Is the cow next a fangflower? of the watering can to a flower? NY NY Is the Space bar Y Move cow in the direction being pressed? of the arrow key Reset flower if it is wilted N Is the arrow key being pressed? N Has the game been Y running for more than 15 seconds and have no Mutate a flower \u25c1 Happy Garden flowchart fangflowers appeared yet? into a fangflower This flowchart shows how various N parts of the game fit together. It also shows how both the player\u2019s actions and the randomly generated events affect what happens in the game.","GAME PROGRESS 1 4 % 159 It\u2019s gardening time! These are going to look great in my garden. It will take some preparation to get the garden ready. Begin by setting up the folders and downloading the images you\u2019ll need. 1 Get started 2 Save the game Open IDLE and create an empty file by clicking Go to your python-games folder and create on the File menu and choosing New File. another folder called happy-garden. From the File menu, choose Save As\u2026 and save the program File as garden.py inside the happy-garden folder. New File Open... Save As: garden.py Open Module... Tags: Recent Files Class Browser Where: happy-garden \u25b6 Cancel Save 3 Set up an image folder 4 Put the images into the folder Within the happy-garden folder, create another Find the images for Happy Garden in the Python folder by right-clicking and choosing New Folder. Games Resource Pack (dk.com\/computercoding) Name it images. It will be used to store all the and copy them into the images folder. Your folders images you need for this game. should look like this now. happy-garden happy-garden garden.py garden.py images images cow-water.png cow.png fangflower.png flower-wilt.png flower.png garden.png zap.png 5 Import modules from random import randint It\u2019s time to start coding. Go back to your garden.py import time file and start by importing some modules. You\u2019ll use randint() to randomly choose which flowers This imports Python\u2019s This imports the will wilt or mutate. The functions in the Time Time module. randint() function from module will keep track of how long the garden has been happy for or how long any flowers Python\u2019s Random module. have been wilted.","160 H A P P Y G A R D E N 6 Declare global variables WIDTH = 800 These variables Next define the global variables. HEIGHT = 600 define the size of These are the variables that will be CENTER_X = WIDTH \/ 2 the game screen. used throughout the game. Type CENTER_Y = HEIGHT \/ 2 this code under the lines you added These values set the in Step 5. cow\u2019s starting position on the screen. These are flag variables, game_over = False which let you know what\u2019s finalized = False Each time a new flower Actor is garden_happy = True created, it gets added to this list. happening in the game. fangflower_collision = False This list will store how long a flower has These variables help time_elapsed = 0 been wilted. keep track of the time. start_time = time.time() This will hold the velocities 7 Add the cow start_time = time.time() of the fangflowers along To start with, the only Actor in the the y-axis. game is the cow. Type the code cow = Actor(\\\"cow\\\") This will hold the velocities shown in black to add the cow cow.pos = 100, 500 of the fangflowers along and set its starting position. the x-axis. 8 Create lists for other Actors flower_list = [] The other Actors in the game\u2014 wilted_list = [] flowers and fangflowers\u2014are fangflower_list = [] generated at random as the game progresses. Since you don\u2019t This list will store the know how many of them will be fangflower Actors. generated, create lists to store each one that appears. 9 Keep track of the fangflowers fangflower_vy_list = [] In this game, you need to pay special attention to the zapping fangflowers. fangflower_vx_list = [] You\u2019ll need to make them move around the garden. They also need ? to bounce off the edges of the game window so that they are always on the screen. You can do this by keeping track of their velocity\u2014the speed at which something moves in a particular direction\u2014along the x-axis and the y-axis. Add these lines after the code from Step 8.","GAME PROGRESS 3 3 % 161 10 Draw the garden def draw(): Now that you\u2019ve set up those global game_over, time_elapsed, finalized variables, you need to draw the if not game_over: garden and the cow. There are no screen.clear() flowers or fangflowers to draw yet, screen.blit(\\\"garden\\\", (0, 0)) but add the code that will draw cow.draw() them when they\u2019re generated. Add for flower in flower_list: these lines immediately after the flower.draw() code from Step 9. for fangflower in fangflower_list: fangflower.draw() This code draws the time_elapsed = int(time.time() - start_time) cow on the screen. screen.draw.text( \\\"Garden happy for: \\\" + This code will draw str(time_elapsed) + \\\" seconds\\\", all the flowers. topleft=(10, 10), color=\\\"black\\\" ) This will draw all the fangflowers. This code checks how long the game has been running for. 11 Time to test pgzrun It\u2019s time to take a look at your garden! Save the IDLE file and then run it from Type this in the Command Prompt the command line in the Command or Terminal window and then Prompt or Terminal window. drag and drop the garden.py file. 12 Get a sneak peek! Pygame Zero Game If there are no mistakes in your code, you Garden happy for: 0 seconds should see a screen like this. If something\u2019s wrong, don\u2019t worry! Just use your debugging skills to check that you\u2019ve spelled everything correctly and used the correct number of spaces for indentation. You should see the garden and the cow holding a watering can.","162 H A P P Y G A R D E N def new_flower(): Don\u2019t forget to save pass your work. 13 Other functions You\u2019ll use a lot of functions in this def add_flowers(): game. You can list some of them pass now and define them later in the code. Using pass will make sure def check_wilt_times(): that Python doesn\u2019t run anything pass yet. Type this code under what you added in Step 10. def wilt_flower(): pass I'm going to make them all bloom. def check_flower_collision(): pass def reset_cow(): pass def update(): pass 14 Moving around the garden def update(): At the moment, the cow appears global score, game_over, fangflower_collision on the screen but doesn\u2019t do global flower_list, fangflower_list, time_elapsed anything. Add some code that lets if not game_over: you move the cow around. Replace if keyboard.left and cow.x > 0: the word pass under def update() cow.x -= 5 with the following code. elif keyboard.right and cow.x < WIDTH: cow.x += 5 This moves the cow five elif keyboard.up and cow.y > 150: pixels to the right when the cow.y -= 5 Right arrow key is pressed. elif keyboard.down and cow.y < HEIGHT: cow.y += 5","GAME PROGRESS 4 7 % 163 15 Another test Let\u2019s check pages Test your newly updated code to make sure 24\u201325 to see it\u2019s correct. Save your IDLE file and run it from how it\u2019s done. the command line. You should now be able to move the cow on the screen. pgzrun Type this in the Command Prompt or Terminal window and then drag and drop the garden.py file. 16 Add a flower These are the This line creates In this step, you\u2019ll create a flower Actor for the cow to global variables a new flower Actor. water and add it to the end of flower_list. You\u2019ll also add this function uses. the value happy to the end of wilted_list, which holds This line sets the the amount of time each flower has been wilted for. The position of happy value will let the program know that the flower the new flower. hasn\u2019t wilted. Replace pass in the new_flower() function with this code. def new_flower(): global flower_list, wilted_list flower_new = Actor(\\\"flower\\\") flower_new.pos = randint(50, WIDTH - 50), randint(150, HEIGHT - 100) flower_list.append(flower_new) wilted_list.append(\\\"happy\\\") return This lets the program know This adds the new flower that the flower is not wilted. to the list of flowers. 17 Add more flowers to the garden I think I need a Having just one flower to water would make the bigger garden! game too easy. You need to add some code that will create a new flower every four seconds to keep the This line calls the cow busy. Add this code to replace the word pass new_flower() function under def add_flowers(). to create a new flower. def add_flowers(): This adds a new flower every global game_over four seconds. if not game_over: new_flower() clock.schedule(add_flowers, 4) return","164 H A P P Y G A R D E N 18 Start adding flowers def reset_cow(): Although add_flowers() will schedule pass a call to itself every four seconds, you need to call it once in the program to add_flowers() start this process. Add the line in black above def update() from Step 13. Save def update(): and run your code to check if the flowers start appearing! 19 Blooming garden Pygame Zero Game If there are no errors in your code, Garden happy for: 20 seconds you will see a new flower appear on the screen every four seconds. This is what your screen will look like after 20 seconds. Use the arrow keys to move the cow around. I\u2019m going to grow even taller than you. 20 Water the flowers It\u2019s time for the cow to water the wilted flowers. Let\u2019s add some code that will make the cow sprinkle water on the flowers when the player presses the Space bar. The code will also check if the cow is standing next to a flower. Add this code to the update() function. This will check if global flower_list, fangflower_list, time_elapsed This will reset the the Space bar is if not game_over: cow\u2019s image after half a second. being pressed. if keyboard.space: cow.image = \\\"cow-water\\\" This line will check This will change the clock.schedule(reset_cow, 0.5) if the cow is next image of the cow to the check_flower_collision() to a flower. one with water coming out of the watering can. if keyboard.left and cow.x > 0: cow.x -= 5","GAME PROGRESS 6 1 % 165 21 Stop watering Uhh... I think that\u2019s The code from Step 20 uses two functions that you haven\u2019t enough water. written yet\u2014reset_cow() and check_flower_collision(). Let\u2019s add the code that will change the image of the cow using the watering can back to the version where it\u2019s just holding it. Replace the word pass under the reset_cow() function from Step 13 with the code in black below. def reset_cow(): This code runs global game_over if the game is if not game_over: not over yet. cow.image = \\\"cow\\\" return add_flowers() This changes the cow\u2019s image back to the original one. 22 Points for accuracy! These are the global You need the code to check if the cow is near a flower when the variables you will use Space bar is pressed. If it is, the flower will get watered and its in this function. \u201ctime since flower wilted\u201d value in wilted_list will be set to happy. To do this, you\u2019ll use Pygame Zero\u2019s built-in colliderect() function This code loops through to check if a flower and the cow have collided or are next to each all the flowers in the list. other. Replace pass under def check_flower_collision() in Step 13 with the code shown below. This changes the wilted flower\u2019s This variable helps def check_flower_collision(): image back to the the program to global cow, flower_list, wilted_list original version. index = 0 move through the for flower in flower_list: This line stops the program list in order. if (flower.colliderect(cow) and counting how long the flower.image == \\\"flower-wilt\\\"): flower\u2019s been wilted. This condition flower.image = \\\"flower\\\" applies if the cow wilted_list[index] = \\\"happy\\\" break is next to the index = index + 1 flower you\u2019re return looking at. This stops the loop from checking the This line updates the other flowers. value of index so that the program moves through the list.","166 H A P P Y G A R D E N 23 Wilt a flower index = 0 1 2 3 It\u2019s time to give your garden- tending cow a bit of a challenge. Add some code that will wilt flower_list These two lists store the a random flower every three information of a particular seconds. The cow will have to flower at the same index dash to the wilted flower to water number. it. Replace the word pass in the wilted_list happy happy wilt_flower() function from Step 13 with the code below. This line def wilt_flower(): This line generates resets the time global flower_list, wilted_list, game_over a random index in for this flower in if not game_over: the list of flowers. wilted_list to if flower_list: the current time. rand_flower = randint(0, len(flower_list) - 1) This checks if the if (flower_list[rand_flower].image == \\\"flower\\\"): flower at this index This schedules flower_list[rand_flower].image = \\\"flower-wilt\\\" is wilted or not. another call to wilted_list[rand_flower] = time.time() wilt_flower() in clock.schedule(wilt_flower, 3) three seconds. return 24 Unhappy garden! This sets the flower Next you need to check if any of the flowers have been image to a wilted wilted for more than ten seconds. If one has, the garden\u2019s flower image. unhappy, and it\u2019s game over! Go to def check_wilt_times() in Step 13 and replace pass with the code shown here. This code loops over each item in the wilted_list. This checks if def check_wilt_times(): These lines there are any global wilted_list, game_over, garden_happy check if the if wilted_list: flower is wilted items in the for wilted_since in wilted_list: and work out wilted_list. if (not wilted_since == \\\"happy\\\"): how long it\u2019s time_wilted = int(time.time() - wilted_since) been wilted. This line checks if (time_wilted) > 10.0: if the flower has garden_happy = False been wilted for game_over = True break more than return ten seconds.","GAME PROGRESS 7 5 % 167 25 Start wilting cow.image=\\\"cow\\\" This command will Now that you\u2019ve added a function return make the flowers wilt. to wilt the flowers, you need to call it. Add this code just below add_flowers() the call to add_flowers() that wilt_flower() you added in Step 18. 26 Check for happiness def update(): Now you need to add a call to global score, game_over, fangflower_collision the check_wilt_times() function global flower_list, fangflower_list, time_elapsed you defined in Step 24. Go to the check_wilt_times() update() function and add this line. if not game_over: 27 Game over! This checks how Your game is almost ready! But before testing it, long the flowers you need to add some code that lets the player have been wilted. know that the game is over if the flowers have been wilted for too long. Add an else branch to This line displays the if not game_over statement in the draw() a message to function you defined in Step 10. show how long the garden has str(time_elapsed) + \\\" seconds\\\", been happy. topleft=(10, 10), color=\\\"black\\\" ) else: if not finalized: cow.draw() screen.draw.text( \\\"Garden happy for: \\\" + str(time_elapsed) + \\\" seconds\\\", topleft=(10, 10), color=\\\"black\\\" ) This displays if (not garden_happy): a message screen.draw.text( that tells \\\"GARDEN UNHAPPY\u2014GAME OVER!\\\", color=\\\"black\\\", topleft=(10, 50) the player the ) game is over. finalized = True","168 H A P P Y G A R D E N Pygame Zero Game 28 Test run Garden happy for: 23 seconds Save your IDLE file and run it from the GARDEN UNHAPPY\u2014GAME OVER! command line in the Command Prompt or Terminal window. Try moving the cow around and water the wilted flowers. If a flower remains wilted for more than ten seconds, you will see a screen like the one shown here. Code testing makes me really giddy! 29 Added menace index = index + 1 So far, keeping the garden happy has been difficult return but not dangerous. What if the flowers start mutating into scary fangflowers that move around the garden def check_fangflower_collision(): trying to zap the cow? Let\u2019s add some functions to pass control the fangflower. Use placeholders for now and define them later on. Type this code above the reset_cow() function you defined in Step 21. Where did these def velocity(): weird flowers pass come from? def mutate(): pass def update_fangflowers(): pass def reset_cow(): global game_over if not game_over: cow.image = \\\"cow\\\"","GAME PROGRESS 8 3 % 169 30 Mutation 0 1 2 3 index It\u2019s time for your harmless flowers to turn fangflower_list into carnivorous fangflowers. Even worse, the code will change one random flower 2 0 -1 3 into a fangflower every 20 seconds after fangflower_vx_list the first mutation. Replace pass under def mutate() with the code below. There\u2019s a lot of code to add here, so be extra careful. These three lists will -3 1 0 2 store the velocities fangflower_vy_list of a particular fangflower at the same index number. If the game is not over and there These are the global are still flowers left to mutate, variables needed in this block of code will run. this function. This line def mutate(): This line picks a removes the global flower_list, fangflower_list, fangflower_vy_list random flower mutated flower global fangflower_vx_list, game_over to mutate. from the list if not game_over and flower_list: rand_flower = randint(0, len(flower_list) - 1) This sets of flowers. fangflower_pos_x = flower_list[rand_flower].x how fast the fangflower_pos_y = flower_list[rand_flower].y fangflower is This line sets the del flower_list[rand_flower] moving left fangflower at the fangflower = Actor(\\\"fangflower\\\") or right on same position as fangflower.pos = fangflower_pos_x, fangflower_pos_y the screen. fangflower_vx = velocity() the flower it fangflower_vy = velocity() This adds a new mutated from. fangflower = fangflower_list.append(fangflower) fangflower to the fangflower_vx_list.append(fangflower_vx) list of fangflowers. This sets fangflower_vy_list.append(fangflower_vy) how fast the clock.schedule(mutate, 20) fangflower is return moving up or down on the screen. The fangflower\u2019s This line schedules a call velocities are to mutate a flower every added to these lists. 20 seconds.","170 H A P P Y G A R D E N Remember, we talked about velocity 31 Move the fangflower Unlike other flowers, the fangflowers don\u2019t stay in on page 160. one place. They move all over the garden trying to zap the cow. In this step, you\u2019ll add the code that Positive x velocity generates the velocity of each fangflower along the x-axis and y-axis. The fangflowers will use a combination of these two velocities to move up, down, side to side, or diagonally. Add the following code under def velocity() from Step 29. Negative x velocity 0 x + Negative y Negative y velocity Negative x + Negative y Positive x + Negative y Negative x + 0 y This combination of the two velocities affect a fangflower\u2019s movement. Positive x + 0 y Positive y velocity Negative x + Positive y Positive x + Positive y This is one of eight different directions a fangflower can move in. This generates the 0 x + Positive y This line generates a number velocity of the fangflower that represents the direction def velocity(): of the fangflower. with no direction yet. random_dir = randint(0, 1) random_velocity = randint(2, 3) If the direction is 1, this If the direction is if random_dir == 0: returns a positive velocity. 0, this returns a return -random_velocity else: negative velocity. return random_velocity","GAME PROGRESS 8 9 % 171 32 Update the fangflowers These are the global It\u2019s time for the fangflowers to start moving. The code in this variables used in step will be called every time the update() function runs. It this function. will also keep the fangflowers inside the garden by making them bounce off the edges of the game screen. Replace pass under def update_fangflowers() from Step 29 with this code. There\u2019s a lot of tricky code here, so type it in carefully. This variable def update_fangflowers(): This loops over all helps the global fangflower_list, game_over the fangflowers if not game_over: in the list. program keep index = 0 track of which for fangflower in fangflower_list: These get the x item in the list it\u2019s fangflower_vx = fangflower_vx_list[index] and y velocities dealing with. fangflower_vy = fangflower_vy_list[index] of the fangflower. fangflower.x = fangflower.x + fangflower_vx If the fangflower fangflower.y = fangflower.y + fangflower_vy These get the touches the left if fangflower.left < 0: new position of edge of the screen, fangflower_vx_list[index] = -fangflower_vx the fangflower. this will make it if fangflower.right > WIDTH: start moving to fangflower_vx_list[index] = -fangflower_vx if fangflower.top < 150: the right. fangflower_vy_list[index] = -fangflower_vy if fangflower.bottom > HEIGHT: fangflower_vy_list[index] = -fangflower_vy index = index + 1 return By changing its y velocity, the fangflower is brought back into the screen. Better make sure none of you wander off!","172 H A P P Y G A R D E N 33 Check for collisions These are the global Now that your fangflowers are in motion, you need variables used to add some code that will check if a fangflower in this function. has caught up with the cow to zap it! Replace pass in the check_fangflower_collision() function with This checks if the the code shown below. fangflower and cow are next to This adds an def check_fangflower_collision(): each other. image to show global cow, fangflower_list, fangflower_collision global game_over the cow has for fangflower in fangflower_list: been zapped. if fangflower.colliderect(cow): cow.image = \\\"zap\\\" This tells the game_over = True program that break the game is over. return This line stops the program from checking other fangflowers. 34 Drawing results Don\u2019t forget to save If a fangflower manages to zap the your work. cow, it\u2019s game over. Add this code to the draw() function to display a game over message. This block of if (not garden_happy): code runs if the screen.draw.text( \\\"GARDEN UNHAPPY\u2014GAME OVER!\\\", color=\\\"black\\\", garden is still topleft=(10, 100) happy but the cow ) finalized = True has been zapped. else: This draws a screen.draw.text( message on the \\\"FANGFLOWER ATTACK\u2014GAME OVER!\\\", color=\\\"black\\\", screen to show topleft=(10, 50) the game is over ) finalized = True because of a fangflower attack. This makes sure the code is not run again. return","GAME PROGRESS 1 0 0 % 173 35 Set up the update def update(): The fangflowers are ready to attack. global score, game_over, fangflower_collision The last thing you need to do is add global flower_list, fangflower_list, time_elapsed some code that starts the whole fangflower_collision = check_fangflower_collision() mutation process if the garden check_wilt_times() has been happy for more than if not game_over: 15 seconds. Go to the update() if keyboard.space: function and add the code as cow.image = \\\"cow-water\\\" shown here. clock.schedule(reset_cow, 0.5) check_flower_collision() This checks if the garden if keyboard.left and cow.x > 0: has been happy for more cow.x -= 5 than 15 seconds and if any elif keyboard.right and cow.x < WIDTH: fangflowers have appeared cow.x += 5 elif keyboard.up and cow.y > 150: on the screen yet. cow.y -= 5 elif keyboard.down and cow.y < HEIGHT: This line cow.y += 5 mutates a if time_elapsed > 15 and not fangflower_list: flower into a mutate() fangflower. update_fangflowers() 36 Test and play! Pygame Zero Game Green thumbs at the ready, your game can now be played! Save and run the file from the Garden happy for: 21 seconds command line. Make sure the cow keeps the FANGFLOWER ATTACK\u2014GAME OVER! flowers watered while avoiding the dangerous fangflowers. What does your screen look like when the fangflowers appear and finally zap the cow? We\u2019ve run all the tests. You\u2019re good to go!","174 HAPPY GARDEN Hacks and tweaks Do you want to make the game even more exciting? You can try out some of these ideas and add new features to the game. Sorry pal, your day random_velocity = randint(2, 3) in the sun is over. \u25b3 Faster fangflowers! \u25b3 Change the gardener You can make the fangflowers move faster by You might think a cow is an unusual gardener. changing the possible range of random_velocity. Why don\u2019t you look for another character in the Python Try increasing the range by using something Game Resource Pack? You could also make a new like randint(4, 6). character using any 8-bit editor available online. clock.schedule(add_flowers, 4) clock.schedule(mutate, 20) \u25b3 More flowers \u25b3 More fangflowers You can change how often a new flower appears Is the game too hard or too easy? on the screen to make the game easier or harder. You can change the code in mutate() Update the code under def add_flowers() to to make fangflowers appear more change how often it schedules a call to itself. or less often.","HACKS AND TWEAKS 175 \u25c1 Add new enemies If you find the game is not challenging enough at the moment, you can add more enemies. Use an online 8-bit editor to create more characters and then add some functions to control their behavior. These functions would be similar to the ones that control the fangflowers in the game. The new enemies could be flowers that fire pellets at the cow if it gets too close, thorn bushes that snake out long stems to catch the cow, or even aliens in flying saucers who are after the fangflowers. \u25b3 Rain in the garden if not raining: screen.blit(\\\"garden\\\", (0, 0)) What happens if it rains in the garden? The flowers will be much happier and wouldn\u2019t need watering. But they else: will also mutate into fangflowers more quickly. To make screen.blit(\\\"garden-raining\\\", (0, 0)) it look like it\u2019s raining, you can update the background with another image from the Python Games Resource Pack or create a new background on your own. To control the new background, create a new variable called raining and change the draw() function to update the background based on the variable\u2019s value.","","Sleeping Dragons","178 SLEEPING DRAGONS How to build Sleeping Dragons Grab your shield and sword as you go Pygame Zero Game in search of dragon treasure. Time your movements to snatch the eggs from under the dragons\u2019 noses. But be careful, brave knight\u2014if they wake up, you\u2019re in for a nasty surprise! What happens In this game, the player controls the hero using the four arrow keys. The hero must collect 20 eggs from the dragons\u2019 lair to win the game. Each dragon sleeps and wakes up at different times. If the hero is near a dragon when it\u2019s awake, the player loses a life. The game ends when the player runs out of lives or collects enough eggs. \u25c1 Dragons 62 The three dragons are harmless when they\u2019re asleep. \u25c1 Eggs Each dragon has a different number of eggs. \u25c1 Hero The fearless hero has three lives to collect 20 eggs.","HOW TO BUILD SLEEPING DRAGONS 179 Why do you sleep Because I like to during the day? fight knights! The dragons breathe fire when they wake up. The dungeon background sets the scene for your quest. \u25c1 Dragons in a dungeon This game uses built-in Pygame functions to animate the Actors and Python\u2019s dictionaries to keep track of the dragons and their eggs.","180 S L E E P I N G D R A G O N S How it works Start You\u2019ll use the draw() function Draw dragons, to draw the hero, the dragons, eggs, and the hero and the eggs on the screen. Then you\u2019ll create the update() Is an arrow key function to check the player\u2019s being pressed? actions and update the different elements of the YN game. Both these functions are called many times every Move the hero in the direction second, which will allow you of the key being pressed to animate the Actors in the game. You\u2019ll also use the clock.schedule_interval() function to wake up the dragons and send them to sleep at regular intervals. Is the hero Y Increase the egg count, hide touching any eggs? the egg(s) for two seconds N Has the player N collected enough N Is the hero being eggs? attacked by a dragon? Y Y End Subtract one from number of lives, reset hero\u2019s position Y \u25c1 Sleeping Dragons flowchart Are there any lives left? There are two separate loops in this program. The main loop is N controlled by Pygame and runs multiple times per second. End","GAME PROGRESS 3 % 181 \u25b7 Dragon animation flowchart Start The second loop in the program is responsible for the dragons\u2019 sleep cycle. It runs once every second. Is the dragon Y awake? N N Has the dragon been N Has the dragon awake long enough? Z slept long enough? Y Z Y Z Wake the dragon Send the dragon to sleep Begin the quest First you\u2019ll create the variables that will track the game\u2019s progress. Then you\u2019ll write some code that will draw all the elements on the screen. Finally, you\u2019ll set up the functions to make the hero move, handle the dragons\u2019 sleep cycles, and check if the hero has collected enough eggs without getting caught. I need some more eggs! 1 Time to begin File Open IDLE and create New File an empty file by going Open... to the File menu and Open Module... selecting New File. Recent Files Class Browser \u25b6","182 SLEEPING DRAGONS 2 Save the file I name thee ? Go to your python-games folder and create Margaret. another folder, called sleeping-dragons, inside it. Then go to the File menu and select Save As... to save the IDLE file as dragons.py in this folder. Save As: dragons.py Tags: Where: sleeping-dragons Cancel Save 3 Add the images sleeping-dragons This game uses nine images. Create a new folder, called images, inside the sleeping-dragons dragons.py folder. Find all the images in the Python Games images Resource Pack (dk.com\/computercoding) and copy them into this folder. dragon-asleep.png dragon-awake.png dungeon.png egg-count.png hero.png life-count.png one-egg.png three-eggs.png two-eggs.png 4 Import a module LINGO Now you can start writing the code. Begin by importing Python\u2019s Math module. Type this Constants at the very top of your IDLE file. Constants are variables that are used to import math This imports the hold values that determine how a game entire module. behaves. There is nothing special about these variables that prevents them from Check page 15 to being changed, but programmers use capital find out more about letters when naming them to let the other the Math module. programmers know that they should not be changed throughout the program.","GAME PROGRESS 1 9 % 183 5 Declare the constants Don\u2019t forget to save You need to declare the constants at the start of the game. your work. In this game, you\u2019ll use constants to determine many things, including the hero\u2019s starting position and the number of This sets the font eggs the player needs to collect to win the game. All of these color to black. constants will be used later in the code. Type this under the This is the distance in line from Step 4. pixels at which a dragon can attack the hero. import math This is the number of These constants WIDTH = 800 seconds the dragons define the size of HEIGHT = 600 stay awake. the game window. CENTER_X = WIDTH \/ 2 CENTER_Y = HEIGHT \/ 2 This sets the number CENTER = (CENTER_X, CENTER_Y) of eggs needed FONT_COLOR = (0, 0, 0) EGG_TARGET = 20 to win the game. HERO_START = (200, 300) ATTACK_DISTANCE = 200 This sets the hero\u2019s DRAGON_WAKE_TIME = 2 position at the start EGG_HIDE_TIME = 2 MOVE_DISTANCE = 5 of the game. This sets the number This is the number of of seconds the eggs pixels the hero moves are hidden. by with each key press. 6 Declare the global variables Check page 74 to After the constants, you need to declare the global variables. They\u2019re a lot learn more about like constants because they\u2019re usually declared at the top of the program. global variables. However, unlike constants, their values change when they\u2019re used throughout the program to track the game\u2019s progress. Type this code next. MOVE_DISTANCE = 5 This tracks the lives = 3 This variable number of eggs eggs_collected = 0 tracks the game_over = False number of lives collected. game_complete = False remaining. reset_required = False This variable This variable tracks if the tracks if the player has won. game is over.","184 S L E E P I N G D R A G O N S EXPERT TIPS 7 Create the lairs Dictionaries Each dragon in this game has its own lair with a certain number of eggs and an easy, medium, or hard difficulty In Python, using a dictionary is another level. You can use Python\u2019s dictionaries to keep track way to store information. It\u2019s like a list, but of all the elements needed to create these lairs. Each with a label attached to every item. This dictionary includes Actors for the dragons and eggs, label is known as the \u201ckey\u201d and the item and variables for tracking each dragon\u2019s sleep cycle. it\u2019s attached to is called the \u201cvalue.\u201dYou Begin by creating a dictionary for the easiest lair. can even create a dictionary in which the Carefully type these lines under the code from Step 6. values are other dictionaries. This is called \u201cnesting,\u201d and it allows you to store the reset_required = False pieces of your game in a structured way. easy_lair = { cherries clock \\\"dragon\\\": Actor(\\\"dragon-asleep\\\", pos=(600, 100)), \\\"eggs\\\": Actor(\\\"one-egg\\\", pos=(400, 100)), paint bucket trophy \\\"egg_count\\\": 1, \\\"egg_hidden\\\": False, \\\"egg_hide_counter\\\": 0, \\\"sleep_length\\\": 10, \\\"sleep_counter\\\": 0, \\\"wake_counter\\\": 0 } 8 Medium lair These are the Next add a dictionary for the lair with medium difficulty. coordinates for the The code for this is a lot like the code in the previous step, dragon in this lair. but some of the values are different. } This checks medium_lair = { This sets the if the eggs are \\\"dragon\\\": Actor(\\\"dragon-asleep\\\", pos=(600, 300)), coordinates currently hidden. \\\"eggs\\\": Actor(\\\"two-eggs\\\", pos=(400, 300)), of the eggs. \\\"egg_count\\\": 2, This tracks \\\"egg_hidden\\\": False, the dragon\u2019s \\\"egg_hide_counter\\\": 0, sleep cycle. \\\"sleep_length\\\": 7, \\\"sleep_counter\\\": 0, \\\"wake_counter\\\": 0 }","GAME PROGRESS 3 4 % 185 9 Hard lair \\\"sleep_length\\\": 7, Now you need to add the third \\\"sleep_counter\\\": 0, and final lair. Add this code \\\"wake_counter\\\": 0 after what you typed in Step 8. } This is just hard_lair = { too hard! \\\"dragon\\\": Actor(\\\"dragon-asleep\\\", pos=(600, 500)), \\\"eggs\\\": Actor(\\\"three-eggs\\\", pos=(400, 500)), This sets the \\\"egg_count\\\": 3, numbers of eggs \\\"egg_hidden\\\": False, \\\"egg_hide_counter\\\": 0, for this lair. \\\"sleep_length\\\": 4, \\\"sleep_counter\\\": 0, \\\"wake_counter\\\": 0 } This tracks how many seconds the eggs have been hidden for. 10 Bring the lairs together \\\"sleep_counter\\\": 0, You\u2019ll need to loop over all the lairs later on in \\\"wake_counter\\\": 0 the code. To make this easier, store them in a } list. Type this line next. lairs = [easy_lair, medium_lair, hard_lair] This list holds all the lairs. 11 A hero is born I was born to The final Actor needed for this game do this! is the hero. It\u2019s the character that the player controls to collect the dragon eggs. lairs = [easy_lair, medium_lair, hard_lair] hero = Actor(\\\"hero\\\", pos=HERO_START) This sets the starting position of the hero Actor.","186 S L E E P I N G D R A G O N S One down, two to go! 12 Draw the Actors Now use the draw() function to display all the Actors on the screen. Add the following code under the lines you typed in Step 11. There\u2019s quite a bit to add here, so be careful. hero = Actor(\\\"hero\\\", pos=HERO_START) def draw(): global lairs, eggs_collected, lives, game_complete This adds a background screen.clear() to the game. screen.blit(\\\"dungeon\\\", (0, 0)) if game_over: screen.draw.text(\\\"GAME OVER!\\\", fontsize=60, center=CENTER, color=FONT_COLOR) elif game_complete: screen.draw.text(\\\"YOU WON!\\\", fontsize=60, center=CENTER, color=FONT_COLOR) else: hero.draw() draw_lairs(lairs) draw_counters(eggs_collected, lives) 13 Create the stubs def draw_lairs(lairs_to_draw): Next create the placeholders for some pass functions that will be defined later on. Using pass will tell Python not to run def draw_counters(eggs_collected, lives): these functions yet. Type this code below pass the lines from Step 12. 14 Run the code Save your file and run it from the command line. Check pages 24\u201325 if you need to remind yourself how to do this. pgzrun Type this command in the Command Prompt or Terminal window, then drag the dragons.py file here to run it.","GAME PROGRESS 50% 187 Pygame Zero Game 15 Enter the dungeon If your code is free of errors, you\u2019ll see a screen similar to the one shown here. You\u2019ll see the hero and the dungeon, but you won\u2019t be able to move the hero around yet. The dragons and eggs will be added in the next step. The hero appears at the starting position. 16 Draw the lairs Don\u2019t forget to save You now need to define the draw_lairs() function. It takes a your work. parameter called lairs_to_draw. This function loops over the three lairs\u2014easy_lair, medium_lair, hard_lair\u2014and draws a This loops over dragon for each of them. If the eggs are not currently hidden, each lair. they are drawn as well. To get the Actors from the dictionaries of all the lairs, type the name of the dictionary followed by the key in square brackets. Replace pass under draw_lairs(lairs_to_draw) from Step 13 with this code. This draws a dragon else: Actor for each lair. hero.draw() draw_lairs(lairs) This draws the eggs draw_counters(eggs_collected, lives) for each lair if they are not currently hidden. def draw_lairs(lairs_to_draw): for lair in lairs_to_draw: lair[\\\"dragon\\\"].draw() if lair[\\\"egg_hidden\\\"] is False: lair[\\\"eggs\\\"].draw()","188 S L E E P I N G D R A G O N S 17 Draw the counters That\u2019s enough eggs Next you\u2019ll define the draw_counters() function. It takes two for one day. parameters\u2014eggs_collected and lives. Their values will be displayed in the bottom-left corner of the game screen. Replace pass under def draw_counters(eggs_collected, lives) with the code shown below. This draws an icon to def draw_counters(eggs_collected, lives): represent the number screen.blit(\\\"egg-count\\\", (0, HEIGHT - 30)) screen.draw.text(str(eggs_collected), of eggs collected. fontsize=40, pos=(30, HEIGHT - 30), color=FONT_COLOR) This draws an icon to screen.blit(\\\"life-count\\\", (60, HEIGHT - 30)) represent the number of screen.draw.text(str(lives), lives the player has left. fontsize=40, pos=(90, HEIGHT - 30), color=FONT_COLOR) 18 Move the hero def update(): With everything set up, it\u2019s time to add some code if keyboard.right: that will make the hero move on the screen. You\u2019ll use hero.x += MOVE_DISTANCE the update() function to do this. If the player presses if hero.x > WIDTH: an arrow key, this code will make the hero move in hero.x = WIDTH that direction by the number of pixels assigned to elif keyboard.left: MOVE_DISTANCE. You also need to add a call to the hero.x -= MOVE_DISTANCE check_for_collisions() function, which you\u2019ll define if hero.x < 0: later. Type this code after the lines from Step 17. hero.x = 0 elif keyboard.down: Hey, move! hero.y += MOVE_DISTANCE That\u2019s my spot. if hero.y > HEIGHT: hero.y = HEIGHT elif keyboard.up: hero.y -= MOVE_DISTANCE if hero.y < 0: hero.y = 0 check_for_collisions()","GAME PROGRESS 6 6 % 189 19 Add a placeholder 20 Try it out This is a good point to run your game and Save your IDLE file and run it from the command check for any bugs. But before you run it, line. If there are no bugs hiding in your code, you\u2019ll you need to set up a placeholder for the see a screen like the one below. You\u2019ll be able to check_for_collisions() function. Add make the hero move around the screen, but you these lines after the code from Step 18. won\u2019t be able to collect any eggs yet. check_for_collisions() Pygame Zero Game def check_for_collisions(): pass The hero moves in the direction of the arrow key being pressed. The counters for the eggs 03 collected and lives remaining appear in the bottom-left corner. 21 Animate the lairs Now animate the dragons and the eggs to make the game more interesting. The update_lairs() function will loop through each lair dictionary and check if the dragon is asleep or awake. Add this code between the update() function and the def check_for_collisions() placeholder. check_for_collisions() This loops def update_lairs(): This is called through all global lairs, hero, lives if the dragon three lairs. for lair in lairs: is asleep. if lair[\\\"dragon\\\"].image == \\\"dragon-asleep\\\": This block update_sleeping_dragon(lair) This is called will animate elif lair[\\\"dragon\\\"].image == \\\"dragon-awake\\\": if the dragon the dragon. update_waking_dragon(lair) is awake. update_egg(lair) This will animate the eggs. def check_for_collisions():","190 S L E E P I N G D R A G O N S 22 Schedule a call update_egg(lair) Next add some code to schedule a call clock.schedule_interval(update_lairs, 1) to the update_lairs() function once every second. Add this line under the code from Step 21. This function schedules a The number of seconds between call to another function at each function call can be changed regular intervals. by updating this number. 23 Wake the sleeping dragon Now you need to check if the dragon has slept long enough. To do this, you need to compare the sleep_counter with the sleep_length set for that dragon. If it\u2019s time to wake the dragon, the sleeping dragon image will be updated and the sleep_counter will be reset to 0. If not, the sleep_counter will be increased by one. Add this code under the line from Step 22. This resets def update_sleeping_dragon(lair): This checks if the if lair[\\\"sleep_counter\\\"] >= lair[\\\"sleep_length\\\"]: sleep_counter is the dragon\u2019s lair[\\\"dragon\\\"].image = \\\"dragon-awake\\\" greater than or equal sleep_counter to 0. lair[\\\"sleep_counter\\\"] = 0 to the sleep_length else: set for the dragon. lair[\\\"sleep_counter\\\"] += 1 This increases the sleep_counter by one. 24 Send the dragon to sleep If the dragon has been awake for long enough, it needs to be sent back to sleep. The function needed to do this is similar to the one you defined in the previous step. However, unlike sleep_length, which is different for all the dragons, the time they should be awake for is the same, so you\u2019ll use the constant DRAGON_WAKE_TIME. Add this code under what you typed in Step 23. This checks if the def update_waking_dragon(lair): This updates the dragon has been if lair[\\\"wake_counter\\\"] >= DRAGON_WAKE_TIME: dragon image. awake long enough. lair[\\\"dragon\\\"].image = \\\"dragon-asleep\\\" lair[\\\"wake_counter\\\"] = 0 This adds one to This resets the dragon\u2019s else: the wake_counter. wake_counter to 0. lair[\\\"wake_counter\\\"] += 1","GAME PROGRESS 8 1 % 191 25 Animate the eggs This block runs The program hides the eggs when the hero collects if any eggs have them. You need to check if the eggs have been hidden been hidden for for long enough and, therefore, need to reappear. Add long enough. this code immediately after the lines from Step 24. This adds one to the lair[\\\"wake_counter\\\"] += 1 egg_hide_counter. This function checks def update_egg(lair): if any eggs need to if lair[\\\"egg_hidden\\\"] is True: stay hidden or not. if lair[\\\"egg_hide_counter\\\"] >= EGG_HIDE_TIME: lair[\\\"egg_hidden\\\"] = False lair[\\\"egg_hide_counter\\\"] = 0 else: lair[\\\"egg_hide_counter\\\"] += 1 26 Test the code Save your file and run it from the command line. You should see the dragons sleeping and waking up. Next you\u2019ll add the code that\u2019ll make the eggs disappear when the hero collects them. Pygame Zero Game The dragons will wake up at different times. 03","192 SLEEPING DRAGONS 27 Check for collisions You now need to define the check_for_collisions() function from Step 19. The code in this function will loop over each lair dictionary and check if the hero has touched an egg and if the hero is close enough to an awake dragon to get attacked. Replace pass under def_check_ for_collisions() with the code shown below. lair[\\\"egg_hide_counter\\\"] += 1 def check_for_collisions(): global lairs, eggs_collected, lives, reset_required, game_complete for lair in lairs: if lair[\\\"egg_hidden\\\"] is False: check_for_egg_collision(lair) if lair[\\\"dragon\\\"].image == \\\"dragon-awake\\\" and reset_required is False: check_for_dragon_collision(lair) This function is called if This function is called if the This makes sure the the eggs are not hidden. dragon is awake and the hero\u2019s player doesn\u2019t lose a position is not being reset. life when the hero is EXPERT TIPS being moved back to the start position. colliderect() Bounding The colliderect() function gets its name rectangle from a combination of two words\u2014 collide and rectangle. Pygame places an Area of collision invisible rectangle around each element is where the on the screen. If you want to detect a collision between two objects, you can two bounding check if the rectangles around them are rectangles overlap. overlapping with each other. Sometimes Pygame detects a collision even if two objects appear to be slightly apart. This is because even when the objects are not touching each other, the rectangles around them can still overlap.","GAME PROGRESS 9 1 % 193 28 Dragon collisions Don\u2019t forget to save If the hero gets too close to an awake your work. dragon, the player will lose a life. You\u2019ll use the check_for_dragon_collision() This calculates the function to calculate this distance. horizontal and vertical Add this code under what you typed distances between the in Step 27. dragon and the hero. check_for_dragon_collision(lair) This finds the distance between the dragon and def check_for_dragon_collision(lair): the hero in a straight line. x_distance = hero.x - lair[\\\"dragon\\\"].x y_distance = hero.y - lair[\\\"dragon\\\"].y distance = math.hypot(x_distance, y_distance) if distance < ATTACK_DISTANCE: handle_dragon_collision() This function is called if the distance between the hero and dragon is less than ATTACK_DISTANCE. 29 Reset hero If the player loses a life, the hero\u2019s position needs to be reset to the starting position. You\u2019ll use the animate() function to do this. In your game, this function takes three parameters\u2014the hero Actor, the hero\u2019s starting position, and the subtract_life() function. Add the code shown in black here. distance = math.hypot(x_distance, y_distance) if distance < ATTACK_DISTANCE: handle_dragon_collision() def handle_dragon_collision(): global reset_required reset_required = True animate(hero, pos=HERO_START, on_finished=subtract_life) This function is called when the animation is complete.","194 S L E E P I N G D R A G O N S def check_for_egg_collision(lair): global eggs_collected, game_complete 30 Egg collisions if hero.colliderect(lair[\\\"eggs\\\"]): You now need to add a function that will lair[\\\"egg_hidden\\\"] = True check if the hero has touched an egg or eggs_collected += lair[\\\"egg_count\\\"] not. This function uses colliderect() to if eggs_collected >= EGG_TARGET: check this. If the hero touches an game_complete = True egg, the egg_count variable will be increased by the number of eggs in that This adds the number of This checks if the number lair. If the egg count reaches the target, eggs for the current lair of eggs collected is greater the game_complete variable will be set to to the player\u2019s egg count. True and the player will win the game. than or equal to the EGG_TARGET. 31 Lose a life Lastly, you need to define the game_complete = True subtract_life() function. Every time the player loses a life, this function will update def subtract_life(): the number of lives remaining. If there are global lives, reset_required, game_over no more lives left, the game_over variable lives -= 1 will be set to True and the game will end. if lives == 0: game_over = True 32 Time to play reset_required = False You are now ready for the quest. Try to collect all 20 eggs to win the game, This variable is set to False, but watch out for those dragons! as the hero is already at the starting position. I did not sign up for this!","GAME PROGRESS 1 0 0 % 195 Hacks and tweaks I could use some help! Add some more challenges to the quest and make the game even more engaging. Here are a few ideas to get you started. if keyboard.d: \u25c1 Add another hero hero2.x += MOVE_DISTANCE All this egg collecting can be a lot of work for one hero. You can add another hero to lend a hand. You\u2019ll if hero2.x > WIDTH: need to add some new code and change some existing code to do this. Begin by changing the hero2.x = WIDTH starting position of the current hero and adding a different one for the new hero. Then add some code elif keyboard.a: to the draw() function to draw the second hero on the screen. Now add the code shown here to the hero2.x -= MOVE_DISTANCE update() function, which will make the second hero move on the screen using a new set of keys\u2014 if hero2.x < 0: W, A, S, D. Lastly, remember to add a parameter to all the functions that check for collisions so they hero2.x = 0 check the collisions for both heroes. elif keyboard.s: This moves the second hero down. hero2.y += MOVE_DISTANCE They are not if hero2.y > HEIGHT: as predictable as hero2.y = HEIGHT you think. elif keyboard.w: I know when the dragons will wake hero2.y -= MOVE_DISTANCE up next. if hero2.y < 0: if lair[\\\"sleep_counter\\\"] >= lair[\\\"sleep_length\\\"]: hero2.y = 0 if random.choice([True, False]): lair[\\\"dragon\\\"].image = \\\"dragon-awake\\\" \u25b7 Less predictable dragons Right now it\u2019s fairly easy to predict when a dragon will wake up. You can add an element of chance to each dragon\u2019s sleep cycle to make the game more challenging. For this, you\u2019ll first need to import the Random module at the top of your program. Then you\u2019ll need to add some code to the update_sleeping_dragon() function. This will randomly decide whether to wake up the dragon each time the function is called. To do this, add the line of code shown in black here to Step 23.","","Reference","198 R E F E R E N C E Project reference This section contains the complete Python code for every game in this book, except for the hacks and tweaks. If your games don\u2019t run properly, check their scripts carefully against the code shown here. Shoot the Fruit (page 48) from random import randint apple = Actor(\\\"apple\\\") def draw(): screen.clear() apple.draw() def place_apple(): apple.x = randint(10, 800) apple.y = randint(10, 600) def on_mouse_down(pos): if apple.collidepoint(pos): print(\\\"Good shot!\\\") place_apple() else: print(\\\"You missed!\\\") quit() place_apple() Coin Collector (page 58) from random import randint WIDTH = 400 HEIGHT = 400 score = 0 game_over = False fox = Actor(\\\"fox\\\") fox.pos = 100, 100 coin = Actor(\\\"coin\\\") coin.pos = 200, 200"]
Search
Read the Text Version
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226