Pygame Game Development

Add Playing Time Limit to Our Game

Now we add another feature to the game.  This feature adds a time limit for the player to hit the ball.

When the player starts the play, the program initializes the play time to 120 seconds.  The play time continues to count down. The game finishes when the time counts down to zero.  At that time, the screen shows the number of hits scored by the player.

Program name: pygame_hitBall_Score_Time.py

Image file: ball.png

Program Example: Hit Ball with Bat Keeping Score and Time
# This program moves the ball randomly.
# The bat is moved by the keyboard arrow keys.
# The player moves the bat to hit the ball.
import pygame
import time
import random
#Inialize pygame module 
pygame.init()
######     SET up     ######
# Set screen width and height.
screen_width = 800
screen_height = 600
# Define colors tuples RGB values.
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
MAGENTA = (255, 0, 255)
# Create a display surface width = 800 pixels, height = 600 pixels.
screen = pygame.display.set_mode((screen_width, screen_height))
# Give our display window a name 'HitBall_Score_Time'.
pygame.display.set_caption('HitBall_Score_Time')
# time.clock() function provides the clock for app.
clock = pygame.time.Clock()

###### Ball Image load
img = pygame.image.load('ball.png')
####### 

#######
bat_width = 30     # Set bat width and bat height.
bat_height = 50
bat_move = 20  # Set bat movement in pixels each key press.
ball_width = 100

###### Define text font to display text on hitting the ball.
font = pygame.font.SysFont("arial black", 48)
text = font.render("I hit the ball", True, BLUE)
textRect = text.get_rect()
textRect.center = screen_width//2, screen_height * 0.2
######

###### Define font for "bat_out_of_screen" message asking player to Continue or Quit.
fontCorQ = pygame.font.SysFont(None, 30)
######      FUNCTIONS      ######
###### Function to ask player to Continue or Quit.
def userInput(cont_quit, color):
    contOrQuit = fontCorQ.render(cont_quit, True, color)
    screen.blit(contOrQuit, [screen_width/5, 4*screen_height/5])
######

###### Define function for text font for number of hits.
def score(count):
    fontS = pygame.font.SysFont('arial black', 24) # Score Text font and size
    textS = fontS.render('Strikes ='+str(count), True, MAGENTA) #Score text color
    screen.blit(textS, (20, 0)) # Position of  score count text
    pygame.display.update()
######

###### Define function for time remaining in the game. Select text for printing time.
def time1(seconds):			  # 1
    fontT = pygame.font.SysFont('arial black', 36) # Font size=36
    textT = fontT.render('Time remaining ='+str(int(seconds/bat_move)),True, BLACK)
    screen.blit(textT, (300, 0)) # Text position = (300, 0) tuple.
    pygame.display.update()
    
######      Main loop      ######
def mainLoop():
    running = True
    bat_out_of_screen = False
###### Initialize hit count and number of seconds remaining in the game.
    count = 0
    seconds = 120 * bat_move		  # 2
    
###### Initialize bat position.
    xBat = screen_width / 2
    yBat = screen_height / 2
 
    batXstep = 0  # Initialize  bat step each key press.
    batYstep = 0 
###### Ball initial position coordinates.
    x = screen_width / 2
    y = screen_height * 0.7
######
    while running:
###### Ask player to play again or quit.
        while bat_out_of_screen == True:
            screen.fill(WHITE)
            userInput("Bat is out of window! Press Q to Quit or C to Continue", RED)
            pygame.display.update()
 
            for event in pygame.event.get():
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_q:
                        running = False
                        bat_out_of_screen = False
                    if event.key == pygame.K_c:
                        mainLoop()
