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 .

4 (17) · 2 Reviews

Download materials
Save for later
Share
You are currently viewing page 3 of 4 of this article. Click here to view the first page.

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.

  1. Add bad guys to a list an array.
  2. Update the bad guy array each frame and check if they are off screen.
  3. 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.

Step 7: Collisions with Badgers and Arrows

The badgers are attacking your castle but your arrows have no effect on them! How's a bunny supposed to defend his home?

Time to set the arrows to kill the badgers so you can safeguard your castle and win the game! Basically, you have to loop through all of the bad guys and inside each of those loops, you have to loop through all of the arrows and check if they collide. If they do, then delete the badger, delete the arrow, and add one to your accuracy ratio.

Right after section #6.3.1, add this:

        #6.3.2 - Check for collisions
        index1=0
        for bullet in arrows:
            bullrect=pygame.Rect(arrow.get_rect())
            bullrect.left=bullet[1]
            bullrect.top=bullet[2]
            if badrect.colliderect(bullrect):
                acc[0]+=1
                badguys.pop(index)
                arrows.pop(index1)
            index1+=1

There's only one important thing to note in this code. The if statement is a built-in PyGame function that checks if two rectangles intersect. The other couple of lines just do what I explained above.

If you run the program, you should finally be able to shoot and kill the badgers.