1

Is there a way to handle collision detection between draw.circle and draw.rect ?

If I try to use sprite collision detection than it says circle has not got rect atrributes.

I create two players: rectangles. I create one ball: circle. I would like to handle the collision between two players and a ball in the best way possible. Could you help ?

I present my code below:

# DATE: 090215

TWO PLAYERS
CONTROL VIA KEYBOARD OR MOUSE
#
import pygame, sys
from pygame.constants import MOUSEMOTION, K_LEFT, K_RIGHT, K_DOWN, K_UP

pygame.init()
clock = pygame.time.Clock()

SCREENW = 800
SCREENH = 600
SCREEN = pygame.display.set_mode((SCREENW,SCREENH),0,32)

WHITE = (255,255,255)
BLACK = (0,0,0)
BLUE = (0,70,160)
RED = (255,0,0)
RECTH = 100
RECTW = 30
#players
PLAYER1P = (0,((SCREENH - RECTH)/2),RECTW,RECTH)
PLAYER2P = ((SCREENW-RECTW),((SCREENH - RECTH)/2),RECTW,RECTH)
# BALLS append with a ball for collision detection purposes
BALLS = []
# PLAYERS append with players for collision detection purposes
PLAYERS = []
# CLASS TO DEFINE PLAYER
class PlayerSprite(pygame.sprite.Sprite):
# define object atributes
    def __init__(self,x,y,rwidth,rheight):
        pygame.sprite.Sprite.__init__(self)    
        self.x = x
        self.y = y   
        self.width = rwidth
        self.height = rheight
# define object behavior
    def update(self,control,Surface,color):
        key = pygame.key.get_pressed()
        self.control = control
        if self.control == 1:               
            self.y = pygame.mouse.get_pos()[1]
            if self.y >= SCREENH - RECTH:
                self.y = SCREENH - RECTH
        if self.control == 0:
            dist = 20
            if key[pygame.K_DOWN]:
                self.y += dist
            if key[pygame.K_UP]:
                self.y -= dist
            if key[pygame.K_LEFT]:
                None
            if key[pygame.K_RIGHT]:
                None
            if self.y >= SCREENH - RECTH:
                self.y = SCREENH - RECTH
            if self.y <= 0:
                self.y = 0
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit() 
    # draw player as a rectangle 
    # the important bit is that here you can change player shape
        self.player = pygame.Rect(self.x,self.y,self.width,self.height)
        pygame.draw.rect(Surface,color,self.player)

class CircleSprite(pygame.sprite.Sprite):
# define object atributes 
    def __init__(self,x,y,rwidth,rheight,speedx,speedy):
        pygame.sprite.Sprite.__init__(self)    
        self.x = x
        self.y = y
        self.speedx = speedx
        self.speedy = speedy
        self.width = rwidth
        self.height = rheight

# define object behavior 
    def update(self,Surface,color):
        #self.control = control
        #if self.control == 1:               
        #        self.y = pygame.mouse.get_pos()[1] 
        self.x += self.speedx
        self.y += self.speedy
   # draw player as a rectangle
   # the important bit is that here you can change player shape
        pygame.draw.circle(Surface, color, (self.x, self.y), self.width, 0)

 # main function 
def main():
# CREATE PLAYER OBJECT before WHILE loop 
    prec1 = PlayerSprite(0,SCREENH/2 - RECTH/2,RECTW,RECTH)
    prec2 = PlayerSprite(SCREENW - RECTW,SCREENH/2 - RECTH/2,RECTW,RECTH)
    prec3 = CircleSprite(SCREENW/2,SCREENH/2,RECTW/3,RECTH/3,10,5)

    PLAYERS.append(prec1)
    PLAYERS.append(prec2)
    BALLS.append(prec3)
    while True:
    # update OBJECT position 
        SCREEN.fill(WHITE) 
        # 0 = KEYBOARD
        # 1 = MOUSE       
        prec1.update(0,SCREEN,BLUE)
        prec2.update(1,SCREEN,BLACK)
        prec3.update(SCREEN,RED)
        # check collision
        is_a_collision = pygame.sprite.collide_mask(prec1,prec3)
        if is_a_collision:
            print "Boom1"
        # change direction
        if prec3.x >= SCREENW or prec3.x <= 0:
            prec3.speedx = - prec3.speedx
        if prec3.y >= SCREENH or prec3.y <= 0:
            prec3.speedy = - prec3.speedy
        pygame.display.update()  
        clock.tick(50)
    pygame.quit()
main()
Dariusz Krynicki
  • 2,544
  • 1
  • 22
  • 47
  • "pygame.sprite.collide_circle() Collision detection between two sprites, using circles. collide_circle(left, right) -> bool. Tests for collision between two sprites, by testing to see if two circles centered on the sprites overlap. If the sprites have a “radius” attribute, that is used to create the circle, otherwise a circle is created that is big enough to completely enclose the sprites rect as given by the “rect” attribute. Intended to be passed as a collided callback function to the *collide functions. – Dariusz Krynicki Feb 10 '15 at 23:30
  • is "rect" a must for sprite ? So, does it mean if I create a sprite by draw.circle will it not have collision detection ? – Dariusz Krynicki Feb 10 '15 at 23:31
  • I know how to do it with an additional if statement with comparision of circle position (x,y) against rectangle (x,y) but I am curious if there is simple collision handle command for circle & rectangle. – Dariusz Krynicki Feb 10 '15 at 23:43
  • Is it important to you that the sprites be drawn directly onto `SCREEN`? It usually makes things a lot more manageable if your sprites have their own images, instead of pasting an *ad hoc* image of themselves on the display surface. Especially so because you're using masks here. I ask so that I can give a better answer. – Augusta Feb 18 '15 at 10:01
  • Additionally, `pygame.sprite.Sprite` is a lot more cooperative if you assign `Rect` and `image` attributes to sprite objects. These are necessary if you plan on using masks and collision functions, since the methods operate on the presumption of their existence. Consider assigning a `rect` property to your classes, something like `@property; def rect(self): ; return pygame.Rect(self.x, self.y, self.width, self.height)`. The rect is not permanent, but will do for just about everything `pygame` might need it for. – Augusta Feb 18 '15 at 10:35

0 Answers0