This tutorial is the fourth tutorial in a series of five Pygame tutorials:
- Tutorial 1 – Getting Started with Pygame
- Tutorial 2 – Creating Sprites using Pygame
- Tutorial 3 – How to control your sprites
- Tutorial 4 – Adding More Sprites
- Tutorial 5 – Pygame – How-To’s
For our car racing game we will add a few more cars.
Each car is an object that will be instantiated from the Car Class.
Looking at the code from our previous tutorial we are adding a few properties and methods to our Car class. This is to allow for the coming cars to have different sizes (width and height), colors and different speed. See the changes on the car.py file.
Then, in our main program, we are going to create four extra cars and we will add these to a list called “all_comming_cars”. Each car will be given a different color, a speed and a different starting position (x & y coordinates). This is what the code on the main.py file does on lines 34 to 62.
The four cars will be moving down (starting at the top of the screen). When they reach the bottom of the screen they will be given a new color, speed and starting position towards the top of the screen. This is what the code on the main.py file does on lines 89 to 94.
The overall speed of the game will be stored in a variable called speed initialised on line 15 of the main.py file. New event handlers will detect when the user presses the UP or DOWN keys on the keyboard. These will increment or decrement the speed variable by 0.05. See lines 82 to 85 of the main.py file.
Here is the code for our latest Car class and for our main program:
import pygame
WHITE = (255, 255, 255)
class Car(pygame.sprite.Sprite):
#This class represents a car. It derives from the "Sprite" class in Pygame.
def __init__(self, color, width, height, speed):
# Call the parent class (Sprite) constructor
super().__init__()
# Pass in the color of the car, and its x and y position, width and height.
# Set the background color and set it to be transparent
self.image = pygame.Surface([width, height])
self.image.fill(WHITE)
self.image.set_colorkey(WHITE)
#Initialise attributes of the car.
self.width=width
self.height=height
self.color = color
self.speed = speed
# Draw the car (a rectangle!)
pygame.draw.rect(self.image, self.color, [0, 0, self.width, self.height])
# Instead we could load a proper picture of a car...
# self.image = pygame.image.load("car.png").convert_alpha()
# Fetch the rectangle object that has the dimensions of the image.
self.rect = self.image.get_rect()
def moveRight(self, pixels):
self.rect.x += pixels
def moveLeft(self, pixels):
self.rect.x -= pixels
def moveForward(self, speed):
self.rect.y += self.speed * speed / 20
def moveBackward(self, speed):
self.rect.y -= self.speed * speed / 20
def changeSpeed(self, speed):
self.speed = speed
def repaint(self, color):
self.color = color
pygame.draw.rect(self.image, self.color, [0, 0, self.width, self.height])
import pygame, random
#Let's import the Car Class
from car import Car
pygame.init()
GREEN = (20, 255, 140)
GREY = (210, 210 ,210)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
PURPLE = (255, 0, 255)
YELLOW = (255, 255, 0)
CYAN = (0, 255, 255)
BLUE = (100, 100, 255)
speed = 1
colorList = (RED, GREEN, PURPLE, YELLOW, CYAN, BLUE)
SCREENWIDTH=800
SCREENHEIGHT=600
size = (SCREENWIDTH, SCREENHEIGHT)
screen = pygame.display.set_mode(size)
pygame.display.set_caption("Car Racing")
#This will be a list that will contain all the sprites we intend to use in our game.
all_sprites_list = pygame.sprite.Group()
playerCar = Car(RED, 60, 80, 70)
playerCar.rect.x = 160
playerCar.rect.y = SCREENHEIGHT - 100
car1 = Car(PURPLE, 60, 80, random.randint(50,100))
car1.rect.x = 60
car1.rect.y = -100
car2 = Car(YELLOW, 60, 80, random.randint(50,100))
car2.rect.x = 160
car2.rect.y = -600
car3 = Car(CYAN, 60, 80, random.randint(50,100))
car3.rect.x = 260
car3.rect.y = -300
car4 = Car(BLUE, 60, 80, random.randint(50,100))
car4.rect.x = 360
car4.rect.y = -900
# Add the car to the list of objects
all_sprites_list.add(playerCar)
all_sprites_list.add(car1)
all_sprites_list.add(car2)
all_sprites_list.add(car3)
all_sprites_list.add(car4)
all_coming_cars = pygame.sprite.Group()
all_coming_cars.add(car1)
all_coming_cars.add(car2)
all_coming_cars.add(car3)
all_coming_cars.add(car4)
#Allowing the user to close the window...
carryOn = True
clock=pygame.time.Clock()
while carryOn:
for event in pygame.event.get():
if event.type==pygame.QUIT:
carryOn=False
elif event.type==pygame.KEYDOWN:
if event.key==pygame.K_x:
playerCar.moveRight(10)
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
playerCar.moveLeft(5)
if keys[pygame.K_RIGHT]:
playerCar.moveRight(5)
if keys[pygame.K_UP]:
speed += 0.05
if keys[pygame.K_DOWN]:
speed -= 0.05
#Game Logic
for car in all_coming_cars:
car.moveForward(speed)
if car.rect.y > SCREENHEIGHT:
car.changeSpeed(random.randint(50,100))
car.repaint(random.choice(colorList))
car.rect.y = -200
all_sprites_list.update()
#Drawing on Screen
screen.fill(GREEN)
#Draw The Road
pygame.draw.rect(screen, GREY, [40,0, 400,SCREENHEIGHT])
#Draw Line painting on the road
pygame.draw.line(screen, WHITE, [140,0],[140,SCREENHEIGHT],5)
#Draw Line painting on the road
pygame.draw.line(screen, WHITE, [240,0],[240,SCREENHEIGHT],5)
#Draw Line painting on the road
pygame.draw.line(screen, WHITE, [340,0],[340,SCREENHEIGHT],5)
#Now let's draw all the sprites in one go. (For now we only have 1 sprite!)
all_sprites_list.draw(screen)
#Refresh Screen
pygame.display.flip()
#Number of frames per secong e.g. 60
clock.tick(60)
pygame.quit()
Detecting Collision
The next addition to our game is used on most 2D arcarde games: The aim is to check when a sprite (e.g. playerCar) is colliding with other sprites (in this case cars stored in the all_coming_cars list).
You would need to add these lines of code in the “game logic” section of your main program loop. For instance you could add these lines on line 95 of the code provided above (main.py).
#Check if there is a car collision
car_collision_list = pygame.sprite.spritecollide(playerCar,all_coming_cars,False)
for car in car_collision_list:
print("Car crash!")
#End Of Game
carryOn=False






