1

I'm trying to make moving clouds for my game but sprites of clouds stuck to borders when I set the velocity of cloud less than 1. I want that cloud continues moving if a part of the cloud is already outside of the screen. I found out that sprites stuck if x of rect equals 0. How to fix it?

My code:

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

enter image description here

volkovik
  • 77
  • 9

1 Answers1

1

Since pygame.Rect is supposed to represent an area on the screen, a pygame.Rect object can only store integral data.

The coordinates for Rect objects are all integers. [...]

The fraction part of the coordinates gets lost when the new position of the object is set to the Rect object:

self.rect.x -= self.vel

If you want to store object positions with floating point accuracy, you have to store the location of the object in separate variables respectively attributes and to synchronize the pygame.Rect object. round the coordinates and assign it to the location (e.g. .topleft) of the rectangle:

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)
Rabbid76
  • 202,892
  • 27
  • 131
  • 174