Simple Example For Handling Input In Pygame

If you haven’t read my post about collision detection in pygame, you must check it out to be able to continue with this tutorial. So check out  collision detection please.

In this example, player will press one (or two) of eight buttons : key up, key down, key left, key right or w,s,a,d to move the box up, down, left, right, respectively. Player can also move the box diagonally. When the box hit the foods, the foods will disappear. When player clicks on the window, new food is created at that position. After each 20 loops, new food is created and placed randomly on the window. The code is almost the same as before, but we removed direction variables, and change them with move_up, move_down, move_left and move_right flags to check for input. If player hit key up or button ‘w’, move_up is true, move_down is false, the box will go up, same goes for the rest.

Here’s the code

import pygame, sys
import random as rd
from pygame.locals import *

# set up pygame
pygame.init()

# set up window
WINDOW_WIDTH = 400
WINDOW_HEIGHT = 400
window_surface = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT), 0, 32)
pygame.display.set_caption('Animation')
game_clock = pygame.time.Clock()

# set up direction
move_left = False
move_up = False
move_right = False
move_down = False
MOVEMENT_SPEED = 4

# set up colors
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
SIZE = 20
counter = 0

bouncer = pygame.Rect(300, 80, 50, 50)
foods = []
for i in xrange(20):
    foods.append(pygame.Rect(rd.randint(0, WINDOW_WIDTH), rd.randint(0, WINDOW_HEIGHT), SIZE, SIZE))

def check_overlap(rect1, rect2):
    """
    :param rect1: pygame rectangle
    :param rect2: pygame rectangle
    :return: True if rect1 overlap rect2
    """
    # check if one of four corners of rect1 is inside rect2
    for a, b in ([rect1, rect2], [rect2, rect1]):
        if is_point_inside_rect(a.left, a.top, b) \
        or is_point_inside_rect(a.left, a.bottom, b) \
        or is_point_inside_rect(a.right, a.top, b) \
        or is_point_inside_rect(a.right, a.bottom, b):
            return True
    else:
        return False

def is_point_inside_rect(x, y, rect):
    return (x > rect.left and x < rect.right and y > rect.top and y < rect.bottom)

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

        if event.type == KEYDOWN:
            if event.key == K_LEFT or event.key == ord('a'):
                move_left = True
                move_right = False
            if event.key == K_RIGHT or event.key == ord('d'):
                move_right = True
                move_left = False
            if event.key == K_UP or event.key == ord('w'):
                move_up = True
                move_down = False
            if event.key == K_DOWN or event.key == ord('s'):
                move_down = True
                move_up = False
        if event.type == KEYUP:
            if event.key == K_ESCAPE:
                pygame.quit()
                sys.exit()
            if event.key == K_LEFT or event.key == ord('a'):
                move_left = False
            if event.key == K_RIGHT or event.key == ord('d'):
                move_right = False
            if event.key == K_UP or event.key == ord('w'):
                move_up = False
            if event.key == K_DOWN or event.key == ord('s'):
                move_down = False
        if event.type == MOUSEBUTTONUP:
            foods.append(pygame.Rect(event.pos[0], event.pos[1], SIZE, SIZE))


    window_surface.fill(BLACK) # set background color of window to black

    # move the bouncer
    if move_down and bouncer.bottom < WINDOW_HEIGHT:
        bouncer.top += MOVEMENT_SPEED
    if move_up and bouncer.top > 0:
        bouncer.top -= MOVEMENT_SPEED
    if move_left and bouncer.left > 0:
        bouncer.left -= MOVEMENT_SPEED
    if move_right and bouncer.right < WINDOW_WIDTH:
        bouncer.right += MOVEMENT_SPEED

    # draw the bouncer
    pygame.draw.rect(window_surface, GREEN, bouncer)

    # check collisions between foods and bouncer
    for food in foods[:]:
        if check_overlap(food, bouncer):
            foods.remove(food)

    # draw 'foods'
    for food in foods:
        pygame.draw.rect(window_surface, BLUE, food)

    # after each 40 loops, we add new food
    counter += 1
    if counter > 20:
        counter = 0
        foods.append(pygame.Rect(rd.randint(0, WINDOW_WIDTH), rd.randint(0, WINDOW_HEIGHT), SIZE, SIZE))

    # draw the window onto the screen
    pygame.display.update()
    # sleep 0.02 second (around 50 frame per seconds)
    game_clock.tick(40) # 40 frame per second


 

Demo

Advertisements