Rect Collision Response
A simple demo on how to do side-based rect collision response.
ConceptI'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 = wall.rect.top if dy < 0: # Moving up; Hit the bottom side of the wall self.rect.top = wall.rect.bottom # Nice class to hold a wall rect class Wall(object): def __init__(self, pos): walls.append(self) self.rect = pygame.Rect(pos, pos, 16, 16) # Initialise pygame os.environ["SDL_VIDEO_CENTERED"] = "1" pygame.init() # 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 = [ "WWWWWWWWWWWWWWWWWWWW", "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", "WWWWWWWWWWWWWWWWWWWW", ] # 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: clock.tick(60) 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) pygame.display.flip()
Pygame.org 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.437758Custom 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.838007Explore the world of party supplies and be inspired by our many products for your big party.Shop engangsservice or disposable tableware supplies at ctiparty.dk
alianaalisa 2020-07-14 18:10:58.699206I 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.822519Thankyou 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.
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
text = smallfont.render("Score: "+str(score), True, red)
SPAWN_LOCATIONS = 
# 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.
NUMBER_OF_BALLS_TO_SPAWN = 300
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
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])
textRect.center = (400 / 2),(700 / 2)+y_displace
# SPawn all the balls.
for event in pygame.event.get():
if event.type == QUIT:
# 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:
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
alianaalisa 2020-06-11 12:24:21.255358I 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.989885very nice
alianaalisa 2020-06-06 13:13:54.697221A 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.382921The link is broken melbetindia
alianaalisa 2020-06-08 14:03:11.953571Excellent 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.993931I 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.274232Such 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.694477Thx for sharing this with us ... Get free netflix Premium account .. https://tricksndtips.com/free-netflix-accounts/
alianaalisa 2020-08-06 07:52:25.975761Just 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.589118he “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