Lucas
Lucas

Reputation: 35

Pygame moving image over rectangle with different colors

I am new to python and pygame and I'm trying to move a image over drawed rectangles with changing colors. Whenever I run this code the image moves but it creates a track of the image.

I know that I need to blit the background of the image in the game loop but how can I blit the background if the background is not an image?

Or do I need to draw my rectangles in a different way?

Full code:

import pygame


pygame.init()
screen = pygame.display.set_mode((600,200))
pygame.draw.rect(screen, (175,171,171), [0, 0, 600, 200])
pygame.draw.rect(screen, (255,192,0), [200, 0, 200, 200])
clock = pygame.time.Clock()
# load your own image here (preferably not wider than 30px)
truck = pygame.image.load('your_image.png').convert_alpha()


class Truck:
    def __init__(self, image, x, y, speed):
        self.speed = speed
        self.image = image
        self.pos = image.get_rect().move(x, y)

    def move(self):
        self.pos = self.pos.move(self.speed, 0)




def game_loop():
    newTruck = Truck(truck, 0, 50, 1)
    gameExit = False
    while not gameExit:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                gameExit = True

        newTruck.move()
        screen.blit(newTruck.image, newTruck.pos)
        clock.tick(60)
        pygame.display.update()

game_loop()

Upvotes: 1

Views: 1780

Answers (2)

skrx
skrx

Reputation: 20438

You can just move the two lines that draw your rects into the main while loop:

def game_loop():
    newTruck = Truck(truck, 0, 50, 1)
    gameExit = False
    while not gameExit:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                gameExit = True

        newTruck.move()
        # Draw the background items first, then the foreground images.
        # If the rects don't cover the whole screen, you can use
        # `screen.fill(some_color)` to clear it.
        pygame.draw.rect(screen, (175,171,171), [0, 0, 600, 200])
        pygame.draw.rect(screen, (255,192,0), [200, 0, 200, 200])
        screen.blit(newTruck.image, newTruck.pos)
        clock.tick(60)
        pygame.display.update()

If the background should be static, you could also draw the rects onto a background surface once and then blit this surf onto the screen in the main loop as jsbueno suggests.

Upvotes: 0

jsbueno
jsbueno

Reputation: 110186

You have to somehow redraw all the objects (rectangles) in your background at every update.

The simplest way to do this is just to call all the drawing code again, before updating your foreground object. Another way, if the background does not change after created, is to blit these background objects into a separate Surface object, and blit that one to the screen on every update.

More sophisticated ways would be to save the background under your foreground objects are prior to drawing them, and then, on the next redraw, first redraw the background and then save the background again and draw the foreground objects on the new position. It is easier to do one of the former methods.

Your code could be written like this:

import pygame

pygame.init()
SIZE = (600,200)

screen = pygame.display.set_mode(SIZE)

bg_image = None

def draw_background(screen):
    global bg_image
    if not bg_image:
        bg_image = pygame.Surface((SIZE))
        pygame.draw.rect(bg_image, (175,171,171), [0, 0, 600, 200])
        pygame.draw.rect(bg_image, (255,192,0), [200, 0, 200, 200])
        ...
        # Draw whatever you want inside this if body

    screen.blit(bg_image, (0, 0))

...

class Truck:
    ...

def game_loop():
    newTruck = Truck(truck, 0, 50, 1)
    gameExit = False
    while not gameExit:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                gameExit = True

        newTruck.move()
        draw_background()
        screen.blit(newTruck.image, newTruck.pos)
        clock.tick(60)
        pygame.display.update()

game_loop()

Upvotes: 2

Related Questions