world.py 4.21 KiB
"""This module contains the World class."""
import pygame as pg
from turret import Turret
from enemy import Zombie
import sound
class World:
"""Class for the world object."""
def __init__(self):
"""Initializes the world object."""
# Constants
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
self.window_resolution = (1920, 1080)
self.waypoints = (
( 175, 0),
( 180, 425),
( 830, 440),
( 830, 1040),
( 175, 1040),
( 175, 690),
(1680, 690),
(1685, 220)
)
# Pygame initialization
pg.init()
self.window = pg.display.set_mode(self.window_resolution, pg.FULLSCREEN | pg.SCALED)
self.window.fill(BLACK)
self.texture_path = 'assets/images/test_map.png'
self.texture = pg.image.load(self.texture_path).convert_alpha()
# Game state variables
self.current_round = 0
self.round_active = False
self.request_to_start_round = False
self.round_start_time = 0
self.round_spawn_times = []
# Game entities
self.enemies = []
self.turrets = []
self.active_tower = 0
#Groups
self.turret_group = []
# Player stats
self.money = 1000
self.player_health = 100
def generate_enemy_spawn_times(self, round_index: int) -> list[tuple[any, int]]:
"""
Returns a list of tuples containing enemy object and time of spawn.
Parameters:
round_index:
The index determines which enemies are spawned.
Returns:
enemies:
Tuple of enemy object and time of spawn.
"""
enemies = []
if round_index <= 10:
for i in range(round_index * 5):
enemies.append((Zombie(100 + 10 * 1.05 ** round_index), 8 * i / (round_index + 3)))
return enemies
def turret_spawn(self, mouse_pos):
temp_turret = Turret(self.texture , mouse_pos)
if self.active_tower == 0 or self.money < temp_turret.cost:
return None
collision = False
if mouse_pos[0] < 1920 and mouse_pos[1] < 1080:
collision = any(temp_turret.rect.colliderect(sprite.rect) for sprite in self.turret_group)
if not collision:
self.turret_group.append(temp_turret)
sound.turret_placement.play()
self.money -= temp_turret.cost
def turret_attacks(self, dt: float):
for turret in self.turret_group:
# Find the nearest enemy for the turret
target = turret.find_nearest_enemy(self.enemies)
if target is not None:
# Rotate the turret to face the targets
turret.face_at_the_current_target(target)
turret.time_since_last_attack += dt
# Attack the target if the cooldown has passed
if turret.time_since_last_attack >= turret.attack_cooldown:
target.hp -= turret.attack_damage
sound.bullet_sound.play()
# Check if the target is dead
if target.hp <= 0:
self.enemies.remove(target)
self.money += target.reward_on_death
sound.play_zombie_groan()
sound.coin_sound.play()
# Attack timer
turret.time_since_last_attack = 0
def draw(self):
"""Draws the world elements to the passed surface."""
self.window.blit(self.texture, (0, 0))
for enemy in self.enemies:
enemy.draw(self.window, self.waypoints)
for turret in self.turret_group:
turret.draw(self.window)
def draw_debug(self):
"""
Draws debug information about the world.
Draws lines between the waypoints.
"""
for i in range(len(self.waypoints) - 1):
pg.draw.line(self.window, (0, 255, 0),
self.waypoints[i], self.waypoints[i + 1], 5)
for point in self.waypoints:
pg.draw.circle(self.window, (255, 0, 0), point, 10)