# Pygame - CollideRect - But How Do They Collide?

I'm having some trouble figuring out how I can handle collisions that are specifically colliding on the top or bottom a rect. How can specify those collisions?

Here's a little code snippet to give you an idea of my approach. As it is now it doesn't matter where it collides.

# the ball has hit one of the paddles. send it back in another direction.
if directionOfBall == 'upleft':
directionOfBall = 'upright'
elif directionOfBall == 'upright':
directionOfBall = 'upleft'
elif directionOfBall == 'downleft':
directionOfBall = 'downright'
elif directionOfBall == 'downright':
directionOfBall = 'downleft'


**EDIT**

top
____
|    |
|    |
|    | Sides
|    |
----
bottom


I need to know if the ball has hit either the top or the bottom.

• possible duplicate of 2d Collision detecton axis aligned boxes Sep 3 '13 at 20:56
• When two rects are overlapping there is no directionality to their state of collision, they are just ... colliding ... Do you mean if you have two rects that are moving, how to tell whether or not they collided against a given edge? Sep 4 '13 at 0:46
• @sean No. It's not a duplicate. My question is about Pygame specifically, I'm not making a physics engine myself. Sep 5 '13 at 15:23
• @Mokosha Well they are moving...but I need to know if the one rect (the ball) has collided with the other rect's (the paddle) top or botom. Look at my edit above. Sep 5 '13 at 15:24

# Makeup of angles:

Basically you have to look at the angles between the center of the rectangle you are using for a paddle and the center of the rectangle of the ball (can also be a point since we collapse the ball rectangle into a point anyways).

The angle between the center points is then compared to the quadrants given by the corner points of the paddle (this gives left, right, up, down). The following program does just that with a bit of normalization to make lookup in the array easier.

# Test program

The part relevant to your question is really the DirRect class.

import pygame
import math

class DirRect(pygame.Rect):
def direction_to_rect(self, drect):
ar = math.atan2(self.centery - self.top, self.right - self.centerx) # half of the angle of the right side
# construct the corner angles into an array to search for index such that the index indicates direction
# this is normalized into [0, 2π] to make searches easier (no negative numbers and stuff)
dirint = [ 2*ar, math.pi, math.pi+2*ar, 2*math.pi]
# calculate angle towars the center of the other rectangle, + ar for normalization into
ad = math.atan2(self.centery - drect.centery, drect.centerx - self.centerx) + ar
# again normalization, sincen atan2 ouputs values in the range of [-π,π]
# search for the quadrant we are in and return it
for i in xrange(len(dirint)):
return i
# just in case -1 as error indicator
return -1

pygame.init()

screen = pygame.display.set_mode([400,400])
screen.fill([255,255,255])

# colorize directional information
colors = [ (255,0,0), #right
(0,255,0), #up
(0,0,255), #left
(0,0,0), #down
(255,255,255) # error = -1
]

#show direction for every point
dsurf = pygame.display.get_surface()
for x in xrange(dsurf.get_width()):
for y in xrange(dsurf.get_height()):
prect = pygame.Rect((x,y),(0,0))

running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
running = False
pygame.display.update()

pygame.quit()

def on_collide(paddle, ball):
# we collided, so which side? Args are the Rects of paddle and ball.


• That looks like a great answer, although I have not had the chance to try it yet. But can pygame do print statements? Oct 30 '13 at 23:11
• Yep, you can have a standard console open with pygame. Or you can replace them with your actions there. Oct 31 '13 at 1:37
• this is quiet simple but really what I was looking for Jan 2 '15 at 8:43