-1

I was only just introduced to Python and I am having a bit of trouble on detecting collision between two rectangles. I want a one rectangle to bounce off the other when they collide

Here is my code so far:

import pygame
import sys
from pygame.locals import *
pygame.init()
ww = 400
wh = 300
w = pygame.display.set_mode((ww,wh))
pygame.display.set_caption('OFK')
s = pygame.display.get_surface()
green = pygame.Color(152,251,152)
blue = pygame.Color(135,206,250)
white = pygame.Color(255,255,240)
clock = pygame.time.Clock()
background_file = 'ice-in-water.jpg'
background_image = pygame.image.load(background_file).convert()
rx = ww/2
ry = wh/2
rw = 30
rh = 20
px = ww/2
py = wh - 40
pw = 60
ph = 10
vdirection = -1
hdirection = 1
while True:
  clock.tick(60)
  for event in pygame.event.get():
    if event.type == QUIT:
      pygame.quit()
      quit()
    if event.type == KEYDOWN:
      #print (event.key,event.unicode)
      if event.key == 275:
        px = px + 30
        if px > ww - pw:
          px = ww - pw
      if event.key == 276:
        px = px - 30
        if px < 0:
          px = 0
  s.fill(green)
  pygame.draw.rect(s,blue,(rx,ry,rw,rh),0)
  pygame.draw.rect(s,white,(px,py,pw,ph),0)
  #w.blit(background_image,(-80,0))
  pygame.display.update()
  #mx,my = pygame.mouse.get_pos()
  #print ("x: ", mx, "y: ", my)
  #print ("ry: ", ry, "wh: ", wh)

  rx = rx + 1.5 * hdirection
  if rx > ww - rw:
    hdirection = -hdirection
  if rx < 0:
    hdirection = -hdirection

  ry = ry + 1.5 * vdirection
  if ry > ww:
    rx = ww/2
    ry = wh/2
    vdirection = -vdirection
  if ry < 0:
    vdirection = -vdirection

I have tried finding tutorials on how to do this, but I can't understand very well. A little help would be appreciated.

Nikolay Kostov
  • 16,433
  • 23
  • 85
  • 123
acornjelly
  • 1
  • 1
  • 3
  • 1
    What's the exact question that you have, or what's not working in your code? – Endareth Jul 03 '15 at 06:46
  • Sorry. How can I make the rectangle bounce off the other one when it hits it. – acornjelly Jul 03 '15 at 06:47
  • Yes, got that. It looks like you've tried to implement that in the code above, what bit of it doesn't work? – SiHa Jul 03 '15 at 06:52
  • I am trying to create a simple version of brick breaker. So far, my code only works so that the "ball" (which is a rect) bounces off the walls, but I want it to bounce off the paddle (second rect) as well. – acornjelly Jul 03 '15 at 06:57
  • 1
    https://www.youtube.com/watch?v=jeZkAKtDIX0 Here is a tutorial on Collision Detection. – Dobz Jul 03 '15 at 06:57

2 Answers2

0

In the Rect class of pygame there is a method called colliderect.

You can also refer to this previous answer for some hints.

Community
  • 1
  • 1
Steven Correia
  • 461
  • 10
  • 18
0
  • I calculate the angle between the two center points of the circles. Also remember arctan returns an angle between -pi/2 and pi/2 meaning you need to account for the other side of the unit circle.

  • then I use the angle to determine the exact points of the circles which point toward the other circle if you were to draw a line from center point to center point.

  • finally, I'm casting them to int as an easy way of checking to see if the two points end up being equal.

def detectCollision(self, game):
    for planet in game.planets:
        directionX = self.x - planet.x
        directionY = self.y - planet.y
        theta = atan(directionY / directionX)
        if directionX < 0:
            theta += pi
        if theta < 0:
            theta += 2 * pi

        # point on player circle
        point1 = [self.x + self.radius*cos(theta+pi),self.y + self.radius*sin(theta+pi)]

        # point on planet circle
        point2 = [planet.x + planet.radius*cos(theta), planet.y + planet.radius*sin(theta)]

        if int(point1[0]) == int(point2[0]) and int(point1[1]) == int(point2[1]):
            print("collided!")

This technically works, but will probably have problems if the movement steps are greater than a unit of 1 integer, since we're only checking that they are equal, not whether they've overlapped. A better way might be to leave them as floats and check that the difference comes within a certain bound, possibly dependent on the player velocity to account for larger jumps between frames.

Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
DGenther
  • 11
  • 1