PyGame use for Game development

Hey Hi, this is Shubham Mishra, today we will going to look at the tools and tricks to implement and run a desktop game with the help of Pygame library.

Before starting I would like to mention basic prerequisite as Python language and it should be installed in your computer. I recommend the latest python version. I used Python 3.7.0 version. If you do not have Pygame module installed then in command prompt just type 'python3 -m pip install -U pygame --user'

Pygame is one of the popular collection of modules written in python. In the below discussion I will give a working code sample for a game which I named it 'CarShoot'. If you want the complete sources just download it from my Github repo CarShootGame

Once you set up everything now it's time to run the code as 'python Car1.py' and play the game.


Python Game Development - Shubham Mishra
Pygame : Python Game Development


The bar in the upper left corner is the progress bar for the game. The blue car is the Hero and the animal in grey (bad guy) running towards the car are the evils. Your task is to make the car run without colliding to the car and click mouse left button to fire the missile on the bad guy. At the end of the game, the score will be shown.

Now it's the time to understand the code, open Car1.py file.




import pygame

from pygame.locals import *

import math

import random

pygame.init()
width, height = 640, 480  # window's dimension
screen = pygame.display.set_mode((width, height))
keys = [False, False, False, False]  # all W-A-S-D keys for Car movement
playerpos = [100, 400]
trees = [[10, 0]]
acc = [0, 0]
arrows = []
badtimer = 100
badtimer1 = 0
badguys = [[640, 100]]
healthvalue = 194
pygame.mixer.init()

player = pygame.image.load("resources/images/Car.png")
tree = pygame.image.load("resources/images/Tree.png")
Blood= pygame.image.load("resources/images/Blood.png")
tree1 = tree
grass = pygame.image.load("resources/images/CarGrass.png")
castle = pygame.image.load("resources/images/castle.png")
road = pygame.image.load("resources/images/Road.png")
arrow = pygame.image.load("resources/images/missile11.png")
badguyimg = pygame.image.load("resources/images/badguy2.png")
healthbar = pygame.image.load("resources/images/healthbar.png")
health = pygame.image.load("resources/images/health.png")
gameover = pygame.image.load("resources/images/gameover.png")
youwin = pygame.image.load("resources/images/youwin.png")
dhamaka = pygame.image.load("resources/images/dhamaka.png")

hit = pygame.mixer.Sound("resources/audio/explode.wav")
enemy = pygame.mixer.Sound("resources/audio/enemy.wav")
shoot = pygame.mixer.Sound("resources/audio/shoot.wav")
hit.set_volume(0.05)
enemy.set_volume(0.05)
shoot.set_volume(0.05)
pygame.mixer.music.load('resources/audio/moonlight.wav')
pygame.mixer.music.play(-1, 0.0)
pygame.mixer.music.set_volume(0.25)

