обнаружение столкновений в pygame между draw.circle и draw.rect

Есть ли способ обработать обнаружение столкновений между draw.circle и draw.rect?

Если я попытаюсь использовать обнаружение столкновения спрайтов, то будет сказано, что у круга нет атрибутов прямоугольника.

Создаю двух игроков: прямоугольники. Создаю один шар: круг. Я хотел бы как можно лучше справиться со столкновением двух игроков с мячом. Не могли бы вы помочь?

Я представляю свой код ниже:

# 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()

person darkman    schedule 10.02.2015    source источник
comment
pygame.sprite.collide_circle () Обнаружение столкновений между двумя спрайтами с использованием кругов. collide_circle (слева, справа) - ›bool. Проверяет столкновение между двумя спрайтами, проверяя, перекрываются ли два круга с центром на спрайтах. Если спрайты имеют атрибут «radius», который используется для создания круга, в противном случае создается круг, достаточно большой, чтобы полностью охватывать прямоугольник спрайтов, заданный атрибутом «rect». Предназначен для передачи в качестве функции обратного вызова столкновения * функциям collide.   -  person darkman    schedule 11.02.2015
comment
нужен ли rect для спрайта? Итак, означает ли это, что если я создам спрайт с помощью draw.circle, у него не будет обнаружения столкновений?   -  person darkman    schedule 11.02.2015
comment
Я знаю, как это сделать с помощью дополнительного оператора if со сравнением положения круга (x, y) с прямоугольником (x, y), но мне любопытно, есть ли простая команда дескриптора столкновения для круга и прямоугольника.   -  person darkman    schedule 11.02.2015
comment
Для вас важно, чтобы спрайты рисовались прямо на SCREEN? Обычно это делает вещи более управляемыми, если у ваших спрайтов есть собственные изображения, вместо того, чтобы вставлять специальное изображение самих себя на поверхность дисплея. Тем более, что вы здесь используете маски. Я спрашиваю, чтобы лучше ответить.   -  person Augusta    schedule 18.02.2015
comment
Кроме того, pygame.sprite.Sprite будет намного более кооперативным, если вы назначите атрибуты Rect и image объектам-спрайтам. Это необходимо, если вы планируете использовать маски и функции столкновения, поскольку методы работают на основе предположения об их существовании. Рассмотрите возможность присвоения вашим классам свойства rect, например, @property; def rect(self): ; return pygame.Rect(self.x, self.y, self.width, self.height). Прямоугольник не постоянный, но годится практически для всего, для чего pygame он может понадобиться.   -  person Augusta    schedule 18.02.2015