1

So I have a very basic PyGame Python program which is a 'car' that the user controls and one which comes down he road towards it. How can I get the NPC car to return to its original position once it leaves the screen? My current code is shown below, thanks for any help you can provide!

import pygame, random
from car import Car
from car import AutoCar

pygame.init()
play = True
clock = pygame.time.Clock()
screen = pygame.display.set_mode((700, 750))
pygame.display.set_caption("Car Game")

# Define a bunch of colours
GREEN = (20, 255, 100)
GREY = (210, 210, 210)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
PURPLE = (255, 0, 255)
BLUE = (0, 0, 255)

all_sprites = pygame.sprite.Group()  # Creates a list of all sprites in the game

playerCar = Car(RED, 20, 30)  # Defines the car, its colour, and its 
size
playerCar.rect.x = 200
playerCar.rect.y = 300

AutoCar1 = AutoCar(BLUE, 20, 30)
AutoCar1.rect.x = 200
AutoCar1.rect.y = 20

all_sprites.add(playerCar)  # Adds the playerCar to the list of sprites
all_sprites.add(AutoCar1)  # Adds an automated 'enemy' car which you must avoid



while play:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:  # If the detected event is clicking the exit button, stop the program.
        play = False
    elif event.type == pygame.KEYDOWN:  # If a key is pressed and the key is 'x', quit the game.
        if event.key == pygame.K_x:
            play = False

keys = pygame.key.get_pressed()  # Defines a variable keys that consists of whatever event is happening in the game
if keys[pygame.K_LEFT]:
    playerCar.move_left(5)
if keys[pygame.K_RIGHT]:
    playerCar.move_right(5)
if keys[pygame.K_DOWN]:
    playerCar.move_backward(5)
if keys[pygame.K_UP]:
    playerCar.move_forward(5)

all_sprites.update()  # Draws in all sprites
AutoCar1.auto_move_forward(3)  # Makes the 'enemy' move forward automatically.



# Create the background
screen.fill(GREEN)
# Create the road
pygame.draw.rect(screen, GREY, [100, 0, 500, 750])
# Draw the lines on the road
pygame.draw.line(screen, WHITE, [340, 0], [340, 750], 5)

# Draw in all the sprites
all_sprites.draw(screen)

pygame.display.flip()
clock.tick(60)  # Cap limit at 60FPS

pygame.quit()

I also have a file defining the class Car and Autocar:

import pygame
WHITE = (255, 255, 255)

class Car(pygame.sprite.Sprite):  # Creates a class representing a car, derived from the sprite class

    def __init__(self, color, width, height):
        # Call the parent class (i.e. Sprite) constructor
        super().__init__()
        self.image = pygame.Surface([width,height])
        self.image.fill(WHITE)
        self.image.set_colorkey(WHITE)  # Sets white as transparent for this class

        # alternatively load a proper car picture:
        # self.image = pygame.image.load("car.png").convert_alpha()

        pygame.draw.rect(self.image, color, [0, 0, width, height])
        self.rect = self.image.get_rect()  # Fetches the rectangle with the dimensions of the image

    def move_right(self, pixels):  # Adds to the x value of the car the desired amount of pixels
        self.rect.x += pixels

    def move_left(self, pixels):  # Same as move_right()
        self.rect.x -= pixels

    def move_forward(self, pixels):
        self.rect.y -= pixels

    def move_backward(self, pixels):
        self.rect.y += pixels

class AutoCar(pygame.sprite.Sprite):

    def __init__(self, color, width, height):
        super().__init__()
        self.image = pygame.Surface([width, height])
        self.image.fill(WHITE)
        self.image.set_colorkey(WHITE)

        pygame.draw.rect(self.image, color, [0, 0, width, height])
        self.rect = self.image.get_rect()

    def auto_move_forward(self, pixels):
        self.rect.y += pixels

    def return_to_top(self):
9000
  • 39,899
  • 9
  • 66
  • 104
Dan Hill
  • 43
  • 5
  • How can you detect it leaving the screen? Do it every time you move it, and reposition it accordingly if it leaves the screen. – 9000 Feb 15 '18 at 16:41
  • Yeah I'm just not 100% sure how to reposition it - I've tried changing AutoCar1.rect.y but nothing happens... – Dan Hill Feb 15 '18 at 17:38

1 Answers1

1

Just store the start position as an attribute of the AutoCar, check in the update method if the sprite is below the screen and then set the self.rect.topleft (or one of the other rect attributes) to the self.start_position.

class AutoCar(pygame.sprite.Sprite):

    def __init__(self, color, width, height):
        super().__init__()
        self.image = pygame.Surface([width, height])
        self.image.fill(WHITE)
        self.image.set_colorkey(WHITE)
        pygame.draw.rect(self.image, color, [0, 0, width, height])
        self.rect = self.image.get_rect()
        self.start_position = (200, -50)
        self.rect.topleft = self.start_position

    def auto_move_forward(self, pixels):
        self.rect.y += pixels

    def return_to_top(self):
        self.rect.topleft = self.start_position

    def update(self):
        if self.rect.top > 750:  # Screen height.
            self.rect.topleft = self.start_position
skrx
  • 19,980
  • 5
  • 34
  • 48