Level 5: Challenge 1 - IncrediCoders/Python1 GitHub Wiki
Intelli-Scents added this page on March 14, 2023
Let's begin your first challenge for Level 5!
You are going to write code that will add a time limit for 45 seconds for each stage of the game!
To find the Level 5 Challenge 1 code template, open the Level 5 folder, the Challenges folder, and then the Challenge 1 folder. You should already have the files downloaded onto your computer (see Load the IncrediCoders Files). Open the CreeperChase_Challenge1.py file in Visual Studio Code to build the program by following along with my instructions below!
I broke these instructions down into a few sections:
On Line 2, from init import *
, initializes the program (init). This includes code that sets up the file path for the images and text file, gets the fonts ready for this game, sets the window size, and loads the images. This statement allows you to use all the information in that file, for the rest of your program.
NEW CODE: On Line 5, you are going to write your own code to set the timer for 45 seconds. See the next section, "Write Your Own Code", for guidance.
On Line 8, def update(delta_time)
updates each time a key is pressed or a button is clicked (these are called an events). This method will continuously check for these events while the game is running.
On Line 9, for event in pygame.event.get():
starts a for loop that runs for every event in the pygame file.
On Line 10, there is the statement if event.type == pygame.QUIT:
which checks if the player has clicked to close the game window.
On Line 11, if the if statement above is true, the stop()
method closes the game window.
On Line 12, elif key_down(event, " ") and (MY.grounded or MY.level_num > 3):
checks three conditions. It checks if the spacebar has been pressed and if the player is on the ground (MY.grounded
) or if the current level is 4 or higher (MY.level_num > 3
).
On Line 13, MY.player.velocity.y = -700
which allows Paul to use his jetpack to jump.
On Line 14, the boolean MY.grounded = False
so that the program knows that Paul is no longer on the ground. This will effect the animations and Paul's velocity later on in the code.
On Line 15, the method jetpack_up_animation()
animates Paul's jetpack moving upward.
On Line 17, if key_held_down(pygame.K_LEFT):
checks if the left arrow key has been pressed.
On Line 19, the code MY.player.velocity.x = max(MY.player.velocity.x - PLAYER_ACCEL, -PLAYER_MAX_SPEED)
sets Paul's velocity when he is moving to the left.
On Line 21, MY.player.sprite = MY.paul_run_left
sets Paul's sprite to the running to the left animation.
On Line 23, key presses are check again, this time to see if it is the right arrow. The statment elif key_held_down(pygame.K_RIGHT):
does this.
On Line 25, the code MY.player.velocity.x = max(MY.player.velocity.x - PLAYER_ACCEL, -PLAYER_MAX_SPEED)
sets Paul's velocity when he is moving to the right.
On Line 27, MY.player.sprite = MY.paul_run_right
is almost exactly like line 21, this time setting Paul's sprite to the running to the right animation.
On Line 28, we have an else:
statement, which is entered if no keys have been pressed.
On Line 29, we check if Paul is currently on the ground with the if MY.grounded:
statement.
On Line 31, if MY.player.velocity.x > 0:
checks if Paul is idle and facing the right while on the ground.
On Line 32, the variable MY.player.velocity.x
is Paul's speed when he is moving to the right, it is set to max(0, MY.player.velocity.x - PLAYER_DECEL)
which means he is not moving at all.
On Line 33, Paul's sprite is set to the right facing idle animation by making MY.player.sprite = MY.paul_idle_right
.
On Line 34, which is just like line 31 but with a <
rather than a >
, we check if Paul is idle and facing the left.
One Line 35, we set the velocity of Paul to be idle in a similar way as we did on line 32 but with some key changes. The variable MY.player.velocity.x
is the same, but this time is set equal to min(0, MY.player.velocity.x + PLAYER_DECEL)
instead. The key differences between this line and 32 is min rather than max is us, and PLAYER_DECEL
is added rather that subtracted.
On Line 36, Paul's sprite, MY.player.sprite
, is set facing the left and idle by equaling it to MY.paul_idle_left
.
On Line 38, this else:
statement means Paul is falling and not yet on the ground.
On Line 39, if MY.player.velocity.x > 0:
checks if Paul is facing the right, like Line 31 does.
On Line 40, which is almost identical to line 32, MY.player.velocity.x = max(0, MY.player.velocity.x - PLAYER_AIR_DECEL)
. The only difference between the two lines is that PLAYER_AIR_DECEL
is used rather than PLAYER_DECEL
.
On Line 41, if MY.player.velocity.x < 0:
checks if Paul is facing the right, like Line 34 does.
On Line 42, is like 35, except it replaces PLAYER_DECEL
with PLAYER_AIR_DECEL
, making the statement MY.player.velocity.x = min(0, MY.player.velocity.x + PLAYER_AIR_DECEL)
.
On Line 45, the if not MY.grounded:
statement is entered if Paul is not on the ground (so when he is jumping or flying).
On Line 46, if MY.player.velocity.x > 0:
is used to check if Paul is facing right, exactly like it is on Lines 31 and 39.
On Line 47, Paul's jetpack animation where he is facing the right is set by writing MY.player.sprite = MY.paul_jetpack_right
.
On Line 48, elif MY.player.velocity.x < 0:
sees if Paul is facing the left, like Lines 34 and 41 do.
On Line 49, the animation for left hand jetpack movement is set with the statement MY.player.sprite = MY.paul_jetpack_left
.
On Line 52, the game's gravity is calculated and set using the statement MY.player.velocity.y = min(MY.player.velocity.y + GRAVITY_ACCEL, PLAYER_TERMINAL_VEL)
.
On Line 55, there is the first statement that starts the block of code that checks for hazard collision. It is for hazard in MY.hazards:
which loops through all hazards in the level to see whether Paul has run into them.
On Line 56, if MY.player.collides_with(hazard):
is the specific statement that checks if Paul has touched a hazard tile while moving through the level.
On Line 57, if the if statement above is true, Paul's health will be reduced by 1. This is done by MY.player_health -= 1
.
On Line 58, checks to see if Paul's health has reached zero with the statement if MY.player_health == 0:
.
On Line 59, restarts the level with the method restart_level(MY.level_num)
if Paul's health has gone down to 0.
On Line 60, the else:
block is entered if Paul's health is greater than 0 after running into a hazard tile.
On Line 61, to show that Paul is hurt after running into a hazard tile, his pain animation is played with the code MY.player.sprite = MY.paul_pain_right
.
On Line 62, MY.player.location = MY.player_start_position
moves Paul back to the entrance portal of the current level to try the level again.
On Line 63, Paul's velocity is reset with MY.player.set_velocity(0, 0)
.
On Line 66, the movement and animations of Paul are updated with the method MY.player.update(delta_time)
which uses delta_time
as a parameter to keep all the updates in sync.
On Line 69, the boolean touching = False
before checking for wall collisions. Later on, if Paul does collided with a wall, this boolean will be set to True.
On Line 70, for wall in MY.walls:
is a loop that checks each wall in the current level.
On Line 71, if a player collides with any wall, it is caught by the statement if MY.player.collides_with(wall):
.
On Line 72, if MY.player.collision[DOWN]:
checks to see if Paul is moving downward when he collided with the wall. If he has, Line 73-75 will run.
On Line 73, the snap_to_object_y(wall, DOWN)
method is used on MY.player
, which makes Paul land on the floor.
On Line 74, Paul's vertical speed MY.player.velocity.y = 0
to stop him from falling further.
On Line 75, to note than Paul is now on the ground and touching a tile, two corresponding booleans are set to true. This makes the statement MY.grounded = touching = True
.
On Line 76, if MY.player.collision[LEFT]:
checks if Paul has hit a wall on the left.
On Line 77, MY.player.snap_to_object_x(wall, LEFT)
put's Paul's sprite to the left of the wall he hit.
On Line 78, Paul's speed while moving horizontally is set to 0 to stop him from moving through the wall with the code MY.player.velocity.x = 0
.
On Line 79, the boolean touching = True
so that the game knows Paul has hit a wall.
On Line 80, if MY.player.collision[RIGHT]:
checks if Paul had collided on a wall to his right.
On Line 81, is just like Line 77 but with a different parameter, which is RIGHT
instead of LEFT
. MY.player.snap_to_object_x(wall, RIGHT)
places Paul's sprite to the right of a wall when he runs into it.
On Line 82, MY.player.velocity.x = 0
sets his horizontal movement speed to 0 so that he does not move through the wall that he just collided with.
On Line 83, since Paul has now touched a wall, the boolean touching = True
so that the game knows what' just happened.
On Line 84, if MY.player.collision[UP]:
checks if Paul has hit a tile above him.
On Line 85, like with the other collisions, it Paul has hit the wall above the function MY.player.snap_to_object_y(wall, UP)
is used to snap him into place on the ceiling.
On Line 86, MY.player.velocity.y = 0
makes sure Paul is no longer moving and doesn't go through the wall above him.
On Line 87, like when Paul collides with any other wall, touching = True
so that the program can handle his movement and animations accordingly.
On Line 88, if the touching
boolean is False
it will enter the if not touching:
code block.
On Line 89, MY.grounded = False
is set if he has not collided with anything, meaning he is in the air and not touching the ground.
NEW CODE: On Line 92, you will write code to make the timer count down. See the next section, "Write Your Own Code," for some guidance.
NEW CODE: On Line 95, you will write code that checks if the timer has reached 0 and has run out. See the next section, "Write Your Own Code," for some guidance.
NEW CODE: On Line 96, you will show the lose screen if the timer has run out. See the next section, "Write Your Own Code," for some guidance.
On Line 99, if MY.player.collides_with(MY.exit_portal):
checks if Paul has collided with the exit portal to move to the next level or win the game.
On Line 100, the if statement if MY.level_num >= 1 and MY.level_num < 6:
check if the current level is between 1 and 5. If the level is 1-5, then Paul will move to the next level.
On Line 102, To move to the next level, first the variable MY.level_num
is increased by one by setting it = MY.level_num + 1
.
On Line 103, Then the level name is increased by one as well, by writing level_name_as_string = 'Level' + str(MY.level_num)
.
On Line 104, the variable tilemap
is the layout of the level and is loaded by using the read_file()
function. This function has the file location as its parameter to load and read a file. In this case the parameter is "Assets/" + level_name_as_string + ".txt"
.
On Line 105, the function load_level(tilemap)
takes the level information stored in tilemap
and updates the game to show this new level.
NEW CODE: On Line 107, you will write code that resets the timer to be at 45 seconds again. See the next section, "Write Your Own Code," for some guidance.
On Line 108, if Paul is currently on the last level, number 6, and has collided with the exit portal he has won the game. We check the level number is 6 with the statement elif MY.level_num == 6:
.
On Line 110, shows the Win screen with the same function you used before on Line 96 to show the Lose screen. This time the parameter is 2
, making the function change(2)
.
On Line 113, the function update_level(delta_time)
updates all the animations and other information about the level according to delta_time
which keeps all the animations on the level in sync.
On Line 116, Manager.register(sys.modules[__name__])
registers the name of the current file and stores that in the manager module. This file runs the main game.
On Line 117, Manager.register(Lose)
registers the game state when the player loses the game.
On Line 118, Manager.register(Win)
registers the game state when the player wins the game.
On Line 121, Manager.run(SCREEN, WINDOW, BLUE, "CHALLENGE1")
runs the game, with "CHALLENGE1" as one of the parameters so that it knows which challenge of Level 5 to run.
On Line 5, you are going to make the timer last 45 seconds. The timer variable is MY.timer
and you will want to make it equal (=
) to 45 seconds which the timing in seconds is implied, so you can just write 45
.
On Line 92, you are going to write code that makes the timer count down. This is done by using -=
to subtract delta_time
from the timer variable which is represented by MY.timer
. However, since delta_time
is being subtracted, you want to put that at the end after the -=
. The variable _delta_time_
is another word for milliseconds.
On Line 95, you will write an if statement that checks if the timer has reached 0. To do this, you first want to start with if
since it is an "if" statement. Next, you want to check if the player's timer: MY.timer
is less than or equal to (<=
) zero (0
). Make sure to add a colon at the end of the line after the 0 since it is an "if" statment.
On Line 96, you will write the same function that is on Line 110. Line 110 shows the win screen, but here you will show the lose screen. This is done by using the same change()
parameter but instead of the 2 for winning, you will use 1
since this is for the losing screen.
On Line 107, you will write code that resets the timer to be at 45 seconds again. Look back at Line 5 where you set the MY.timer
variable equal to 45
, do the same thing for this line.
I included a solution file for Level 5: Creeper Chase Challenge 1. This file has all the code filled in, so if you run into any issues with your code (for example, it doesn't compile/run, or something isn't working correctly in your program), then you can take a look at the final code file to see what you did differently:
IMPORTANT: Please don't cheat yourself! Finish the game first!
Next, you can take on the other challenge to chase the Creeper and learn more! When you're done, you can move on to Level 6, the Boss Battle!
Challenge 2: In this challenge, you are going to add batteries to the game. Paul collects the batteries to regain his health.
Bonus Challenge: In this extra challenge, you'll see how to make your own levels for Paul to run and jump (and fly) through! Practice your game design skills!
-
Level 5: Unplugged Activity - I wrote this page with more details than what you saw in the book. In this game,
-
Level 5: Rewards - If you completed the Creeper Chase program that we talked about, then I set up this page to act as a reward. You can see some illustrations of me and learn more about who I am! You'll also find the **WHAT **Award digital download, to show off your accomplishment!
-
Level 5: Creeper Chase: All Online Articles - Return back to the main Level 5 page, with all our online resources!
After you're completely done with Level 5 (did you do the challenges?), then it's time to move on to Level 6! While you read through Level 6 in your book, you can check out the resources from Paul Python, as he teaches you how to build the Boss Battle program:
I hope you had fun learning about the Creeper Chase!
--