Skip to main content

Rect Collision Response

A simple demo on how to do side-based rect collision response.

This is a simple demo on how to do side-based rectangle collision response. It's extremely simple, and not very hard to understand.


I'm putting this here since it's not in the download. Basically how it works is when you move a rect, you first move along the X axis, test for a collision, move out, then move along the Y axis, test for a collision, and move out. This prevents the infamous "corner-catching" bug, and lets you move smoothly along walls.

#! /usr/bin/env python

import os
import random
import pygame

# Class for the orange dude
class Player(object):
    def __init__(self):
        self.rect = pygame.Rect(32, 32, 16, 16)

    def move(self, dx, dy):
        # Move each axis separately. Note that this checks for collisions both times.
        if dx != 0:
            self.move_single_axis(dx, 0)
        if dy != 0:
            self.move_single_axis(0, dy)
    def move_single_axis(self, dx, dy):
        # Move the rect
        self.rect.x += dx
        self.rect.y += dy

        # If you collide with a wall, move out based on velocity
        for wall in walls:
            if self.rect.colliderect(wall.rect):
                if dx > 0: # Moving right; Hit the left side of the wall
                    self.rect.right = wall.rect.left
                if dx < 0: # Moving left; Hit the right side of the wall
                    self.rect.left = wall.rect.right
                if dy > 0: # Moving down; Hit the top side of the wall
                    self.rect.bottom =
                if dy < 0: # Moving up; Hit the bottom side of the wall
           = wall.rect.bottom

# Nice class to hold a wall rect
class Wall(object):
    def __init__(self, pos):
        self.rect = pygame.Rect(pos[0], pos[1], 16, 16)

# Initialise pygame
os.environ["SDL_VIDEO_CENTERED"] = "1"

# Set up the display
pygame.display.set_caption("Get to the red square!")
screen = pygame.display.set_mode((320, 240))

clock = pygame.time.Clock()
walls = [] # List to hold the walls
player = Player() # Create the player

