Beginning Game Programming for Teens with Python
This is a post by Tutorial Team Member Julian Meyer, a 13-year-old python developer. You can find him on Google+ and Twitter. Have you ever wondered how video games are created? It’s not as complicated as you might think! In this tutorial, you’ll create a simple game called Bunnies and Badgers, where the hero, the […] By .
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Beginning Game Programming for Teens with Python
35 mins
- Getting Started: Installing Python
- Running Python Code from File
- Adding the Game Resources
- Step 1: Hello Bunny
- Step 2: Add Scenery
- Step 3: Make the Bunny Move
- Step 4: Turning the Bunny
- Step 5: Shoot, Bunny, Shoot!
- Step 6: Take Up Arms! Badgers!
- Step 7: Collisions with Badgers and Arrows
- Step 8: Add a HUD with Health Meter and Clock
- Step 9: Win or Lose
- Step 10: Gratuitous Music and Sound Effects!
- Where To Go From Here?
Step 4: Turning the Bunny
Yes, your bunny now moves when you press keys but wouldn’t it be even cooler if you could use your mouse to rotate the bunny to face a direction of your choosing, so he’s not facing the same way all the time? It’s simple enough to implement using trigonometry.
Take a look at the following illustration:
In the above image, if (5,3) is the position of the bunny and (2,4) is the current position of the mouse, you can find the rotation angle (z) by applying the atan2 trigonometric function to the difference in distances between the two points. Of course, once you know the rotation angle, you can simply rotate the bunny accordingly. :]
If you’re a bit confused about this part, don’t worry – you can continue on anyway. But this is why you should pay attention in Math class! :] You’ll use this stuff all the time in game programming.
Now you need to apply this concept to your game. To do this, you can use the PyGame Surface.rotate(degrees) function. Incidentally, keep in mind that the Z value is in radians. :[
The atan2 function comes from the Python math library. So add this to the end of section #1 first:
import math
Then, replace the last line in section #6 (the player.blit line) with the following code:
# 6.1 - Set player position and rotation
position = pygame.mouse.get_pos()
angle = math.atan2(position[1]-(playerpos[1]+32),position[0]-(playerpos[0]+26))
playerrot = pygame.transform.rotate(player, 360-angle*57.29)
playerpos1 = (playerpos[0]-playerrot.get_rect().width/2, playerpos[1]-playerrot.get_rect().height/2)
screen.blit(playerrot, playerpos1)
Let’s go through the basic structure of the above code. First you get the mouse and player positions. Then you feed those into the atan2 function. After that, you convert the angle received from the atan2 function from radians to degrees (multiply radians by approximately 57.29 or 360/2π).
Since the bunny will be rotated, its position will change. So now you calculate the new bunny position and display the bunny on screen.
Run the game again. If you use just the WASD keys, then the game should behave exactly like before. But if you move your mouse, the bunny rotates too. Cool!
Step 5: Shoot, Bunny, Shoot!
Now that your bunny’s moving around, it’s time to add a little more action. :] How about letting the bunny shoot enemies using arrows? This is no mild-mannered rabbit!
This step is a bit more complicated because you have to keep track of all the arrows, update them, rotate them, and delete them when they go off-screen.
First of all, add the necessary variables to the end of the initialization section, section #2:
acc=[0,0]
arrows=[]
The first variable keeps track of the player’s accuracy and the second array tracks all the arrows. The accuracy variable is essentially a list of the number of shots fired and the number of badgers hit. Later, we will be using this information to calculate an accuracy percentage.
Next, load the arrow image at the end of section #3:
arrow = pygame.image.load("resources/images/bullet.png")
Now when a user clicks the mouse, an arrow needs to fire. Add the following to the end of section #8 as a new event handler:
if event.type==pygame.MOUSEBUTTONDOWN:
position=pygame.mouse.get_pos()
acc[1]+=1
arrows.append([math.atan2(position[1]-(playerpos1[1]+32),position[0]-(playerpos1[0]+26)),playerpos1[0]+32,playerpos1[1]+32])
This code checks if the mouse was clicked and if it was, it gets the mouse position and calculates the arrow rotation based on the rotated player position and the cursor position. This rotation value is stored in the arrows array.
Next, you have to actually draw the arrows on screen. Add the following code right after section #6.1:
# 6.2 - Draw arrows
for bullet in arrows:
index=0
velx=math.cos(bullet[0])*10
vely=math.sin(bullet[0])*10
bullet[1]+=velx
bullet[2]+=vely
if bullet[1]<-64 or bullet[1]>640 or bullet[2]<-64 or bullet[2]>480:
arrows.pop(index)
index+=1
for projectile in arrows:
arrow1 = pygame.transform.rotate(arrow, 360-projectile[0]*57.29)
screen.blit(arrow1, (projectile[1], projectile[2]))
The vely and velx values are calculated using basic trigonometry. 10 is the speed of the arrows. The if statement just checks if the bullet is out of bounds and if it is, it deletes the arrow. The second for statement loops through the arrows and draws them with the correct rotation.
Try and run the program. You should have a bunny that shoots arrows when you click the mouse! :D
Step 6: Take Up Arms! Badgers!
OK, you have a castle and you have a hero who can move and shoot. So what’s missing? Enemies who attack the castle that the hero can shoot at!
In this step, you’ll create randomly generated badgers that run at the castle. There will be more and more badgers as the game progresses. So, let’s make a list of what you’ll need it to do.
- Add bad guys to a list an array.
- Update the bad guy array each frame and check if they are off screen.
- Show the bad guys.
Easy, right? :]
First, add the following code to the end of section #2:
badtimer=100
badtimer1=0
badguys=[[640,100]]
healthvalue=194
The above sets up a timer (as well as a few other values) so that the game adds a new badger after some time has elapsed. You decrease the badtimer every frame until it is zero and then you spawn a new badger.
Now add the following to the end of section #3:
badguyimg1 = pygame.image.load("resources/images/badguy.png")
badguyimg=badguyimg1
The first line above is similar to all the previous image-loading code. The second line sets up a copy of the image so that you can animate the bad guy much more easily.
Next, you have to update and show the bad guys. Add this code right after section #6.2:
# 6.3 - Draw badgers
if badtimer==0:
badguys.append([640, random.randint(50,430)])
badtimer=100-(badtimer1*2)
if badtimer1>=35:
badtimer1=35
else:
badtimer1+=5
index=0
for badguy in badguys:
if badguy[0]<-64:
badguys.pop(index)
badguy[0]-=7
index+=1
for badguy in badguys:
screen.blit(badguyimg, badguy)
Lots of code to go over. :] The first line checks if badtimer is zero and if it is, creates a badger and sets badtimer up again based on how many times badtimer has run so far. The first for loop updates the x position of the badger, checks if the badger is off the screen, and removes the badger if it is offscreen. The second for loop draws all of the badgers.
In order to use the random function in the above code, you also need to import the random library. So add the following to the end of section #1:
import random
Finally, add this line right after the while statement (section #4) to decrement the value of badtimer for each frame:
badtimer-=1
Try all of this code out by running the game. Now you should start seeing some real gameplay – you can shoot, move, turn, and badgers try to run at you.
But wait! Why aren't the badgers blowing up the castle? Let's quickly add that in...
Add this code right before the index+=1 on the first for loop in section #6.3:
# 6.3.1 - Attack castle
badrect=pygame.Rect(badguyimg.get_rect())
badrect.top=badguy[1]
badrect.left=badguy[0]
if badrect.left<64:
healthvalue -= random.randint(5,20)
badguys.pop(index)
# 6.3.3 - Next bad guy
This code is fairly simple. If the badger's x value is less than 64 to the right, then delete that bad guy and decrease the game health value by a random value between 5 and 20. (Later, you will display the current health value on screen.)
If you build and run the program, you should get a bunch of attacking badgers who vanish when they hit the castle. Although you cannot see it, the badgers are actually lowering your health.