## Simple Collision Detection Example in Pygame

If you haven’t read Simple Animation In Pygame yet, go check it out. Because I’ll reuse many of the code in that post.

Let’s get started by showing 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
DOWN_LEFT = 1
DOWN_RIGHT = 2
UP_LEFT = 3
UP_RIGHT = 4
directions = [DOWN_LEFT, DOWN_RIGHT, UP_LEFT, UP_RIGHT]
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 = {'rect': pygame.Rect(300, 80, 50, 80), 'dir':UP_RIGHT}
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()

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

if bouncer['dir'] == DOWN_LEFT:
bouncer['rect'].left -= MOVEMENT_SPEED
bouncer['rect'].top += MOVEMENT_SPEED
if bouncer['dir'] == DOWN_RIGHT:
bouncer['rect'].left += MOVEMENT_SPEED
bouncer['rect'].top += MOVEMENT_SPEED
if bouncer['dir'] == UP_LEFT:
bouncer['rect'].left -= MOVEMENT_SPEED
bouncer['rect'].top -= MOVEMENT_SPEED
if bouncer['dir'] == UP_RIGHT:
bouncer['rect'].left += MOVEMENT_SPEED
bouncer['rect'].top -= MOVEMENT_SPEED

# check out of bound
if bouncer['rect'].top < 0: # over the top of window
if bouncer['dir'] == UP_LEFT:
bouncer['dir'] = rd.choice(directions) #DOWN_LEFT
if bouncer['dir'] == UP_RIGHT:
bouncer['dir'] = rd.choice(directions) #DOWN_RIGHT
if bouncer['rect'].bottom > WINDOW_HEIGHT: # below the bottom of window
if bouncer['dir'] == DOWN_LEFT:
bouncer['dir'] = rd.choice(directions) #UP_LEFT
if bouncer['dir'] == DOWN_RIGHT:
bouncer['dir'] = rd.choice(directions) #UP_RIGHT
if bouncer['rect'].left < 0: # out of left side
if bouncer['dir'] == DOWN_LEFT:
bouncer['dir'] = rd.choice(directions) #DOWN_RIGHT
if bouncer['dir'] == UP_LEFT:
bouncer['dir'] = rd.choice(directions) #UP_RIGHT
if bouncer['rect'].right > WINDOW_WIDTH: # out of right side
if bouncer['dir'] == DOWN_RIGHT:
bouncer['dir'] = rd.choice(directions) #DOWN_LEFT
if bouncer['dir'] == UP_RIGHT:
bouncer['dir'] = rd.choice(directions) #UP_LEFT
# draw the bouncer
pygame.draw.rect(window_surface, GREEN, bouncer['rect'])

# check collisions between foods and bouncer
for food in foods[:]:
if check_overlap(food, bouncer['rect']):
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
```

What we’re doing is we create a bouncer, and many boxes. Whenever the bouncer hit a box, the box will be removed from the screen.
What we should focus here is the two important functions, check_overlap and is_point_inside_rect.

Let’s go with is_point_inside_rect_first, since it’s used by check_overlap.
This picture virtually how to check a point’s inside or outside of a rectangle:

A point (x,y) is inside a rectangle if its x is bigger than left and smaller than right side value of rectangle, same goes for top and bottom. In the above pictures, there are three point inside the rectangle.

Now let’s go to the check_overlap function. This function check if four corners of a rect1 is inside rect2 [rect1, rect2] and vice versa [rect2, rect1].

The code inside game loop has been changed a little bit. Line 63 to 74 move the bouncer, line 77 to 96 check if the bouncer hit one of the four sides of the window, if it is, randomly change the direction of it. The for loop at line 101 check if the bouncer collide with any food, and if it collide, it will eat the food, the food will disappear. Notice that we get food from food[:] not food. This is because in Python you should not remove or add a list while iterating through it. For example it’s difficult if you’re counting the number of jelly beans in a jar while someone’s adding or removing jelly beans, same thing goes for list.

Line 111 check if counter > 20, if it is, add more food into foods. The last line , game_clock.tick(), I just simply understand that it kind of sets the frame rate of the game. No matter how fast or slow your computer is, the while loop will always run 40 times per second.

Result of the code above:

That’s it for this tutorial. Feel free to donate, many thanks.