Begin by importing the necesary libraries and defining the global configuration constants. These settings establish the screen dimensions, asset directories, and initial state variables for the game session.
import pygame
import sys
# Configuration constants
ASSET_DIR = "resources/"
WIDTH = 800
HEIGHT = 600
TARGET_FPS = 60
# Game state variables
game_active = True
level_index = 1
current_score = 0
sun_currency = 250
Next, define the primary game engine class. This component manages window initialization, the main event loop, and screen updates. The execution loop persists until the termination flag is set to false.
class GameEngine:
def __init__(self):
self.display = None
self.clock = None
def initialize_screen(self):
pygame.init()
self.display = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Garden Defense")
self.clock = pygame.time.Clock()
def run_loop(self):
self.initialize_screen()
while game_active:
self.display.fill((255, 255, 255))
self.process_events()
self.render_interface()
pygame.display.flip()
self.clock.tick(TARGET_FPS)
def process_events(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
Interface elements such as score, currency, and control instructions require dynamic rendering. Implement a helper method to generate text surfaces and draw them onto the main display at specific coordinates.
def generate_text(self, message, size, color):
font = pygame.font.SysFont('consolas', size)
return font.render(message, True, color)
def render_interface(self):
# Display currency
sun_text = self.generate_text(f"Sun: {sun_currency}", 24, (0, 0, 0))
self.display.blit(sun_text, (10, 10))
# Display level and score
status = self.generate_text(
f"Level: {level_index} | Score: {current_score}",
24, (0, 0, 0)
)
self.display.blit(status, (10, 40))
# Instructions
hint = self.generate_text(
"Left Click: Sunflower | Right Click: Peashooter",
18, (255, 0, 0)
)
self.display.blit(hint, (WIDTH - 400, HEIGHT - 30))
Finally, construct the grid system where plants are positioned. The map class handles tile coordinates and background imagery rendering.
class GridMap:
def __init__(self):
self.tile_size = 100
self.row_count = 5
self.col_count = 9
self.grid = []
def load_textures(self):
# Placeholder for loading tile images
self.light_tile = pygame.Surface((self.tile_size, self.tile_size))
self.light_tile.fill((100, 200, 100))
self.dark_tile = pygame.Surface((self.tile_size, self.tile_size))
self.dark_tile.fill((50, 150, 50))
def render(self, surface):
for r in range(self.row_count):
for c in range(self.col_count):
x = c * self.tile_size
y = r * self.tile_size
if (r + c) % 2 == 0:
surface.blit(self.light_tile, (x, y))
else:
surface.blit(self.dark_tile, (x, y))