Więc próbuję wykryć kolizje w mojej grze przy użyciu instancji. Oto kod:

class Paddle:
def __init__(self, x, y, width, height, rect):
    self.x = x
    self.y = y
    self.width = width
    self.height = height
    self.rect = pygame.rect.Rect(x, y, width, height)
class Ball:
    coordinateX = 600
    coordinateY = 300
    velocity = [random.randint(0,1),random.randint(-1,1)]

player = (Paddle(1100, 300, 10, 30, (1100, 300, 10, 30)))
enemy = Paddle(100, 300, 10, 30, (100, 30, 10, 30))
ball = (Ball.coordinateX, Ball.coordinateY, 15)

A później:

ballRect = pygame.rect.Rect(Ball.coordinateX, Ball.coordinateY, 10, 10)
if pygame.sprite.collide_rect(player, ballRect):
    bounce()
2
PiggyTheFirstAstro 1 kwiecień 2020, 13:25

3 odpowiedzi

Najlepsza odpowiedź

Po pierwsze, podczas tworzenia atrybutu rect dla swojej piłki, powinien to być self.rect = pygame.Rect(x, y, width, height) (zakładając, że importujesz Pygame z import pygame). To powinno wystarczyć na AttributeError. To samo dotyczy Twojego ballRect, ballRect = pygame.Rect(Ball.coordinateX, Ball.coordinateY, 10, 10).

Następnie używasz niewłaściwej funkcji wykrywania kolizji. pygame.sprite odnosi się do czegoś zupełnie innego w Pygame (jego obiekty Sprite), a Twoja klasa Ball ani Paddle nie jest Sprite'ami Pygame, z napisanego przez Ciebie kodu. Dlatego dzwonienie do pygame.sprite.collide_rect() nie ma tutaj sensu.

Zamiast tego powinieneś po prostu użyć rect.colliderect, na przykład:

if rect.colliderect(other_rect):
    # Colliding!
    print("Stop touching me!")

Lub w Twoim przypadku:

if player.rect.colliderect(ballRect):
    bounce()

Ponadto nie musisz przekazywać rect jako argumentu do swojej inicjalizacji Paddle, ponieważ nigdy nie jest używany. rect obiektu jest w całości wygenerowany z innych argumentów.

Wreszcie, Twoja klasa Ball i kod instancji wydają się trochę nieaktualne. Powinieneś go wygenerować i zainicjalizować tak, jak robisz to dla Paddle.

EDYTUJ Jeszcze jedna rzecz. W pygame, kiedy tworzysz obiekt z atrybutem rect, nie musisz już przypisywać wartości x i y do obiektu, ponieważ kiedykolwiek będziesz ich potrzebować, powiedzmy, w a blit, możesz po prostu przekazać rect bezpośrednio (lub rect.x i rect.y w niektórych skrajnych przypadkach) jako argument pozycji, a pygame ładnie poradzi sobie z resztą.

Oto, jak powinien wyglądać Twój kod (po poprawieniu kilku innych rzeczy):

class Paddle():
    def __init__(self, x, y, width, height):
        self.width = width
        self.height = height
        self.rect = pygame.Rect(x, y, width, height)

class Ball():
    def __init__(self, x, y, width, height):
        self.rect = pygame.Rect(x, y, width, height)
        self.velocity = [random.randint(0,1),random.randint(-1,1)]

player = Paddle(1100, 300, 10, 30)
enemy = Paddle(100, 300, 10, 30)
ball = Ball(600, 300, 10, 10)

# Other stuff

# Collision checking
if player.rect.colliderect(ball.rect):
    bounce()
2
underscoreC 1 kwiecień 2020, 17:30

Jak wskazuje nazwa modułu „sprite”, funkcja pygame.sprite.collide_rect i wszystkie inne funkcje wykrywania kolizji oczekują instancji Sprite jako argumentów.

Spójrz na dokumentację:

pygame.sprite.collide_rect()
Wykrywanie kolizji między dwoma duszkami za pomocą prostokątów.
collide_rect(left, right) -> bool

Testy kolizji między dwoma duszkami. Używa funkcji kolizji pygame rect do obliczenia kolizji. Przeznaczone do przekazania jako kolidująca funkcja wywołania zwrotnego do * funkcji collide. Sprite muszą mieć atrybuty „rect”.

(Ponadto zazwyczaj nie używasz tej funkcji bezpośrednio, ale razem z Group).

Więc albo zacznij używać klasy Sprite (co powinieneś zrobić), albo użyj funkcji, które zapewnia klasa Rect, takich jak colliderect:

colliderect()
sprawdź, czy dwa prostokąty nachodzą na siebie
colliderect(Rect) -> bool

Zwraca wartość true, jeśli jakakolwiek część któregokolwiek z prostokątów nakłada się (z wyjątkiem górnej + dolnej lub lewej + prawej krawędzi).

2
Community 20 czerwiec 2020, 09:12

Zgodnie z dokumentacją pygame.sprite.collide_rect() służy do wykrywania kolizji między dwa sprite'y , jednak mijasz obiekt pygame.rect.Rect() i obiekt Paddle .

Więc to, co musisz zrobić, to utworzyć dwa obiekty za pomocą pygame.sprite.Sprite, a następnie wykryć kolizję między nimi, jeśli chcesz użyć pygame.sprite.collide_rect()

1
Seysen 1 kwiecień 2020, 10:36