Search code examples
pythonpython-3.xpygamepygame-surface

Pygame renders text over old text


I have this following function to draw to the pygame window:

    base.draw(win, rocket.in_space)
win.blit(rocket_img, (120, 150))
if rocket.in_space:
    velocity_label = STAT_FONT.render(f"Velocity: {round(rocket.velocity, 3)} km/s", True, (255, 255, 255))
    acceleration_label = STAT_FONT.render(f"Acceleration: {round(rocket.acceleration, 3)} km/s^2", True, (255, 255, 255))
    altitude_label = STAT_FONT.render(f"Altitude: {round(rocket.altitude, 3)} km", True, (255, 255, 255))
    fuel_label = STAT_FONT.render(f"Fuel: {round(rocket.fuel, 2)} kg", True, (255, 255, 255))
    time_label = STAT_FONT.render(f"Time: {round(rocket.time_passed, 2)} s", True, (255, 255, 255))
else:
    velocity_label = STAT_FONT.render(f"Velocity: {round(rocket.velocity, 3)} km/s", True, (0, 0, 0))
    acceleration_label = STAT_FONT.render(f"Acceleration: {round(rocket.acceleration, 3)} km/s^2", True, (0, 0, 0))
    altitude_label = STAT_FONT.render(f"Altitude: {round(rocket.altitude, 3)} km", True, (0, 0, 0))
    fuel_label = STAT_FONT.render(f"Fuel: {round(rocket.fuel, 2)} kg", True, (0, 0, 0))
    time_label = STAT_FONT.render(f"Time: {round(rocket.time_passed, 2)} s", True, (0, 0, 0))
win.blit(velocity_label, (0, 0))
win.blit(acceleration_label, (0, 50))
win.blit(altitude_label, (0, 100))
win.blit(fuel_label, (0, 150))
win.blit(time_label, (0, 200))
pygame.display.update()

And this code to make the background move:

class Base:
VEL = 5
HEIGHT = bg_img.get_height()
IMG = bg_img
space = space_img

def __init__(self, x):
    self.x = x
    self.y1 = 0
    self.y2 = self.HEIGHT

def move(self, vel):
    self.VEL = vel
    self.y1 -= self.VEL
    self.y2 -= self.VEL
    if self.y1 + self.HEIGHT < 0:
        self.y1 = self.y2 + self.HEIGHT

    if self.y2 + self.HEIGHT < 0:
        self.y2 = self.y1 + self.HEIGHT

def draw(self, win, in_space):
    if in_space:
        win.blit(self.space, (self.x, self.y2))
        win.blit(self.space, (self.x, self.y1))
    else:
        win.blit(self.IMG, (self.x, self.y2))
        win.blit(self.IMG, (self.x, self.y1))

However, when the background starts speeding up, the text begins to render over itself. I'm not sure why this happens. Any help is greatly appreciated.

Edit: The speed at which the base moves increases over time

Screen freezes

This is what it looks like when the screen freezes.


Solution

  • The issue is the computation of the y-coordinate of the background. The algorithm breaks down, if self.VEL is greater than HEIGHT. Use the modulo (%) operator to compute the y-coordinate:

    class Base:
        VEL = 5
        HEIGHT = bg_img.get_height()
        IMG = bg_img
        space = space_img
    
        def __init__(self, x):
            self.x = x
            self.y = 0
    
        def move(self, vel):
            self.VEL = vel
            self.y = (self.y - self.VEL) % self.HEIGHT
            
        def draw(self, win, in_space):
        if in_space:
            win.blit(self.space, (self.x, self.y - self.HEIGHT))
            win.blit(self.space, (self.x, self.y))
        else:
            win.blit(self.IMG, (self.x, self.y - self.HEIGHT))
            win.blit(self.IMG, (self.x, self.y))