Sprite'y przyklejone do krawędzi okna, gdy prędkość jest mniejsza niż 1 [duplikat]

Dec 28 2020

Próbuję stworzyć ruchome chmury dla mojej gry, ale sprite'y chmur utknęły na granicach, kiedy ustawię prędkość chmury na mniej niż 1. Chcę, aby chmura nadal się poruszała, jeśli część chmury jest już poza ekranem. Dowiedziałem się, że duszki utknęły, jeśli x z rect jest równe 0. Jak to naprawić?

Mój kod:

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

Odpowiedzi

2 Rabbid76 Dec 28 2020 at 21:01

Ponieważ pygame.Rectma reprezentować obszar na ekranie, pygame.Rectobiekt może przechowywać tylko integralne dane.

Wszystkie współrzędne obiektów Rect są liczbami całkowitymi. […]

Ułamkowa część współrzędnych zostaje utracona, gdy nowe położenie obiektu zostanie ustawione na obiekt Rect :

self.rect.x -= self.vel

Jeśli chcesz przechowywać pozycje obiektu z dokładnością zmiennoprzecinkową, musisz zapisać lokalizację obiektu w osobnych zmiennych lub atrybutach i zsynchronizować pygame.Rectobiekt. roundwspółrzędne i przypisz je do lokalizacji (np. .topleft) prostokąta:

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)