# keep looping through
running = 1
exitcode = 0
while running:
    badtimer -= 1
    # clear the screen before drawing it again
    screen.fill(0)
    # draw the Grass on the screen at X:100, Y:100
    screen.blit(grass, (0, 0))
    screen.blit(grass, (540, 0))
    # draw road
    screen.blit(road, (100, 0))
    # Set Car position
    screen.blit(player, playerpos)
    # Draw arrows

    for bullet in arrows:
        index = 0
        bullet[1] -= 40
        if bullet[1] <= 0:
            arrows.pop(index)
        index += 1
        screen.blit(arrow, (bullet[0], bullet[1]))

    # Draw badgers

    if badtimer == 0:
        badguys.append([random.randint(100, 480), 0])
        #badguys.append([random.randint(100, 480), 0])
        # add tree
        trees.append([random.randint(0, 20), 0])

        badtimer = 100 - (badtimer1 * 2)  # this is to increase rate of evils
        if badtimer1 >= 40:
            badtimer1 = 40
            #badguys.append([random.randint(100, 480), 0])
        else:
            badtimer1 += 20

    index = 0
    playerrect = pygame.Rect(player.get_rect())
    for badguy in badguys:
        if badguy[1] >= 480:
            badguys.pop(index)
        badguy[1] += 5
        # Attack-------------------------------#
        badrect = pygame.Rect(badguyimg.get_rect())
        badrect.top = badguy[1]
        badrect.left = badguy[0]
        if pygame.Rect(badrect.left,badrect.top,29,64).colliderect(playerpos[0],playerpos[1],50,100) == True:
            hit.play()
            healthvalue -= random.randint(5, 15)
            badguys.pop(index)
            screen.blit(Blood, (playerpos[0], playerpos[1]))
        # Check for collisions----------------------------------------------------------------
        index1 = 0
        for bullet in arrows:
            bullrect = pygame.Rect(arrow.get_rect())
            bullrect.left = bullet[0]
            bullrect.top = bullet[1]
            if badrect.colliderect(bullrect):
                enemy.play()
                acc[0] += 1
                badguys.pop(index)
                arrows.pop(index1)
                screen.blit(dhamaka, (bullet[0], bullet[1]))
            index1 += 1
        # Next bad guy
        index += 1
    for badguy in badguys:
        screen.blit(badguyimg, badguy)

    indexTree = 0
    index = 0
    # add trees
    for tree2 in trees:
        screen.blit(tree, (tree2[0], tree2[1]))
        screen.blit(tree, (tree2[0]+540, tree2[1]))
        if tree2[1] >= 480:
            trees.pop(indexTree)
    for tree2 in trees:
        tree2[1] += 7
    # Draw clock
    font = pygame.font.Font(None, 24)
    survivedtext = font.render(
        str((90000 - pygame.time.get_ticks()) / 60000) + ":" + str((90000 - pygame.time.get_ticks()) / 1000 % 60).zfill(
            2), True, (0, 0, 0))
    textRect = survivedtext.get_rect()
    textRect.topright = [635, 5]
    screen.blit(survivedtext, textRect)
    #  Draw health bar
    screen.blit(healthbar, (5, 5))
    for health1 in range(healthvalue):
        screen.blit(health, (health1 + 8, 8))
    # update the screen
    pygame.display.flip()
    # loop through the events
    for event in pygame.event.get():
        # check if the event is the X button
        if event.type == pygame.QUIT:
            # if it is quit the game
            pygame.quit()
            exit(0)
        if event.type == pygame.KEYDOWN:
            if event.key == K_w:
                keys[0] = True
            elif event.key == K_a:
                keys[1] = True
            elif event.key == K_s:
                keys[2] = True
            elif event.key == K_d:
                keys[3] = True
        if event.type == pygame.KEYUP:
            if event.key == pygame.K_w:
                keys[0] = False
            elif event.key == pygame.K_a:
                keys[1] = False
            elif event.key == pygame.K_s:
                keys[2] = False
            elif event.key == pygame.K_d:
                keys[3] = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            shoot.play()
            acc[1] += 1
            arrows.append([playerpos[0] + 20, playerpos[1] + 32])
    # Move player
    if keys[0] and playerpos[1] >= 5:
        playerpos[1] -= 10
    elif keys[2] and playerpos[1] <= 400:
        playerpos[1] += 10
    if keys[1] and playerpos[0] >= 100:
        playerpos[0] -= 10
    elif keys[3] and playerpos[0] <= 490:
        playerpos[0] += 10

    # Win/Lose check
    if pygame.time.get_ticks() >= 90000:
        running = 0
        exitcode = 1
    if healthvalue <= 0:
        running = 0
        exitcode = 0
    if acc[1] != 0:
        accuracy = acc[0] * 0.99 / acc[1] * 100
    else:
        accuracy = 0
# Win/lose display
if exitcode == 0:
    pygame.font.init()
    font = pygame.font.Font(None, 24)
    text = font.render("Accuracy: "+str(accuracy)+"%", True, (255,0,0))
    textRect = text.get_rect()
    textRect.centerx = screen.get_rect().centerx
    textRect.centery = screen.get_rect().centery+24
    screen.blit(gameover, (0,0))
    screen.blit(text, textRect)
