Build a fast, fun python game using Pygame. This mini project is perfect for python projects for beginners: you’ll learn graphics, input handling, collision detection, scoring, and a restart screen.
What You’ll Build
- 3-lane road with a player car that moves left/right
- Obstacle “waves” that always leave one safe lane
- Score + Highscore display
- Game Over screen with “Press SPACE to Restart”
Requirements
- Install Python (3.9+ recommended).
- Install Pygame:
pip install pygame
🌐 Car Game Animation
import pygame
import random
import sys
pygame.init()
# Screen settings
WIDTH, HEIGHT = 400, 600
ROAD_WIDTH = 240
ROAD_X = (WIDTH - ROAD_WIDTH) // 2
LANE_COUNT = 3
LANE_WIDTH = ROAD_WIDTH // LANE_COUNT
# Car settings
CAR_WIDTH, CAR_HEIGHT = 30, 50
car_y = HEIGHT - CAR_HEIGHT - 40
# Obstacle settings
OBSTACLE_WIDTH, OBSTACLE_HEIGHT = 25, 40
obstacle_speed = 4
OBSTACLE_GAP = 150 # 🔥 vertical gap between waves
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Racing Game with Highscore")
clock = pygame.time.Clock()
font = pygame.font.SysFont("Arial", 28)
# Colors
WHITE = (255, 255, 255)
GRAY = (64, 64, 64)
GREEN = (34, 177, 76)
RED = (200, 50, 50)
YELLOW = (241, 196, 15)
BLUE = (41, 128, 185)
# Highscore
highscore = 0
def lane_x(lane):
return ROAD_X + lane * LANE_WIDTH + (LANE_WIDTH - CAR_WIDTH) // 2
def draw_road():
screen.fill(GREEN)
pygame.draw.rect(screen, GRAY, (ROAD_X, 0, ROAD_WIDTH, HEIGHT))
for i in range(1, LANE_COUNT):
pygame.draw.line(screen, WHITE, (ROAD_X + i * LANE_WIDTH, 0), (ROAD_X + i * LANE_WIDTH, HEIGHT), 4)
def draw_car(lane, y):
x = lane_x(lane)
pygame.draw.rect(screen, BLUE, (x, y, CAR_WIDTH, CAR_HEIGHT))
pygame.draw.rect(screen, YELLOW, (x + 6, y + 18, 18, 15))
def draw_obstacle(lane, y):
x = lane_x(lane)
pygame.draw.rect(screen, RED, (x, y, OBSTACLE_WIDTH, OBSTACLE_HEIGHT))
def collision(rect1, rect2):
return pygame.Rect(rect1).colliderect(pygame.Rect(rect2))
def game_loop():
global highscore
car_lane = 1
obstacles = []
score = 0
running = True
# 🔥 Cooldown control
last_spawn_y = 0
while running:
draw_road()
# Event handling
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT and car_lane > 0:
car_lane -= 1
if event.key == pygame.K_RIGHT and car_lane < LANE_COUNT - 1:
car_lane += 1
# Spawn new obstacle wave (ONLY when last one moved down enough)
if not obstacles or (obstacles[-1][1] > OBSTACLE_GAP):
lanes = [0, 1, 2]
free_lane = random.choice(lanes) # always keep 1 lane free
for lane in lanes:
if lane != free_lane:
obstacles.append([lane, -OBSTACLE_HEIGHT])
# Move obstacles
obstacles[:] = [[lane, y + obstacle_speed] for lane, y in obstacles if y < HEIGHT]
for lane, y in obstacles:
draw_obstacle(lane, y)
# Draw car
draw_car(car_lane, car_y)
# Collision check
car_rect = (lane_x(car_lane), car_y, CAR_WIDTH, CAR_HEIGHT)
for lane, y in obstacles:
obs_rect = (lane_x(lane), y, OBSTACLE_WIDTH, OBSTACLE_HEIGHT)
if collision(car_rect, obs_rect):
running = False
# Score
score += 1
score_text = font.render(f"Score: {score // 10}", True, WHITE)
screen.blit(score_text, (10, 10))
# Highscore
highscore_text = font.render(f"Highscore: {highscore}", True, WHITE)
screen.blit(highscore_text, (10, 40))
pygame.display.update()
clock.tick(60)
# Update Highscore
if score // 10 > highscore:
highscore = score // 10
game_over_screen(score // 10)
def game_over_screen(final_score):
while True:
screen.fill(RED)
over_text = font.render(f"Game Over!", True, WHITE)
score_text = font.render(f"Your Score: {final_score}", True, WHITE)
highscore_text = font.render(f"Highscore: {highscore}", True, WHITE)
restart_text = font.render("Press SPACE to Restart", True, WHITE)
quit_text = font.render("Press Q to Quit", True, WHITE)
screen.blit(over_text, (WIDTH // 2 - over_text.get_width() // 2, HEIGHT // 2 - 80))
screen.blit(score_text, (WIDTH // 2 - score_text.get_width() // 2, HEIGHT // 2 - 40))
screen.blit(highscore_text, (WIDTH // 2 - highscore_text.get_width() // 2, HEIGHT // 2))
screen.blit(restart_text, (WIDTH // 2 - restart_text.get_width() // 2, HEIGHT // 2 + 40))
screen.blit(quit_text, (WIDTH // 2 - quit_text.get_width() // 2, HEIGHT // 2 + 80))
pygame.display.update()
# Event handling
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE: # Restart
return
if event.key == pygame.K_q: # Quit
pygame.quit()
sys.exit()
def main():
while True:
game_loop()
if __name__ == "__main__":
main()
🔍 Output Preview
How to Run
- Save the file as
racing_game.py
. - Open Terminal/PowerShell in the folder and run:
python racing_game.py
- Controls: Left Arrow / Right Arrow to change lanes.
Troubleshooting
- No module named pygame: run
pip install pygame
. - Window not responding: don’t block the main loop; keep
pygame.event.get()
calls. - Too hard? Increase
OBSTACLE_GAP
(e.g., 180–220) or decreaseobstacle_speed
.
Why This Is a Great Mini Project
This python mini project teaches real game dev concepts (render loop, events, collisions) and is a strong addition to your portfolio of python projects with source code.
Related Searches (for readers)
games using python, python game code, python coding for games, games in python, python projects for beginners, mini project in python, simple projects in python, python project ideas
FAQ
Q: Can I add images or sounds?
Yes. Load sprites with pygame.image.load()
and sounds with pygame.mixer.Sound()
.
Q: How to increase difficulty?
Gradually increase obstacle_speed
and reduce OBSTACLE_GAP
as score rises.