###### Keyboard Events for bat movement.
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    batXstep = -bat_move
                    batYstep = 0
                elif event.key == pygame.K_RIGHT:
                    batXstep = bat_move
                    batYstep = 0
                elif event.key == pygame.K_UP:
                    batYstep = -bat_move
                    batXstep = 0
                elif event.key == pygame.K_DOWN:
                    batYstep = bat_move
                    batXstep = 0
            if event.type == pygame.KEYUP:
                    batYstep = 0 # If the key is up, do not change bat position.
                    batXstep = 0

###### Check if bat is out of display window.
        if xBat >= screen_width - 50 or xBat < 50 or yBat >= screen_height - 50 or yBat < 50:
            bat_out_of_screen = True
 
        xBat += batXstep
        yBat += batYstep
######
        screen.fill(WHITE)
###### Draw bat rectangle and update the screen.
        pygame.draw.rect(screen, GREEN, [xBat, yBat, bat_width, bat_height])
        pygame.display.update()

###### Generate new ball location randomly for each new frame. 
        x = x + random.randint(-30, 30) 
        y = y + random.randint(-30, 30)
        
###### Check if ball reaches the screen window.
###### Back-off the ball back by 50 pixels if the ball reachs screen boundary.
        back_off = 50
        if  x > 700:
            x = x - back_off
        elif x < 0:
            x = back_off
        if y > 500:
            y = y - back_off
        elif y < 0:
            y = back_off
            
# The blit function draws the ball image on the display at location (x, y).
        screen.blit(img, (x, y))
        pygame.display.update()
###### Call score function.
        score(count)
        time1(seconds)				# 3
######
# If bat comes within 30 pixels of ball’s left x-coordinate
# AND the bat comes within ball’s left edge coordinate + ball_width, then
# test if the bat comes within 30 pixels of ball’s top y-coordinate
# AND the ball’s top edge y-coordinate +ball_width.
        if xBat > x - 30 and xBat < x + ball_width:
            if yBat > y - 30 and yBat < y +ball_width:
                count += 1
                screen.blit(text, textRect) 
# If Bat hit the ball, then print text "I hit the ball".
                pygame.display.update()  # print text "I hit the ball".

        seconds -= 1			 # 4
        if seconds == 0:
            running = False
        clock.tick(60)
        pygame.time.delay(50)
    pygame.quit()
    quit()
 
mainLoop()

Detailed Line-by-line Explanation of the Program:

The program is the same as the previous two programs except for the following.

1) The program defines a new function called “time1()”. This function has one parameter “seconds”.

The time() function is very similar to the function score(count) defined in the previous program.

  • Then, we create a new font variable named “fontT” (T for time) with font type Arial black and font size = 36.
  • Then, we use the render() method to create a font object ‘textT’. We use BLACK color for the text.
  • Next, we blit the text “Time remaining” to the Screen object at location (x, y) = (300, 0) at the top-right corner of the screen
  • Finally, we call the display.update() function to make the time remaining text visible on the screen.
###### Define function for time remaining. Select text for printing time.
def time1(seconds):    # 1)
    fontT = pygame.font.SysFont('arial black', 36) # Font size=36
    textT = fontT.render('Time remaining ='+str(int(seconds/bat_move)),True, BLACK)
    screen.blit(textT, (300, 0)) # Text loaction = (300, 0) tuple
    pygame.display.update()
######

2) In step 2), we initialize the “seconds” variable to 120 seconds and make the seconds variable count seconds.  This gives the player 2 minutes to hit the ball.

    seconds = 120 * bat_move		# 2

3) Next, we call the function ‘seconds’.

        time1(seconds)			# 3

4) In the last step, the program decrements the variable “seconds” by one each second. 

If the variable “seconds” decrements to 0, the program sets the variable “running” = False and the game ends.

        if xBat > x - 30 and xBat < x + ball_width:
            if yBat > y - 30 and yBat < y + ball_width:
                count += 1
                screen.blit(text, textRect) # If Bat hit the ball
                pygame.display.update()  # print text "I hit the ball."
        seconds -= 1			# 4
        if seconds == 0:
            running = False
Verified by MonsterInsights