else:
    pygame.font.init()
    font = pygame.font.Font(None, 24)
    text = font.render("Accuracy: "+str(accuracy)+"%", True, (0,255,0))
    textRect = text.get_rect()
    textRect.centerx = screen.get_rect().centerx
    textRect.centery = screen.get_rect().centery+24
    screen.blit(youwin, (0,0))
    screen.blit(text, textRect)
while 1:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit(0)
    pygame.display.flip()



The basic logic is that to update the screen in every single millisecond with the help of while() loop. The car, bad guy, missiles are nothing but the images located at the position in the form of (X, Y) coordinate. For each iteration of while loop new position is assigned to each image if it is within the constraints or else it is removed from the screen. For below understanding I recommend you to open Car1.py file simultaneously since I will take the line number as the reference to explain the code.

I have initialized the window size, keys as all W-A-S-D keys for Car movement, player position, trees, arrows are nothing but the missiles array which is initially empty, health value.
The running is set to 1, it is the flag for games continuation. The running is set to zero for two conditions (line no: 180),
  1. If the health value goes below to zero
  2. If the timeout occurs
From line no: 20 to 43, the resources are loaded for the game. file in the formate .wav is for the music purpose.
screen.blit() method is used to add an image to the screen at the position mentioned. The for loop at line no: 61, is for missiles released by the car. variable bullet basically has two values as its X and Y coordinate. So for each bullet in the array of arrows, bullet[0] means its X and bullet[1] means its Y position in the window. If the bullet[1] i.e. Y position goes below to zero that is it goes out of the screen, then we delete it from the arrows array.

line no: 70 to 83, It is an important portion of the code since we are written the logic to increase the rate of the bad guy as the time goes on of the game. The 'badguys' is the collection of bad guys.

At line no: 85, The 'playerrect' is the variable to get the current position of the player. This variable will be useful to check whether the bad guy has collided with the player or not.

From line no:86 to 113, the brain portion of the code as it checks collision and also takes actions based on it. The if condition at line no: 94, checks the collision between bad guy and player. If the collision is their then players health value is reduced else not. The for loop at line no: 101, checks a possible collision among bad guy and missile. If such a collision occurs then a blast image is popped up and accuracy value increased. The 'acc' has two values acc[0] is to store the number of hits among missile and bad guy, the acc[1] is to store the number of missiles fired.

The for loop at line no: 120, is to draw trees on the screen. These trees are just for representation purpose. From line no: 127 to 140, the Clock and the Health bar are drawn.

From line no: 142 to 170, all the events are captured for keyboard's key pressing and mouse clicks. Based on the event the player's position is changed.

The If conditions on line no: 181 is to check the game exit condition. Once the game over it comes out of the while loop and now its time to show the score to the user. 

Enjoyed!, This is the end of our discussion. Now I want you to play with the code and make more few games. 

If you want to know about Data Structure and its type visit my recent post: Data Structure and Data Structure types

See my all posts Shubham Mishra

Ok great, we are done with this post,  

Now if you like my way of talk, lets explore more blogs written by me and my inner knowledge,

Get to know answers for common search on Google : A blog for posts which can help you for daily life problems, such as where to get free images, Topic suggestion for the blog.

Computer Science algorithms and other knowledge share : A blog for posts such as best search algorithm, Top interview questions for diffrent technologies, knowledge share for some frameworks or programming languages for the interview or in general terms.

My ideas to solve real world problems : A blog where me shared and presented my ideas to solve a real world problems, this will be interesting for me.

Future of computer science technology discussed : A blog where me discussed about the future of computer science and new technologies which will change our way for looking to solve problems.

Ruby on Rails Web development Blog : As the name suggest, it is the blog for sharing few knowledge about RoR web development framework.


Liked my blogs, wanna to connect:

LinkedIn   GitHub  |  HackerEarth   ResearchGate  |  Twitter  |  Facebook  |  StackOverflow

Thanks for reading this post, Have a good day :)



Comments

Popular posts from this blog

Amazon Interview question from leetcode coding problem 1

Puzzles for the interview which every one should read once

Use ChatGPT for improve your coding quality