问题
For some reason the Colliderect won't work and the rain passes through pavement. This is really annoying because all of those unused sprites create tons of lag.
import pygame
import random
class Square(pygame.sprite.Sprite):
def __init__(self, x, y, size1, size2, speedx, speedy, colour):
super().__init__()
self.image = pygame.Surface([size1, size2])
self.image.fill(colour)
self.speedx = speedx
self.speedy = speedy
self.rect=self.image.get_rect()
self.rect.x=x
self.rect.y=y
def update(self):
square_colour = (random.randint(0,255), random.randint(0,255), random.randint(0,255))
self.rect.x = self.rect.x + self.speedx
self.rect.y = self.rect.y + self.speedy
my_square = Square(0, 705, 20, 30, 1, 0, (0, 0, 0))
pavement = Square(0, 735, 750, 15, 0 , 0, (100, 100, 100))
allspriteslist = pygame.sprite.Group()
allspriteslist.add(my_square)
allspriteslist.add(pavement)
pygame.init()
screen = pygame.display.set_mode([750,750])
pygame.display.set_caption('Snake Example')
clock = pygame.time.Clock()
background_colour = (150, 150, 150)
done = False
while not done:
r = Square(random.randint(0, 747), 0, 3, 7, 0, 5, (137, 200, 230))
allspriteslist.add(r)
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
done = True
if my_square.rect.x > 750:
my_square.rect.x = - 10
if my_square.rect.x < - 50:
my_square.rect.x = 800
if r.rect.colliderect(pavement.rect):
allspriteslist.remove(r)
screen.fill(background_colour)
allspriteslist.draw(screen)
allspriteslist.update()
pygame.display.flip()
回答1:
You have to detect the collision of all the raindrops with the pavement.
Add a group for the raindrops:
rain = pygame.sprite.Group()
Add each rain drop to the group:
done = False
while not done:
r = Square(random.randint(0, 747), 0, 3, 7, 0, 5, (137, 200, 230))
allspriteslist.add(r)
rain.add(r)
And remove a drop if it hits the ground, by pygame.sprite.Sprite.kill():
done = False
while not done:
# [...]
for r in rain:
if r.rect.colliderect(pavement.rect):
r.kill()
Removing the rain drops can be simplified by using pygame.sprite.spritecollide() and passing True
to the argument dokill
:
done = False
while not done:
# [...]
pygame.sprite.spritecollide(pavement, rain, True)
Complete example code:
import pygame
import random
class Square(pygame.sprite.Sprite):
def __init__(self, x, y, size1, size2, speedx, speedy, colour):
super().__init__()
self.image = pygame.Surface([size1, size2])
self.image.fill(colour)
self.speedx = speedx
self.speedy = speedy
self.rect=self.image.get_rect()
self.rect.x=x
self.rect.y=y
def update(self):
square_colour = (random.randint(0,255), random.randint(0,255), random.randint(0,255))
self.rect.x = self.rect.x + self.speedx
self.rect.y = self.rect.y + self.speedy
my_square = Square(0, 705, 20, 30, 1, 0, (0, 0, 0))
pavement = Square(0, 735, 750, 15, 0 , 0, (100, 100, 100))
allspriteslist = pygame.sprite.Group()
allspriteslist.add(my_square)
allspriteslist.add(pavement)
rain = pygame.sprite.Group()
pygame.init()
screen = pygame.display.set_mode([750,750])
pygame.display.set_caption('Snake Example')
clock = pygame.time.Clock()
background_colour = (150, 150, 150)
done = False
while not done:
r = Square(random.randint(0, 747), 0, 3, 7, 0, 5, (137, 200, 230))
allspriteslist.add(r)
rain.add(r)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
done = True
if my_square.rect.x > 750:
my_square.rect.x = - 10
if my_square.rect.x < - 50:
my_square.rect.x = 800
pygame.sprite.spritecollide(pavement, rain, True)
screen.fill(background_colour)
allspriteslist.draw(screen)
allspriteslist.update()
pygame.display.flip()
来源:https://stackoverflow.com/questions/61453075/how-to-determine-why-objects-pass-through-each-other-in-colliderect