46 Video Views·Apr 21, 2025
In this great beginner Pygame project, we rebuild the classic early 2000's flash game 'HELICOPTER' in Python! This tutorial covers everything from setting up a PyGame project, generating a random board, controlling altitude by player keyboard inputs, and scoring and progressive difficulty!
The code and assets are available for download at the link here:
https://github.com/plemaster01/pythonHelicopter
Please consider becoming a super supporter of the channel at the Patreon link here:
https://www.patreon.com/LeMasterTech
Don't forget to leave a like, subscribe, and comment what you'd like to see more of on the channel, and thanks for watching!
TIMESTAMPS:
00:00 Intro
00:19 Setting Up A PyGame Project
03:45 Randomly Generate The Initial Board
12:45 Draw the Board and the Player on Screen
19:53 Handle Player and Board Movement
33:07 Pygame Collision detection between the player and the board!
36:20 Restarting, Score Tracking and High Score Tracking!
42:45 Importing, Scaling, and Drawing a .png image into our Pygame Game!
46:07 Progressive Difficulty In our Pygame Game!
47:28 Outro and Thanks!
what's up you guys welcome back to the
channel in today's video I'm going to
show you how to create this complete
classic helicopter flying game in Python
code using the pi game module we're
going to do it from scratch
[Music]
alrighty so as with every Pi game game
that we do Step One is import pygame if
you don't have it already installed in
your package just go ahead and run pip
install pygame and then right in the
beginning just do pygame dot in it make
sure you spell it right pygame.in it and
I'll try to go pretty quick through some
of the generic stuff that we do in every
video but this is an important step so
we do want to put height and width of
our screen into a couple variables
because we're going to use those in a
lot of positions like for drawing the
obstacles for the helicopter so we're
going to want these in variables
and then to actually use them it's
screen equals and then pygame dot
display and then dot set mode and you
just give it width comma height like
that okay and then if you're gonna uh
want to change the uh caption it's
pygame dot Set uh pygame.display dot set
caption and then you just put what you
want it to be in there and we'll say
helicopter in Python just like that
okay and then if you're gonna have any
text which we are we're going to display
the score stuff like that then you want
to say font and set this up as pygame
dot font with lowercase f dot font with
a capital f and I'm just going to use
freesands bold.ttf because that uh is a
font that comes with most installs
but you can import a more fun font file
here if you want and then we're going to
set up a frame rate which I'll make my
frames 60 and then you need a timer so a
timer is going to be equal to
pygame.time dot clock with a Capital C
and that's really all we need for just
base project setup now we want to do our
main game Loop so we're going to make
this variable run and it'll be true
initially
and we're going to say wall run so until
something stops that run variable we
want the following commands to happen
every time over and over again
so first thing we'll do is we'll just uh
fill it with a background color and I
will use black and then you want timer
dot tick at your frame rate so that just
controls the speed at which your game uh
is gonna move and then we just need to
figure out how to get out of that while
loop so that's the most important first
step when you create a while loop is
make sure you don't create an infinite
while loop you need to have a way to get
out of it and so to do that we'll say
four event in pygame.event.get this is
the event handler of Pi game that will
get everything happening with your
computer so Mouse clicks keyboard clicks
anything like that and then we'll say if
the event that happened
uh is equal to
pygame Dot and then the specific dot
quit command
um and if that is true then we'll set
run equal to false and then we'll come
out of our event handling here and we'll
say every Loop we want this
pygame.display.flip which just throws
every visual element we generate onto
the screen and then pygame.quit outside
of that while loop so uh while run we're
going to do all these things if they hit
the quit button in the top right of our
window then we'll set run equal to false
so it'll come down here and it'll do
pygame.quit and that should be all we
need to do to get our base window so
here you can see we've got a 16 High
1000 wide I tried to go with about the
screen size of the classic game
but feel free to play around with that
um and so the first thing we're going to
want to do really is we're going to want
to handle generating a random map uh
when we boot our game up so we're going
to make a variable
um that I'll call new map and it's going
to be equal to true in the very
beginning and it's going to be equal to
True any time that uh we restart the
game so we'll come right after
timer.tick and we'll just say if new map
then what we want to do is we want to
generate a new board so we'll say all of
the rectangles in our board are map
rects are going to be equal to a
function that we'll call generate
new just like this okay and then we're
going to set new map equal to false
because anytime new map is true we just
want to do this once
so now we have to take a look at what
we're actually going to do with the
generate new function and it's not going
to be that hard so Define generate new
we don't have to pass anything in
um and then what we want to return is
basically a list of rectangles
all right so let's take a look at how
we're going to do this first of all
uh let's just go ahead and put this Rex
list initialized in here
um just as an empty list and then let's
grab the first height of our first
rectangle right so um whatever we want
the height of the first top rectangle to
be equal to let's get a random value So
Random dot Rand end zero to three
hundred and you do have to import the
random module so you need this import
random up there with your import Pi game
that should come with your python
installs but you can run pip to install
it too if you need to
okay so that's going to be the first top
height that we are going to use and then
what we want to say is for I in range
and we need to calculate the total
number of rectangles that we should have
and I actually think the best place to
do this is not going to be inside this
function
I think it'll actually be in our
initialization so it's definitely
possible that you'll want to play around
with these values in your version of the
game but basically I'm going to make an
empty list of the map rectangles out
here but I'm also going to do a little
bit of math okay so I'm going to decide
how wide in pixels I want each rectangle
to be and this is something we can play
around with in a second but I'm going to
say 10 initially when I was playing
around with it that looked pretty good
and then the total amount of rectangles
we want is going to be equal to the
width of our screen floor divided by the
width of our rectangle and so floor
division is uh is how you get an integer
value no matter what so first if for
some reason your width was 1001 this
would round down to the lowest integer
value
okay so we're just gonna do that in the
beginning so that we can reference it in
this function but we can also reference
it in other functions if we so choose
all right so for I in range total number
of rectangles what do we want to do for
every rectangle we want to select a top
height that is going to be close to the
previous top height right because we
don't want to make it impossible to get
through our Channel we want it to kind
of look like a carved continuous path so
the new top height will be our random
dot Rand int and for this one instead of
instead of using the just raw 0 to 300
we want to make sure that it's within I
guess plus or minus some spacer that
we're going to determine so the smallest
value it could be would be top height
minus some spacer value and the farthest
down it could be would be top height
plus some spacer value okay so that'll
be one more variable to put up in the
beginning and I'm going to put a 10 in
here and then once we generate this map
and draw it on the screen I'll show you
what kind of tweaking like this
rectangle width and this spacer value
can get you
but basically what we're doing is for
every rectangle we're going to grab a
new height for it that's within plus or
minus our spacer value of the previous
rectangle that way there's not going to
be any huge really bizarre jumps in the
uh kind of elevation change but then we
also need some limits so we need to say
if top height is ever less than zero
right so if if for some reason the top
height of the first rectangle was five
and then the random selection chose 10
minus that so so negative five we don't
actually want a rectangle that can go
off screen so we want to limit top
height equal to zero
and then I think a good Gap to have
between the top and the bottom rectangle
is 300 pixels that's kind of why I did
it zero to 300 I know I didn't really
touch on where that 300 came from but
that's half the screen so uh basically I
always want the player to have a gap of
300 to fly through so then we need an LF
here that's basically if top height ever
gets greater than 300 then we want to
set top height equal to 300 and so now
you're probably saying like okay that's
fine but we've we've kind of done all
this talking about the top height and we
haven't really used it so now we're
going to basically our top rectangle is
going to be pygame dot draw Dot rect
just like this and then we're going to
put it on the screen and you probably
saw in the intro uh the classic game is
these are just like neon green box so
I'm gonna make my neon green to stay
pretty true to that but you can
definitely play around with color here
if you want to
um and make them you know blue red
whatever you could even make it change
colors as the score increased if you
really wanted to but now we have to be
very careful on the rectangle definition
so the X starting position should be I
times rectangle width right we're going
all the way across the screen I is our
index variable in our for Loop and each
of them should be as wide as our
variable rectangle width and then we
want to have the Y starting position
these are for the top rectangles
remember the Y starting position should
always be zero so it's always starting
at the top of the screen
and then for our oop don't close that
yet there we go and then for our
goodness
excuse me sorry about that
uh so that's our X and Y starting
position then for our width which is
pretty easy
it's just rectangle width and then for
our height it's actually very easy too
it's going to be that top height
variable that we just defined
um and I'm just going to leave it as a
solid rectangle I don't need rounded
edges or anything but so this is going
to give us a row of rectangles across
the top of the screen that will be
within our spacer value of the previous
ones
and this is just going to give us a
really cool top uh row and then the
important thing to do for the bottom row
is just understand that we want like a
constant Gap in this case 300 and so we
can copy this
pygame.draw.rect but we do have to
change several things about it so the X
starting position that doesn't change
but the Y starting position is actually
going to be top height so that variable
we found plus 300 which is basically our
Gap and if you think that you're going
to want to mess with The Gap that the
player flies through you can make this a
variable instead of 300.
uh I don't want to mess with that so I'm
Gonna Leave It 300 but we can then uh
make the rectangle width the same and
then for height of this you could do
some like complicated math to figure out
um you know how high uh the rectangle is
and just draw it to the bottom of the
screen but actually if you make it too
long all it's going to do is draw off
the bottom of the screen so I'm just
going to use height here uh for
convenience but you don't have to like
this is going to be more than enough
always because basically the longest a
bottom rectangle will ever be will be
300 right so you could just get around
that and say 300 here I I don't really
care it's not going to chew up a bunch
of processing power so then you want to
add these rectangles to our list because
we're going to use them for Collision
detection and a lot of other things
later on so we want to Rex dot append
the bottom racked and then uh this is
cool this is saving our rectangle
objects to a rectangles list
but because this is how we generate a
new board we're not actually going to be
drawing these onto the screen every
iteration of the loop so what we need to
do that's all it takes to generate a new
board in the beginning but what we need
to do is we need to make a function
called Draw map that's basically going
to draw those rectangles
every single iteration of the loop
so we'll just make this function draw
map and we're going to pass in the map
rectangles that we should have just
gotten from generate new right and we're
going to come right underneath our
generate new function and now we're
going to make a function called Draw
underscore mapped and we pass in our
list of rectangles and this is super
simple it's just for I in range length
of rectangles then what we want to do
rectangles then what we want to do is
pygame dot draw dot rect on the screen
color green
and then for the rectangle we're just
going to say Rex at I right so we have
all these rectangles defined in our Rex
list so we're just going through one at
a time drawing them on the screen color
green and then what I found just makes
it look a little bit more professional
look a little bit better and help Define
the edges is I just chose here to make a
dark gray border around the entire
screen this is totally an optional step
but I do really like the way it looks so
it just starts at zero zero it's the
full width and the full height and I
gave it a frame width of 12. it just it
looks good to have a border on this
project this is not necessary but okay
so this should be everything we need to
get the board initially created and
randomly generated and then also have it
drawn on the screen so let's take a look
alright so you can see I've got this
kind of lower half slow arcing like
curve to it which is pretty good but if
I booted up again I should get a totally
different board because it's completely
randomly generated so let's try it again
and now you can see it's up at the top
and so now I want to briefly touch on
you can kind of see each individual
rectangle to the next is not a ton of
variation you do get some cool shape but
if you want to mess with that a bit then
what you change is your spacer variable
right so if we said 15 instead and then
we booted it up now you can see you get
uh occasionally you get bigger steps in
it and it can make it a little more
challenging and what you'll see here is
if we made that spacer like 25 you could
get some very big single rectangle jumps
and so like if you had two straight that
were close to your limit you could
change by an entire like 50 and just two
so I am going to leave it 10 for now but
you can play around with it you could
also play around with like rectangle
width here so if I made it 20 if I made
it twice as wide you can see it's
actually kind of a lower def shape you
know so if I were even to make this like
uh five five wide right you're going to
see a lot of really wacky shapes
um and you'll see it's sort of just
increasing definition in it you could
even go down to one and you would get a
really spiky kind of path through um
right it's kind of like sound files
almost
um so that's just I wanted to touch on
what those variables are really doing
for us but I'm going to leave rectangle
width at 10 and I'm gonna leave uh
spacer at 10 for now okay so now let's
go ahead and take a look at what we
should do next and I think the next
thing to do would be draw the player and
then also uh move the player and move
the rectangles right so let's go ahead
and draw the player and I'm going to use
a circular like hitbox for the player
and we are going to actually import a
helicopter shape a little bit later but
for now I'm going to make the player a
circle
just so we get the player's hitbox so we
don't get too caught up in style until
we get the functionality working
and so for this we're going to make
another function called Draw player and
something I'm really trying to do more
of in projects is uh you really use
object oriented programming the way it's
supposed to and so break all of these
functions even if they're only a few
lines a piece out into their own
functions rather than stuff them all in
the game Loop so
all right so we're going to want two new
variables for this we're going to want a
player X variable which I'll just put it
at 100 so it's kind of off of the left
edge of the screen and then we want
player Y which I'll make 300 just
initially it doesn't matter because
actually what we're going to do is come
down inside our generate new function
and we're going to just call that player
y as a global so we don't have to pass
it in and out
but when we Define the top height right
here one more thing that I want to do is
just Define that player y coordinate
as the top height plus 150. and so if
you think about we said the player will
always have a 300
300 pixel Gap and so this is going to
stick the player right in the middle of
the Gap when we generate a new board and
now this function and this function can
officially just be closed while we work
on other functions so let's take a look
at the draw player function now
Define draw
player and basically we don't have to
take anything in because all we're
returning is our player like Circle so
the location and hitbox for the player
which is just going to be equal to
pygame dot draw dot Circle and uh we're
gonna put it on the screen I'm gonna
make this initial circle white so it's
really easy to see against a black
background and then for a center point
we're just going to give it the player X
and player Y coordinates we just came up
with and then for radius I'm just going
to use 20. so we're in a gap of 300 a
radius of 20 might seem like you're
giving the player a ton of space but as
the speed starts to increase on this
game that's actually still going to
become very difficult so totally
something you can mess with if you want
and we will come back to this later and
we'll also this is where we'll
um draw player hit box as Circle and uh
player helicopter image so we're gonna
do the player helicopter image but first
we're gonna talk about how to use
um that hitbox and how to kind of move
the player and move the rectangles so uh
for now if I just make this we should
get a white circle yeah directly in
between our starting objects right so
you could say that it doesn't really
make sense to make the players uh y
position in between the first rectangles
but in my experience you know putting
the player 10 rectangles away there
hasn't been a single situation where
that uh hasn't been close enough to the
original spot so I think that looks
pretty good
um now let's go ahead and take a look at
how to kind of move the player so the
classic way to really move the player is
uh is with one key that you sort of hold
down to get to move up and then you
release to move down and it's sort of
gravity based and momentum based where
the longer you hold it down the faster
you'll shoot up and the longer you've
released it the faster you'll go down
this is similar to like Flappy Bird or
Jetpack Joyride I think as far as I know
helicopter was practically the first one
to do that
so what we're going to do to move the
player is we're going to make a new
variable that we'll call flying so when
you're holding the space bar down you'll
be given the helicopter some gas and
you'll be shooting upward and then when
you release the space bar you'll start
letting gravity do its thing so we need
some new categories in our event
handling we need if event actually
this uh four event in pygame.event.get
we're going to add some new event types
so this should probably shouldn't have
worked it should be if event DOT type is
equal to pygame.quit which I don't know
if you guys are attentive or not but you
may have noticed up to this point I've
been having trouble with the x button
um I'm guessing it was because I just
said if event is equal to pygame.quit
and uh I just answered something I was
trying not to panic and uh be like why
was the x button not working but that's
why and there you go we just learned
something live troubleshooting you guys
are lucky uh so now we want to to event
type equal to pygame Dot and now we want
um not Mouse button down excuse me key
down so just key down like that and
we're going to take a look at what to do
with the space bar so we need if event
dot key is equal to pygame dot k
underscore space
okay just like this and if event dot key
is equal to k space then we want Flying
equal to true all right and now we want
to figure out what's the opposite of
that if event DOT type is equal to
pygame dot key up so you've released the
space bar if event dot key is equal to
pygame dot k underscore space
then flying is equal to false just like
that okay pretty easy
um pretty simple stuff and all we have
to do to use that is basically make a
new function obviously underneath uh our
draw player that we'll call move player
and so for this one we are going to uh
basically get back a new y coordinate
for the player as well as we want to
keep track of the rate of change so our
speed in the y direction
using a new function that we'll call
move player and we need to pass in here
obviously the players y uh the current y
coordinate as well as the current y
speed as well as whether or not we are
flying okay so uh we need to make a new
variable here obviously called y speed
and when the game boots up we'll make it
zero so you're not uh going upwards
you're not going downwards you're just
sitting there and now let's take a look
at how to use that so Define move player
and let's make sure we get our variables
that we said we'd pass in in the correct
order so I think we said y position
and then our speed and then if we're
flying or not and I think we said we
need to return our y position and our
speed now let's just double check that
player y y speed and then whether or not
we're flying and we're gonna pass back
the Y position and the speed yep
so this is actually not that hard all
we're going to do is say if flying is
active then we want our speed to be plus
equals
gravity so we'll say that we move
upwards in the same speed that we move
downwards oops
okay and then our y Position will be
minus equals speed and then we'll say
come on stop fighting me
and then we'll say else meaning flying
is not true then our speed is going to
be minus equals gravity
gravity just like that and then our y
Position will still be yeah it's it's
fighting me on gravity because I haven't
made it yet so actually y position minus
equal speed is true no matter what it's
uh always our y position is always
changing you don't have an option in
this game to stay stationary you either
are going up or down which is actually
kind of the challenge of it so we need
to make this variable gravity that's
also going to be one of the things that
kind of controls the difficulty of the
game
and so you can play around these
variables if you want I have found 0.3
to be a uh you have a lot of control
it's fairly responsive but you don't
have so much control that it's
impossible like it doesn't change so
rapidly that you can't get a handle on
things so now uh that really should be
all we have to do so if we boot this up
and I'm going to try to oh
I went I started by going straight up oh
so make sure you have the uh flying
equals false to start uh because
um you want uh yeah there we go so now
if I tap the space key
I can kind of get the uh player to hover
in place which is kind of fun and if I
hold it down I shoot up with more speed
and if I let go for a while there's a a
pretty significant curve so this is kind
of like a little bit of physics-based
um you know change of Direction gravity
is sort of this acceleration that can
change our why speed over time so it's
really change in velocity per time which
is what acceleration is
okay
and so actually we're not gonna move the
player in the X Direction the way we're
going to give the illusion of flying
forward is by moving all of the
rectangles on the board uh and this is
probably going to be the most
complicated step in the process and the
best part is it's not even that
complicated okay so let's take a look at
it right below where we're moving the
player we're going to want another
function that we're going to call uh
basically move rectangles okay and so
for this we're going to sort of be
overwriting our list of rectangles using
a function called move Rex
move rects and all we're gonna pass in
here are gonna be our map rectangles
okay so let's come below move player and
Define move rectangles and then in here
we're still passing in this list of
rectangles and we're returning
returning the list of rectangles all
right
so uh what are we gonna do inside of
here well we're going to say 4 I in
range length
of our rectangles list so this is
basically saying for every rectangle in
our rectangles list we're just going to
redefine rects at I equal to and so now
the thing about defining a rectangle is
that you don't give it color when you
just Define it like this you give it X
and Y start position and then you also
give it width and height so
it's going to be Rex at I zero minus a
variable we're going to make called map
speed and to start I'm just going to
make map speed equal to 2 but we are
going to make that get progressively
faster the higher the score gets when we
get to the scoring step but so basically
we're taking your X starting coordinate
and we're going to move it to the left
by the speed of the map but then
everything else about the rectangle is
going to stay the same so Rex I one and
then this is going to always be
rectangle width and then this is going
to be Rex
I3 so we want the rectangle to stay the
same vertical height the whole time it's
on there
um so basically we're not changing
anything about the rectangle except its
X position and then we need to do sort
of some checking to see if our rectangle
just got off the map so we're going to
say if Rex at i 0 plus the rectangle
width
um
is less than and now we'll say just zero
so basically you're all the way off the
screen right
um then we want to
Rex dot pop and uh something to actually
be careful about here is we want to pop
two rectangles so we want to pop Rex dot
pop uh we want to pop both of the first
two rectangles because the way we added
to these in the generate new list was we
added the top rectangle then the bottom
rectangle we didn't add all of the top
rectangles to one list and the bottom
rectangles to another we added the top
rectangle then the bottom rectangle but
they're in the same X position so this
means we want to pop the bottom
rectangle and then the top rectangle to
make sure we remove the right number of
rectangles from our list
and then what we're going to do is we're
going to select if we did have to do
this here uh we're gonna select a new
top height top height equal to random
dot Rand
int there we go
um
from Rhett's negative two so this is the
previous top one right so negative 2
means we're now selecting backwards from
the end of the list so negative one is
your last element in the list negative
two is the second to last element in the
list which is gonna be the last top
rectangle because the way we have it set
up we're always adding a bottom
rectangle last but we're going to use
the top rectangle to get our new top
height
okay so top height was three on that
rectangle so the options for this new
rectangle are basically Rex minus two
um three which is the top height minus
the spacer or plus the spacer so this is
how we're gonna get a continuous board
that goes forward
um as we as we play the game
all right and so now we need to do the
same if top height checks uh less than
zero and greater than 300 and actually
the easiest way to do this is just going
to be grab these four lines of code
um and then we will actually use very
similar uh top and bottom rect code so
uh you know you could grab those and try
to
um modify them but I'm gonna just think
through what we're doing now
okay so this is actually pretty
important we're appending to our
rectangles list so we need to put the
new rectangle in this list
and what it's going to be is that Rex
minus 2 plus rect width for starting X
position minus two uh sorry zero so
Rex minus two zero refers to the
previous uh the last top rectangles X
starting position so this new rectangle
is going to be that position
plus the width of one rectangle it's a y
starting position will always be zero
because it's a top rectangle its width
will always be rectangle width and then
its height is going to be this top
height variable
and then we need to also add a bottom
rectangle to make sure we keep these
kind of standard orders of doing things
so we have Rex minus 2 0 and we are
going to add to it the rect width the X
position doesn't change right and then
it's top height plus 300 just like
before and then rect width and then I'm
just to be consistent I'm going to throw
height in here as well and then what we
will do here this is actually an okay
time to incorporate scoring I guess too
so we'll call in the score variable and
we'll say any time we've erased one new
rectangle and drawn on or two new
rectangles I guess and drawn on two new
rectangles we'll call that one point so
let's go ahead and make a variable score
that will just start out equal to zero
but we'll say you get a point every time
you've moved a rectangle off the screen
okay so we haven't put any Collision
detection in but just with this function
that we just made we should have
everything we need uh to get the
rectangles kind of moving as the player
is flying through them so let's go ahead
and boot it up and see if it's working
yeah and you can see like map Speed 2 is
not very fast but that's kind of to give
the player a chance to like initially
get their helicopter flying get a feel
for the controls
and then we're going to want to go ahead
and make like Progressive difficulty but
the last real game mechanic that's
missing is we obviously don't have any
Collision detection and this is going to
be pretty easy so let's go ahead and
sort of take a look at how to do that
next so if we come down below our move
rectangles function
then what we can do is we can create
some variable checking like if game is
over or if it's not I'll call it active
but basically all check Collision needs
to tell us is if we are colliding or if
we aren't and that'll set this active
variable to either true or false so we
need to pass in all of the rectangles
and we need to pass in the player Circle
and I guess we'll pass in active too I'm
not sure if we'll need that or not but
let's pass it in there in case we need
it uh and so now let's come up to our
functions and let's just make a new one
which is going to be called
uh what do we call it check Collision
Define check Collision
and we are going to pass in here the
rects the circle and then also active
and we are just going to return whether
we should still be active okay and just
to briefly touch on you've probably
noticed all of my uh functions I give
the names inside slightly different
names than the name outside that's just
because uh pycharm in particular will
give you this it Shadows the name active
from the outer scope that can create
confusion when your code doesn't really
know which active it's looking at so I
just try to change them up inside the
function just wanted to touch on that
briefly now what we're going to say is
for I in range length of our rectangles
right so for every rectangle in that
rectangles list top or bottom if our
player uh I think I called it Circle if
Circle dot Collide rect and this is a
really nice function that pygame has
built in for its polygons so you can
check if our player's circular hitbox
collides with the rectangle at and so
all you give in here is the rectangle to
check for collision with so if it
collides with a rectangle we're going to
set act equal to false otherwise Act is
going to be equal to true
so I guess this is the benefit of
passing what it's currently Set uh to in
here otherwise you would just want
something like active equals true right
in the beginning but we don't need that
okay and so this should be all we need
to do to create uh working Collision
detection and then to see if it's
working we'll just make it to where our
if active to where our uh player
movement and wrecked uh map movement
only work if active is true and so in
the beginning obviously we want active
equal to True okay so if we did that
right then just with that very simple
function yeah everything will stop
moving when we hit uh a rectangle so
obviously the map's not moving very fast
and the gaps aren't very big so I could
play this forever but if I you know fly
up into a ceiling Target it stops the
game so that's really cool and that is
legitimately the basis of all of this
gameplay so now what I think we should
do is we should incorporate some of
those real like improvements to make
this a much more fun game so first let's
take a look at basically how to restart
the game right
so I think if we press uh the enter key
or uh it's called the return key in pi
game but if you press enter on your
keyboard uh while active is false I
think we should use that to sort of
reboot so we'll say if event dot key in
our pygame.keydown logic if event.key is
equal to pygame dot k underscore and
it's called K return but that's your
Enter key okay it's just because
old-timey keyboard said return instead
of enter there I think it actually goes
back to typewriters which is awesome so
then we'll say if not active meaning uh
if you press the enter key and you've
lost so active is false then we'll
restart but if you hit the enter key
accidentally while you're playing it
won't do anything
um
but then we'll set a few things that new
map variable we made in the beginning
we'll set that equal to True we'll set
active back equal to true we will reset
the Y speed so that you're back to
neutral and then we'll reset the map
speed uh to two or whatever initial
value you want it to have and then we'll
say if score is greater than high score
which we obviously need to make a new
high score variable but then we'll set
our high score variable equal to score
because then the last thing we need to
do is we need to clear out our score so
this is just a quick simple way to check
if we got a new high score every time we
restart and so underneath score let's
just make another variable high score
and we're not doing anything with those
yet but this should allow us so like
when I boot it up if I was caught off
guard and oh okay I died if I hit enter
yeah it generates a new map
um which is really fun and now I can
just sort of keep playing
um so okay I've said several times we're
going to make it progressively more
difficult which is going to be like a
big Improvement for
um a big Improvement for like
replayability and making it fun and
challenging to like beat your high score
so we're going to Define our map speed
as equal to 2 plus the score four
divided by and here's kind of an
interesting thing where whatever number
you put here the bigger you put it
um the the longer you'll be able to play
before losing because basically us this
means every time we score 50 the map's
gonna go one faster so if I put a
hundred here it would be every time we
scored a hundred the map will go one
faster so what you'll see when I boot
this up is uh just by flying for a
little while and surviving
the map is going to start moving a lot
faster so there it just went to three
and then it goes to four and now it's at
five uh six but then the thing is every
time you get another score up It's Gonna
Change speeds even faster because you're
obviously clearing rectangles a lot
faster so you can play around with this
value if you want I found 50 was like
just about the right speed for like a
lot of challenge but also very fun and
rewarding
um okay so I'm gonna do that for map
speed and then uh I'm gonna put a few
things on the screen now so I think we
should put the score and the high score
and instructions to restart on the
screen so let's do screen dot blit of a
font dot render and this is ordinarily a
two-step process but because these are
so simple I'm gonna do it in one line of
code and I'm gonna put the score inside
of a formatted string
uh and then you need to give it the
anti-alias argument of true which just
Smooths it out and then uh we'll have
the text be black which um might seem
like a bold Choice since the background
is black uh so you could you could
change the color of the text if you
wanted but when the green blocks are are
there it'll look really clear and then
when they're not it's okay it's it's
kind of fun and honestly that reminds me
of the classic look of the game anyways
and then so uh we just need to give it
an X and Y starting position for the
screen dot blit which is a block
transfer to actually draw it on the
screen so what we did here is we defined
pygame font of score with the score
variable in it uh color black anti-alias
true and then we screened up blit or
block transfer draw it onto the screen
in position 2015 okay
and now we'll also uh font.render
another one for high score and I put the
score at the top of the screen I'm gonna
put the high score at the bottom of the
screen just like this and so instead of
2015 I'm gonna go 25.65.
um put it pretty close to the bottom and
then I'm also going to say if not active
so the player knows how to uh screened
up so they know how to reboot
um
we'll say press enter to restart
and anti-alias true and color black uh
oh I just did screen.blit but I skipped
font dot render so a lot of the times in
uh projects where I have bigger text or
a ton of text I'll do the font dot
renders and the screen dot Blitz on
different rows
just kind of putting it on one for ease
of use here and I'm gonna put this
pretty close to the middle of the screen
at the top of the screen and also at the
bottom of the screen so same text just
going to draw it in two spots so
regardless of whether you were close to
the bottom or the top of the screen when
you lost this will allow you to see the
instructions for restarting and I think
that's going to be it for that so let's
go ahead and take a look at some of our
uh
some of our work there so far okay so
yeah you can see uh high scores at the
bottom regular scores at the top uh you
can see now every time we get 50
um you can obviously kind of visually
see the map start moving a lot faster
um so let's just go ahead and see if I
can get to like around a thousand
that'll be map will be moving pretty
good and then we should get the uh enter
command uh yeah there we go okay so
press enter to restart that looks pretty
good so I'm good with text but uh one
thing I know I've said a few times that
we want to do is we want to improve the
look of the player right so
um this game is called helicopter it'd
be nice if we could get a good looking
helicopter but we did Define like a
circular uh hitbox already that'll be
really useful
so what we're going to do is we're gonna
instead of this being a white circle
we'll make it a black circle once we're
confident that our helicopters drawn in
the right spot but so uh let's make a
new variable just call it heli uh which
is kind of shortcut for helicopter
um and then pygame dot we're going to do
two things so we're gonna do transform
dot scale so this is going to make sure
that we scale it to the right size but
inside that scale command we're going to
do pygame.image dot load and this is
similar to the font uh rendering and
blending on one line you could do
pygame.mage.load and then scale it it's
just going to be easier like this
so if you've grabbed the code and assets
package from my GitHub you'll have this
exact helicopter image but if you don't
if you have your own helicopter image
you just need to play with the scaling
until you get one that you feel
comfortable with but even though we used
a radius of 20 my helicopter image just
has a lot of empty space around it so I
found 60 by 60 for the scaling really
helps bring it down to a good size where
the main body of the helicopter sort of
works right over top of our Circle here
all right so we come down here uh where
we have
player.draw.circle and that's where we
Define the player
and we're going to do screen dot blit of
our heli image and then for position
it's going to be player X and we're
actually going to scoot It Back 40
pixels
because again the body of the helicopter
is 60 wide but we want the hitbox to
basically be on the cabin of the
helicopter not really the tail so we're
going to scoot It Back 40 and then for
the Y position
we want this this is going to be the top
uh part of your image and we don't
actually want this to be at the center
point we want it to be up a little bit
so we'll do player uh y minus 30 and
let's go ahead and actually this needs
to be
coordinates
inside of screen.blit just like that
okay and so if I boot this up now it
might look a little silly because we
have a white helicopter with a white
circle but what you can see clearly is
the circle lines up pretty good with the
body of our helicopter but we need that
circular hitbox because Pi game is not
great with checking collision with
images you have to set up kind of
complex masking rules so we're going to
keep that but we want to be out of sight
so change the circle to be black and now
you'll have this really crisp looking
helicopter and you won't see the circle
at all and then when you hit something
you'll see the circle a little bit but
it really just makes it so that the
helicopter is a lot easier to see and it
feels pretty fair like it doesn't feel
totally broken like oh I didn't collide
with anything it does feel like the
image is hitting the edges just like
that
um so that's pretty cool uh I would call
that completely done last thing I think
I want to incorporate is just in the
same way we make the speed increase as
we get a higher score I think it's also
fun to make our spacer more difficult as
we get a higher score so like initially
the blocks could only change by 10 per
piece right
um but it's it's actually fun to make it
a second element of like Progressive
difficulty would be if also every 100
pixels we made it to where it could be
one more so like the spacer definitely
increases the difficulty in your game so
whatever you start with if you also made
it to where the pieces could become more
erratic and spread out as you played
that's another fun way to incorporate
Progressive difficulty
so now as I'm flying through here every
50 I'll start to see my helicopter speed
up but then every hundred and it's kind
of a subtle change but every hundred you
might notice your uh path gets a little
bit less smooth so that can kind of
create some more funky shapes and make
it a lot more difficult for the player
to fly through really smoothly so yeah
you can kind of see now we're up at like
a thousand and the shapes are getting
really erratic and difficult so speed
was increasing which is a big deal but
also our shape was increasing okay so we
have high score tracking
um I've covered in a lot of previous
videos how to read and write that high
score into a text file so if you are
interested in setting up a kind of high
scoring that saves when you exit
um check out some of my past videos you
can leave a comment asking sort of which
specific videos uh cover that because on
this tutorial I want to keep it pretty
short and sweet and give you guys this
really cool classic game in literally
138 lines of code like
that is awesome we did it in under an
hour
I had a ton of fun with this game I hope
you did too consider leaving a like on
the channel subscribing to the channel
it helps me out a ton all the support on
YouTube's been really fantastic if you
really love the content that I make and
you want to help me continue producing
great content consider checking out the
patreon link in the description of the
video as well of course all the code and
assets for this project are available in
a GitHub Link in the description as well
and as always thanks for watching and
good luck with your code thanks bye