How to determine why objects pass through each other in Colliderect

不打扰是莪最后的温柔 提交于 2021-02-11 15:52:48

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!