游戏可以运行

This commit is contained in:
2026-05-20 20:21:27 +08:00
parent 00908667dd
commit 88b3255ab2
11 changed files with 690 additions and 0 deletions

82
game/tower.py Normal file
View File

@@ -0,0 +1,82 @@
import pygame
import math
from game.config import TOWER_DATA, COLOR_BLACK, COLOR_WHITE
from game.utils import distance
from game.projectile import Projectile
class Tower:
def __init__(self, tower_type, grid_col, grid_row, px, py):
data = TOWER_DATA[tower_type]
self.type = tower_type
self.col = grid_col
self.row = grid_row
self.x = px
self.y = py
self.damage = data["damage"]
self.range = data["range"]
self.fire_rate = data["fire_rate"]
self.price = data["price"]
self.color = data["color"]
self.name = data["name"]
self.splash = data.get("splash", 0)
self.slow_factor = data.get("slow_factor", 0)
self.slow_duration = data.get("slow_duration", 0)
self.cooldown = 0
self.target = None
def find_target(self, enemies):
self.target = None
best = None
best_progress = -1
for e in enemies:
if not e.alive:
continue
d = distance(self.x, self.y, e.x, e.y)
if d <= self.range:
progress = e.waypoint_index + (1 - distance(e.x, e.y, *self._wp(e.waypoint_index)) / 100)
if progress > best_progress:
best_progress = progress
best = e
self.target = best
def _wp(self, idx):
from game.config import PATH_WAYPOINTS
if idx < len(PATH_WAYPOINTS):
return PATH_WAYPOINTS[idx]
return PATH_WAYPOINTS[-1]
def update(self, dt, enemies, projectiles):
if self.cooldown > 0:
self.cooldown -= dt
self.find_target(enemies)
if self.target and self.cooldown <= 0:
self.cooldown = self.fire_rate
proj_type = {"arrow": "arrow", "cannon": "cannon", "slow": "slow"}[self.type]
projectiles.append(Projectile(
self.x, self.y, self.target, self.damage,
proj_type=proj_type, splash=self.splash,
slow_factor=self.slow_factor, slow_duration=self.slow_duration,
))
def draw(self, surface):
ix, iy = int(self.x), int(self.y)
if self.type == "arrow":
pygame.draw.rect(surface, self.color, (ix - 12, iy - 12, 24, 24))
pygame.draw.rect(surface, COLOR_BLACK, (ix - 12, iy - 12, 24, 24), 2)
elif self.type == "cannon":
pygame.draw.circle(surface, self.color, (ix, iy), 14)
pygame.draw.circle(surface, COLOR_BLACK, (ix, iy), 14, 2)
pygame.draw.circle(surface, (180, 100, 30), (ix, iy), 8)
elif self.type == "slow":
points = [(ix, iy - 14), (ix + 14, iy), (ix, iy + 14), (ix - 14, iy)]
pygame.draw.polygon(surface, self.color, points)
pygame.draw.polygon(surface, COLOR_BLACK, points, 2)
if self.target and self.target.alive:
pygame.draw.line(surface, (*self.color, ), (ix, iy), (int(self.target.x), int(self.target.y)), 1)
def draw_range(self, surface):
pygame.draw.circle(surface, COLOR_WHITE, (int(self.x), int(self.y)), self.range, 1)