Sprites pegados al borde de la ventana cuando la velocidad es menor que 1 [duplicar]

Dec 28 2020

Estoy tratando de crear nubes en movimiento para mi juego, pero los sprites de las nubes se pegan a los bordes cuando establezco la velocidad de la nube en menos de 1. Quiero que la nube continúe moviéndose si una parte de la nube ya está fuera de la pantalla. Descubrí que los sprites se atascan si x de rect es igual a 0. ¿Cómo solucionarlo?

Mi código:

class Cloud(pygame.sprite.Sprite):
    def __init__(self):
        super(Cloud, self).__init__()
        images = [load_image(f"cloud{i}.png") for i in range(1, 5)]
        self.image = random.choice(images)
        self.rect = self.image.get_rect()

        self.rect.x = random.randrange(WIDTH - self.rect.w)
        self.rect.y = random.randrange(HEIGHT - self.rect.h)

        self.vel = 10 / FPS  # It returns value less then 1

    def update(self, event=None):
        if not event:
            self.rect.x -= self.vel

Respuestas

2 Rabbid76 Dec 28 2020 at 21:01

Dado que pygame.Rectse supone que representa un área en la pantalla, un pygame.Rectobjeto solo puede almacenar datos integrales.

Las coordenadas de los objetos Rect son todos números enteros. [...]

La fracción de las coordenadas se pierde cuando la nueva posición del objeto se establece en el objeto Rect :

self.rect.x -= self.vel

Si desea almacenar posiciones de objetos con precisión de punto flotante, debe almacenar la ubicación del objeto en variables separadas respectivamente atributos y sincronizar el pygame.Rectobjeto. roundlas coordenadas y asígnelo a la ubicación (por ejemplo .topleft) del rectángulo:

class Cloud(pygame.sprite.Sprite):
    def __init__(self):
        super(Cloud, self).__init__()
        images = [load_image(f"cloud{i}.png") for i in range(1, 5)]
        self.image = random.choice(images)
        self.rect = self.image.get_rect()

        self.rect.x = random.randrange(WIDTH - self.rect.w)
        self.rect.y = random.randrange(HEIGHT - self.rect.h)
        self.x, self.y = self.rect.topleft

        self.vel = 10 / FPS  # It returns value less then 1

    def update(self, event=None):
        if not event:
            self.x -= self.vel
            self.rect.topleft = round(self.x), round(self.y)