# Holds the level layout in a list of strings.
level = [
"W                  W",
"W         WWWWWW   W",
"W   WWWW       W   W",
"W   W        WWWW  W",
"W WWW  WWWW        W",
"W   W     W W      W",
"W   W     W   WWW WW",
"W   WWW WWW   W W  W",
"W     W   W   W W  W",
"WWW   W   WWWWW W  W",
"W W      WW        W",
"W W   WWWW   WWW   W",
"W     W    E   W   W",

# Parse the level string above. W = wall, E = exit
x = y = 0
for row in level:
    for col in row:
        if col == "W":
            Wall((x, y))
        if col == "E":
            end_rect = pygame.Rect(x, y, 16, 16)
        x += 16
    y += 16
    x = 0

running = True
while running:
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            running = False
        if e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE:
            running = False
    # Move the player if an arrow key is pressed
    key = pygame.key.get_pressed()
    if key[pygame.K_LEFT]:
        player.move(-2, 0)
    if key[pygame.K_RIGHT]:
        player.move(2, 0)
    if key[pygame.K_UP]:
        player.move(0, -2)
    if key[pygame.K_DOWN]:
        player.move(0, 2)
    # Just added this to make it slightly fun ;)
    if player.rect.colliderect(end_rect):
        raise SystemExit, "You win!"
    # Draw the scene
    screen.fill((0, 0, 0))
    for wall in walls:
        pygame.draw.rect(screen, (255, 255, 255), wall.rect)
    pygame.draw.rect(screen, (255, 0, 0), end_rect)
    pygame.draw.rect(screen, (255, 200, 0), player.rect)



Home Page

Releases account Comments

  • Sillyurs 2011-08-26 13:54:12

    The link is broken...

    asdasdasd 2013-10-28 13:00:42

    swag on u

    alianaalisa 2020-08-02 08:12:10.437758

    Custom designed, cut and sewn to flatter, and made with the most premium materials, our chic everyday apparel redefines luxury. spring workout

    alianaalisa 2020-08-02 11:10:50.604787

    "Global Bizarre uncovers strange facts, conspiracy theories, unexplained mysteries, weird stuff, and esoteric knowledge within our mysterious universe." Mystarious Universe

    alianaalisa 2020-07-09 10:35:45.838007

    Explore the world of party supplies and be inspired by our many products for your big party.Shop engangsservice or disposable tableware supplies at

    alianaalisa 2020-07-14 18:10:58.699206

    I think this is an informative post and it is very useful and knowledgeable. therefore, I would like to thank you for the efforts you have made in writing this article. Travel Inspiration

    alianaalisa 2020-06-10 09:48:52.822519

    Thankyou for sharing the data which is beneficial for me and others likewise to see. high risk business stripe
  • CHAD2430 2014-06-12 15:29:48

    Used the collision detection code on my own project, but the block warps outside the walls provided and is invisible.

  • Duality 2014-09-16 21:54:31

    and how do you do the collsion detection part without using the rect class ? i am trying to understand how this all works.

  • piglet coder 2015-09-10 00:02:13

    How do I use sprites for the walls and player instead of solid colors?

    The Orca 2015-09-11 06:25:56

    You'd just blit the sprites into place rather than drawing rects for them. For example, where it says:
    pygame.draw.rect(screen, (255, 200, 0), player.rect)
    You could replace that with:
    screen.blit(sprite, player_x_coordinate, player_y_coordinate)

    You'd naturally need to make sure the player's x and y coordinates are tracked well. Also, make sure to convert the sprite first. While you can just put the file you wish to use as an image there, it will be extremely slow if not converted outside your game loop.

    piglet coder 2015-11-12 23:25:26

    Oh cool thank you☻☺☻☺☻☺☻☺☻☺☻☺!..
    I'll do something like this.

    es_04 2018-05-28 17:09:53.656128

    Could you please post the code for sprites in walls and player here?
  • rollz 2015-09-19 19:05:16


  • James Witherspoon 2015-10-07 18:57:17

    Hi there, what version of pygame and python is this using? Thanls

  • JBalisticMC 2015-10-24 13:25:47


    red = (255,0,0)

    import pygame, sys, random, time, os
    from pygame.locals import *

    AppleThinkness = 30
    block_size = 20
    FPS = 15

    appleimg = pygame.image.load('apple.png')

    screen=pygame.display.set_mode((700,400),0,32) #Sets screen size to 640 x 360 @ 32 bit
    pygame.display.set_caption('Frantic Balloon Pops')

    icon = pygame.image.load('Untitled-icon.png')


    smallfont = pygame.font.SysFont("comicsansms", 25)
    medfont = pygame.font.SysFont("comicsansms", 50)
    largefont = pygame.font.SysFont("comicsansms", 80)

    lead_x = 700/2
    lead_y = 400/2

    lead_x_change = 10
    lead_y_change = 0

    lead_x += lead_x_change
    lead_y += lead_y_change

    def score(score):
    text = smallfont.render("Score: "+str(score), True, red)
    screen.blit(text, [0,0])

    def spawn_balls():
    # Don't have this in the loop as you only want them to spawn once when the game starts, not every time the game loops.
    for i in range(0,NUMBER_OF_BALLS_TO_SPAWN):
    # This will happen the number of times equal to NUMBER_OF_BALLS_TO_SPAWN at the moment 6.

    # Generate a random x position, between 0 and 640 (Screen width.)
    x_pos_ball = random.randint(0,700-54) # 54 is the size of the ball image, adust end points so they are on screen.
    # Generate a random y position, between 0 and 360 (Screen height.)
    y_pos_ball = random.randint(0,400-54)

    # Draw the ball at the random position

    def text_objects(text,color,size):
    if size == "small":
    textSurface = smallfont.render(text, True, color)
    elif size == "medium":
    textSurface = medfont.render(text, True, color)
    elif size == "large":
    textSurface = largefont.render(text, True, color)

    def message_to_screen(msg,color, y_displace=0, size = "small"):
    textSurf, textRect = text_objects(msg, color, size)
    #screen_text = font.render(msg, True, color)
    #gameDisplay.blit(screen_text, [display_width/2, display_height/2]) = (400 / 2),(700 / 2)+y_displace
    screen.blit(textSurf, textRect)

    # SPawn all the balls.
    while True:
    for event in pygame.event.get():
    if event.type == QUIT:
    screen.blit(background, (0,0))

    score (0)

    # Commented out all this stuff as we dont't need it for random spawning.
    """# so this is where you list all of the locations for each circle...
    spawn_locations = [(0,0),(50,50),(100,100),(150,150),(200,200),

    # so it is just like the fruits where fruits = ["apple", "pear", "some other fruit..."] but instead
    # "apple" is changed for (0,0) which is the coordinate for where you create the circle
    # and this will go through each location i.e (0,0) and blit to the screen a cirle at that location
    # so all you have to do to add more is add more locations to the spawn_locations list"""
    for spawn_location in SPAWN_LOCATIONS:
    screen.blit(ball, spawn_location)

    x,y = pygame.mouse.get_pos()
    x -= pin.get_width()/2
    y -= pin.get_height()/2


    I want when the 'pin' touches the 'balloon' than it will pop. How do I do this? and what do I add?

  • Max 2016-01-09 16:19:06

    Thank you very much :-)

  • xXMartinBauzaXx 2016-05-18 23:49:55

    if you are here that means than you actually have pygame so copy the source code and
    paste it!!!

    alianaalisa 2020-06-11 12:24:21.255358

    I am happy to find your distinguished way of writing the post. Now you make it easy for me to understand and implement the concept. Thank you for the post. audio typing
  • Pavel stanley 2016-08-15 13:31:12

    This tut helped me a lot. Thank you very much.

  • ridgen 2018-04-09 12:05:52.989885

    very nice
  • alianaalisa 2020-06-06 13:13:54.697221

    A very awesome blog post. We are really grateful for your blog post. You will find a lot of approaches after visiting your post. low acid coffee
  • ProcksimaSwon 2020-06-07 12:09:37.382921

    The link is broken melbetindia
  • alianaalisa 2020-06-08 14:03:11.953571

    Excellent post. I was always checking this blog, and I’m impressed! Extremely useful info specially the last part, I care for such information a lot. I was exploring this particular info for a long time. Thanks to this blog my exploration has ended. get a lot of followers on instagram
  • filmizukne 2020-06-20 15:46:51.993931

    I was reading your article and wondered if you had considered creating an ebook on this subject. Your writing would sell it fast. You have a lot of writing talent. 먹튀검증
  • alianaalisa 2020-07-13 19:46:30.274232

    Such a very useful article. Very interesting to read this article.I would like to thank you for the efforts you had made for writing this awesome article. barras de gin
  • Tricksndtips 2020-07-14 23:09:26.694477

    Thx for sharing this with us ... Get free netflix Premium account ..
  • alianaalisa 2020-08-06 07:52:25.975761

    Just One Reason Is A Book Tackling Suicide. A Mental Health toolkit with a simple technique against suicidal thoughts. This book helps to prevent suicide. suicide awareness and prevention
  • alianaalisa 2020-08-06 08:51:35.589118

    he “Super” is a title given to those strains of Kratom which are only obtained from the largest, well-nourished leaves with the highest concentrations of Alkaloids. The Super Green Malay is one of our most loved strains because of its purity and originality. Kratom