import pygame
import sys
import random
import math
from typing import List, Tuple, Optional, Dict
from enum import Enum

# 初始化
pygame.init()
pygame.mixer.init()

# 游戏设置
SCREEN_WIDTH = 900
SCREEN_HEIGHT = 600
FPS = 60
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("植物大战僵尸")
clock = pygame.time.Clock()

# 颜色定义
COLORS = {
    'background': (20, 40, 0),
    'lawn': (100, 180, 60),
    'lawn_dark': (80, 150, 40),
    'sun_yellow': (255, 220, 0),
    'plant_green': (60, 180, 80),
    'zombie_gray': (120, 140, 100),
    'ui_bg': (40, 40, 60),
    'text_white': (240, 240, 240),
    'text_yellow': (255, 220, 0),
    'text_green': (60, 220, 100),
    'text_red': (255, 60, 60),
    'health_green': (60, 220, 100),
    'health_yellow': (255, 200, 60),
    'health_red': (255, 60, 60),
    'bullet_pea': (100, 220, 100),
    'bullet_ice': (150, 220, 255),
}

# 加载字体
try:
    font_names = ["msyh.ttc", "simhei.ttf", "simsun.ttc", None]
    FONT_SMALL = FONT_MEDIUM = None
    
    for font_name in font_names:
        try:
            if font_name is None:
                FONT_SMALL = pygame.font.Font(None, 20)
                FONT_MEDIUM = pygame.font.Font(None, 32)
                break
            
            FONT_SMALL = pygame.font.Font(font_name, 20)
            FONT_MEDIUM = pygame.font.Font(font_name, 32)
            
            test_surface = FONT_SMALL.render("测试", True, (255, 255, 255))
            if test_surface.get_width() > 0:
                break
        except:
            continue
except:
    FONT_SMALL = pygame.font.Font(None, 20)
    FONT_MEDIUM = pygame.font.Font(None, 32)

# 网格设置
GRID_WIDTH = 9
GRID_HEIGHT = 5
CELL_SIZE = 80
LAWN_X = 150
LAWN_Y = 100

# 植物类型枚举
class PlantType(Enum):
    SUNFLOWER = "sunflower"
    PEASHOOTER = "peashooter"
    WALLNUT = "wallnut"
    SNOWPEA = "snowpea"
    POTATOMINE = "potatomine"

# 僵尸类型枚举
class ZombieType(Enum):
    NORMAL = "normal"
    CONEHEAD = "conehead"
    BUCKETHEAD = "buckethead"

class Vector2:
    """简化版向量类"""
    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y
    
    def to_tuple(self):
        return (int(self.x), int(self.y))
    
    def distance_to(self, other):
        dx = self.x - other.x
        dy = self.y - other.y
        return math.sqrt(dx*dx + dy*dy)

class Sun:
    """阳光"""
    def __init__(self, x, y, value=25):
        self.x = x
        self.y = y
        self.value = value
        self.size = 20
        self.lifetime = 10.0
        self.float_offset = random.random() * math.pi * 2
    
    def update(self, dt):
        """更新"""
        self.lifetime -= dt
        if self.lifetime <= 0:
            return False
        
        # 浮动效果
        self.float_offset += dt * 2
        self.y += math.sin(self.float_offset) * 0.3
        
        return True
    
    def draw(self, surface):
        """绘制"""
        # 主体
        pygame.draw.circle(surface, COLORS['sun_yellow'], (int(self.x), int(self.y)), self.size)
        
        # 光芒
        for i in range(8):
            angle = math.radians(i * 45)
            start_x = self.x + math.cos(angle) * self.size
            start_y = self.y + math.sin(angle) * self.size
            end_x = self.x + math.cos(angle) * (self.size + 8)
            end_y = self.y + math.sin(angle) * (self.size + 8)
            pygame.draw.line(surface, COLORS['sun_yellow'], 
                           (start_x, start_y), (end_x, end_y), 3)
        
        # 中心
        pygame.draw.circle(surface, (255, 255, 200), (int(self.x), int(self.y)), self.size//2)
        
        # 数值
        value_text = FONT_SMALL.render(str(self.value), True, (0, 0, 0))
        surface.blit(value_text, (int(self.x - value_text.get_width()/2), 
                                int(self.y - value_text.get_height()/2)))

class Plant:
    """植物"""
    def __init__(self, plant_type, grid_x, grid_y):
        self.type = plant_type
        self.grid_x = grid_x
        self.grid_y = grid_y
        self.x = LAWN_X + grid_x * CELL_SIZE + CELL_SIZE//2
        self.y = LAWN_Y + grid_y * CELL_SIZE + CELL_SIZE//2
        self.health = 0
        self.max_health = 0
        self.attack_timer = 0
        self.sun_timer = 0
        self.ready_to_remove = False
        
        # 初始化属性
        self.init_attributes()
    
    def init_attributes(self):
        """初始化属性"""
        if self.type == PlantType.SUNFLOWER:
            self.health = 80
            self.max_health = 80
        elif self.type == PlantType.PEASHOOTER:
            self.health = 100
            self.max_health = 100
        elif self.type == PlantType.WALLNUT:
            self.health = 400
            self.max_health = 400
        elif self.type == PlantType.SNOWPEA:
            self.health = 100
            self.max_health = 100
        elif self.type == PlantType.POTATOMINE:
            self.health = 50
            self.max_health = 50
    
    def update(self, dt):
        """更新"""
        if self.type == PlantType.SUNFLOWER:
            self.sun_timer += dt
            if self.sun_timer >= 10.0:  # 每10秒产生阳光
                self.sun_timer = 0
                return "sun"
        
        elif self.type in [PlantType.PEASHOOTER, PlantType.SNOWPEA]:
            self.attack_timer += dt
            if self.attack_timer >= 2.0:  # 每2秒攻击
                self.attack_timer = 0
                slow = 0.5 if self.type == PlantType.SNOWPEA else 0
                return ("attack", 20, slow)
        
        return None
    
    def take_damage(self, damage):
        """受到伤害"""
        self.health -= damage
        if self.health <= 0:
            self.ready_to_remove = True
            if self.type == PlantType.POTATOMINE:
                return ("explode", 150)  # 爆炸伤害
        return None
    
    def draw(self, surface):
        """绘制"""
        # 根据类型绘制
        if self.type == PlantType.SUNFLOWER:
            # 茎
            pygame.draw.rect(surface, (0, 150, 0), 
                           (self.x - 5, self.y, 10, 20))
            # 花盘
            pygame.draw.circle(surface, COLORS['sun_yellow'], (self.x, self.y), 20)
            # 花瓣
            for i in range(8):
                angle = math.radians(i * 45)
                px = self.x + math.cos(angle) * 25
                py = self.y + math.sin(angle) * 25
                pygame.draw.circle(surface, (255, 240, 100), (int(px), int(py)), 8)
        
        elif self.type == PlantType.PEASHOOTER:
            # 身体
            pygame.draw.ellipse(surface, COLORS['plant_green'], 
                              (self.x - 20, self.y - 15, 40, 30))
            # 头部
            pygame.draw.circle(surface, (80, 200, 100), (self.x + 15, self.y), 12)
            # 嘴巴
            pygame.draw.ellipse(surface, (100, 50, 0), 
                              (self.x + 10, self.y - 4, 8, 8))
        
        elif self.type == PlantType.WALLNUT:
            # 坚果
            pygame.draw.circle(surface, (150, 100, 50), (self.x, self.y), 25)
            # 裂纹
            if self.health < self.max_health * 0.5:
                pygame.draw.line(surface, (100, 60, 30), 
                               (self.x - 15, self.y - 10), 
                               (self.x + 15, self.y + 10), 3)
        
        elif self.type == PlantType.SNOWPEA:
            # 身体
            pygame.draw.ellipse(surface, (100, 180, 220), 
                              (self.x - 20, self.y - 15, 40, 30))
            # 头部
            pygame.draw.circle(surface, (120, 200, 240), (self.x + 15, self.y), 12)
            # 冰霜
            for i in range(4):
                angle = math.radians(i * 90)
                px = self.x + math.cos(angle) * 20
                py = self.y + math.sin(angle) * 20
                pygame.draw.circle(surface, (200, 230, 255, 100), (int(px), int(py)), 4)
        
        elif self.type == PlantType.POTATOMINE:
            # 土豆
            pygame.draw.ellipse(surface, (150, 100, 50), 
                              (self.x - 15, self.y - 10, 30, 20))
            # 引信
            pygame.draw.line(surface, (200, 150, 100), 
                           (self.x, self.y - 10), (self.x, self.y - 20), 3)
            # 危险标志
            pygame.draw.circle(surface, COLORS['text_red'], (self.x, self.y - 20), 4)
        
        # 生命条
        if self.health < self.max_health:
            bar_width = 40
            bar_height = 6
            bar_x = self.x - bar_width//2
            bar_y = self.y - 35
            
            # 背景
            pygame.draw.rect(surface, (50, 0, 0), (bar_x, bar_y, bar_width, bar_height))
            
            # 生命
            health_width = int(bar_width * (self.health / self.max_health))
            if self.health > self.max_health * 0.5:
                health_color = COLORS['health_green']
            elif self.health > self.max_health * 0.2:
                health_color = COLORS['health_yellow']
            else:
                health_color = COLORS['health_red']
            
            pygame.draw.rect(surface, health_color, (bar_x, bar_y, health_width, bar_height))

class Bullet:
    """子弹"""
    def __init__(self, x, y, damage=20, slow=0):
        self.x = x
        self.y = y
        self.damage = damage
        self.slow = slow
        self.speed = 5
        self.active = True
        self.is_ice = slow > 0
    
    def update(self):
        """更新"""
        self.x += self.speed
        if self.x > SCREEN_WIDTH + 50:
            self.active = False
        return self.active
    
    def draw(self, surface):
        """绘制"""
        if self.is_ice:
            color = COLORS['bullet_ice']
            border_color = (200, 230, 255)
        else:
            color = COLORS['bullet_pea']
            border_color = (150, 240, 150)
        
        pygame.draw.circle(surface, color, (int(self.x), int(self.y)), 6)
        pygame.draw.circle(surface, border_color, (int(self.x), int(self.y)), 6, 2)
        
        # 尾部
        pygame.draw.circle(surface, (255, 255, 255, 100), (int(self.x-4), int(self.y)), 3)

class Zombie:
    """僵尸"""
    def __init__(self, zombie_type, row, level=1):
        self.type = zombie_type
        self.row = row
        self.level = level
        
        self.x = SCREEN_WIDTH + 50
        self.y = LAWN_Y + row * CELL_SIZE + CELL_SIZE//2
        self.health = 0
        self.max_health = 0
        self.speed = 1.0
        self.damage = 10
        self.attack_timer = 0
        self.active = True
        self.eating = False
        self.slow_multiplier = 1.0
        self.slow_timer = 0
        
        # 动画
        self.walk_phase = 0
        
        # 初始化属性
        self.init_attributes()
    
    def init_attributes(self):
        """初始化属性"""
        if self.type == ZombieType.NORMAL:
            self.health = 100
            self.max_health = 100
            self.speed = 1.0
        elif self.type == ZombieType.CONEHEAD:
            self.health = 200
            self.max_health = 200
            self.speed = 0.9
        elif self.type == ZombieType.BUCKETHEAD:
            self.health = 300
            self.max_health = 300
            self.speed = 0.8
    
    def update(self, dt, plants):
        """更新"""
        if not self.active:
            return None
        
        # 减速效果
        if self.slow_timer > 0:
            self.slow_timer -= dt
            if self.slow_timer <= 0:
                self.slow_multiplier = 1.0
        
        # 检查是否在吃植物
        plant_to_eat = None
        for plant in plants:
            if plant.ready_to_remove:
                continue
            
            plant_row = int((plant.y - LAWN_Y) / CELL_SIZE)
            if plant_row == self.row and self.x - plant.x < 40 and self.x > plant.x:
                plant_to_eat = plant
                break
        
        if plant_to_eat:
            self.eating = True
            self.attack_timer += dt
            if self.attack_timer >= 2.0:  # 每2秒攻击一次
                self.attack_timer = 0
                return ("attack", plant_to_eat, self.damage)
        else:
            self.eating = False
            # 移动
            current_speed = self.speed * self.slow_multiplier
            self.x -= current_speed * dt * 60
            
            # 检查是否到达房子
            if self.x < LAWN_X - 50:
                return "reach_house"
        
        # 更新动画
        self.walk_phase += dt * 5
        
        return None
    
    def take_damage(self, damage, slow=0):
        """受到伤害"""
        self.health -= damage
        
        # 减速效果
        if slow > 0:
            self.slow_multiplier = 1.0 - slow
            self.slow_timer = 2.0
        
        if self.health <= 0:
            self.active = False
            return "dead"
        
        return None
    
    def draw(self, surface):
        """绘制"""
        # 身体
        body_height = 40
        body_width = 30
        body_color = COLORS['zombie_gray']
        
        if self.type == ZombieType.CONEHEAD:
            body_color = (180, 180, 180)
        elif self.type == ZombieType.BUCKETHEAD:
            body_color = (100, 100, 100)
        
        # 身体
        pygame.draw.rect(surface, body_color, 
                        (int(self.x - body_width//2), int(self.y - body_height//2), 
                         body_width, body_height))
        
        # 头部
        head_radius = 12
        pygame.draw.circle(surface, (150, 180, 150), (int(self.x), int(self.y - 15)), head_radius)
        
        # 脸
        # 眼睛
        eye_size = 4
        pygame.draw.circle(surface, (255, 255, 255), (int(self.x - 4), int(self.y - 16)), eye_size)
        pygame.draw.circle(surface, (255, 255, 255), (int(self.x + 4), int(self.y - 16)), eye_size)
        pygame.draw.circle(surface, (0, 0, 0), (int(self.x - 3), int(self.y - 16)), eye_size//2)
        pygame.draw.circle(surface, (0, 0, 0), (int(self.x + 5), int(self.y - 16)), eye_size//2)
        
        # 嘴巴
        if self.eating:
            # 吃的时候
            mouth_width = 10
            pygame.draw.ellipse(surface, (200, 100, 100), 
                              (int(self.x - mouth_width//2), int(self.y - 10), 
                               mouth_width, 6))
        else:
            # 平时
            pygame.draw.line(surface, (200, 100, 100), 
                           (int(self.x - 5), int(self.y - 8)), 
                           (int(self.x + 5), int(self.y - 8)), 2)
        
        # 手臂
        arm_length = 20
        arm_angle = math.radians(30 + 10 * math.sin(self.walk_phase))
        arm_x = self.x + math.cos(arm_angle) * arm_length
        arm_y = self.y + math.sin(arm_angle) * arm_length
        pygame.draw.line(surface, body_color, (int(self.x), int(self.y)), 
                        (int(arm_x), int(arm_y)), 8)
        
        # 腿
        leg_length = 25
        leg_angle = math.radians(-20 + 20 * math.sin(self.walk_phase + math.pi))
        leg_x = self.x + math.cos(leg_angle) * leg_length
        leg_y = self.y + math.sin(leg_angle) * leg_length
        pygame.draw.line(surface, (100, 120, 100), (int(self.x), int(self.y + 10)), 
                        (int(leg_x), int(leg_y)), 8)
        
        # 特殊装备
        if self.type == ZombieType.CONEHEAD:
            # 路障
            pygame.draw.circle(surface, (200, 200, 200), (int(self.x), int(self.y - 25)), 15)
        elif self.type == ZombieType.BUCKETHEAD:
            # 铁桶
            pygame.draw.rect(surface, (150, 150, 150), 
                           (int(self.x - 20), int(self.y - 30), 40, 20))
        
        # 生命条
        if self.health < self.max_health:
            bar_width = 40
            bar_height = 6
            bar_x = self.x - bar_width//2
            bar_y = self.y - 35
            
            # 背景
            pygame.draw.rect(surface, (50, 0, 0), (int(bar_x), int(bar_y), bar_width, bar_height))
            
            # 生命
            health_width = int(bar_width * (self.health / self.max_health))
            if self.health > self.max_health * 0.5:
                health_color = COLORS['health_green']
            elif self.health > self.max_health * 0.2:
                health_color = COLORS['health_yellow']
            else:
                health_color = COLORS['health_red']
            
            pygame.draw.rect(surface, health_color, (int(bar_x), int(bar_y), health_width, bar_height))
        
        # 减速效果
        if self.slow_multiplier < 1.0:
            pygame.draw.circle(surface, (100, 150, 255, 100), 
                             (int(self.x), int(self.y)), 25, 3)

class Game:
    """游戏主类"""
    def __init__(self):
        self.sun = 50
        self.wave = 1
        self.score = 0
        self.zombies_killed = 0
        
        # 游戏状态
        self.game_over = False
        self.paused = False
        self.in_menu = True
        self.won = False
        
        # 游戏对象
        self.plants = []
        self.zombies = []
        self.bullets = []
        self.suns = []
        
        # 植物卡片
        self.plant_cards = [
            {'type': PlantType.SUNFLOWER, 'cost': 50, 'name': '向日葵', 'cooldown': 0},
            {'type': PlantType.PEASHOOTER, 'cost': 100, 'name': '豌豆射手', 'cooldown': 0},
            {'type': PlantType.WALLNUT, 'cost': 50, 'name': '坚果墙', 'cooldown': 0},
            {'type': PlantType.SNOWPEA, 'cost': 175, 'name': '寒冰射手', 'cooldown': 0},
            {'type': PlantType.POTATOMINE, 'cost': 25, 'name': '土豆地雷', 'cooldown': 0},
        ]
        
        # 选中的植物
        self.selected_plant = None
        self.selected_plant_cost = 0
        
        # 计时器
        self.sun_timer = 0
        self.sun_spawn_delay = 5.0
        self.zombie_timer = 0
        self.zombie_spawn_delay = 5.0
        self.wave_timer = 0
        self.wave_duration = 30.0
        
        # 生成初始阳光
        for _ in range(3):
            self.spawn_sun()
    
    def spawn_sun(self, x=None, y=None):
        """生成阳光"""
        if x is None or y is None:
            x = random.randint(200, SCREEN_WIDTH - 200)
            y = random.randint(100, SCREEN_HEIGHT - 200)
        
        sun = Sun(x, y)
        self.suns.append(sun)
    
    def spawn_zombie(self):
        """生成僵尸"""
        if len(self.zombies) >= 15:  # 僵尸数量上限
            return
        
        # 随机行
        row = random.randint(0, GRID_HEIGHT - 1)
        
        # 选择僵尸类型
        if random.random() < 0.1 + (self.wave - 1) * 0.05:  # 波次越高，高级僵尸越多
            zombie_type = random.choice([ZombieType.CONEHEAD, ZombieType.BUCKETHEAD])
        else:
            zombie_type = ZombieType.NORMAL
        
        zombie = Zombie(zombie_type, row, self.wave)
        self.zombies.append(zombie)
    
    def place_plant(self, grid_x, grid_y, plant_type, cost):
        """放置植物"""
        if self.sun < cost:
            return False
        
        # 检查位置是否被占用
        for plant in self.plants:
            if plant.grid_x == grid_x and plant.grid_y == grid_y and not plant.ready_to_remove:
                return False
        
        # 创建植物
        plant = Plant(plant_type, grid_x, grid_y)
        self.plants.append(plant)
        
        # 消耗阳光
        self.sun -= cost
        
        return True
    
    def check_sun_collection(self, pos):
        """检查阳光收集"""
        for sun in self.suns[:]:
            distance = math.sqrt((pos[0] - sun.x) ** 2 + (pos[1] - sun.y) ** 2)
            if distance < sun.size + 20:  # 点击范围
                self.sun += sun.value
                self.suns.remove(sun)
                return True
        return False
    
    def update(self, dt):
        """更新游戏"""
        if self.game_over or self.paused or self.in_menu or self.won:
            return
        
        # 更新阳光生成
        self.sun_timer += dt
        if self.sun_timer >= self.sun_spawn_delay:
            self.sun_timer = 0
            self.spawn_sun()
        
        # 更新僵尸生成
        self.zombie_timer += dt
        if self.zombie_timer >= self.zombie_spawn_delay:
            self.zombie_timer = 0
            self.spawn_zombie()
        
        # 更新波次
        self.wave_timer += dt
        if self.wave_timer >= self.wave_duration:
            self.next_wave()
        
        # 更新植物
        for plant in self.plants[:]:
            if plant.ready_to_remove:
                self.plants.remove(plant)
                continue
            
            result = plant.update(dt)
            if result:
                if result == "sun":
                    # 产生阳光
                    self.spawn_sun(plant.x, plant.y - 30)
                elif isinstance(result, tuple) and result[0] == "attack":
                    # 发射子弹
                    _, damage, slow = result
                    bullet = Bullet(plant.x + 20, plant.y, damage, slow)
                    self.bullets.append(bullet)
        
        # 更新僵尸
        for zombie in self.zombies[:]:
            if not zombie.active:
                self.zombies.remove(zombie)
                self.score += 10
                self.zombies_killed += 1
                continue
            
            result = zombie.update(dt, self.plants)
            if result:
                if result == "reach_house":
                    self.game_over = True
                    return
                elif isinstance(result, tuple) and result[0] == "attack":
                    # 攻击植物
                    _, plant, damage = result
                    plant_result = plant.take_damage(damage)
                    if plant_result and plant_result[0] == "explode":
                        # 土豆地雷爆炸
                        _, explosion_damage = plant_result
                        # 伤害周围僵尸
                        for z in self.zombies[:]:
                            distance = math.sqrt((z.x - plant.x) ** 2 + (z.y - plant.y) ** 2)
                            if distance < 100:  # 爆炸范围
                                z.take_damage(explosion_damage)
                        plant.ready_to_remove = True
        
        # 更新子弹
        for bullet in self.bullets[:]:
            if not bullet.update():
                self.bullets.remove(bullet)
                continue
            
            # 检查子弹击中僵尸
            for zombie in self.zombies[:]:
                if not zombie.active:
                    continue
                
                # 检查是否在同一行
                zombie_row = int((zombie.y - LAWN_Y) / CELL_SIZE)
                bullet_row = int((bullet.y - LAWN_Y) / CELL_SIZE)
                
                if zombie_row == bullet_row and abs(zombie.x - bullet.x) < 20:
                    result = zombie.take_damage(bullet.damage, bullet.slow)
                    if result == "dead":
                        self.zombies.remove(zombie)
                        self.score += 10
                        self.zombies_killed += 1
                    
                    bullet.active = False
                    self.bullets.remove(bullet)
                    break
        
        # 更新阳光
        for sun in self.suns[:]:
            if not sun.update(dt):
                self.suns.remove(sun)
        
        # 检查胜利条件
        if self.wave > 5:  # 5波后胜利
            self.won = True
    
    def next_wave(self):
        """下一波"""
        self.wave += 1
        self.wave_timer = 0
        self.wave_duration = min(60.0, 30.0 + self.wave * 3)
        self.zombie_spawn_delay = max(1.0, 5.0 - self.wave * 0.5)
    
    def draw_background(self, surface):
        """绘制背景"""
        # 背景
        surface.fill(COLORS['background'])
        
        # 草坪
        for y in range(GRID_HEIGHT):
            for x in range(GRID_WIDTH):
                rect_x = LAWN_X + x * CELL_SIZE
                rect_y = LAWN_Y + y * CELL_SIZE
                
                # 交替颜色
                if (x + y) % 2 == 0:
                    color = COLORS['lawn']
                else:
                    color = COLORS['lawn_dark']
                
                pygame.draw.rect(surface, color, 
                                (rect_x, rect_y, CELL_SIZE, CELL_SIZE))
                pygame.draw.rect(surface, (60, 100, 40), 
                                (rect_x, rect_y, CELL_SIZE, CELL_SIZE), 1)
        
        # 房子
        house_width = 50
        house_height = GRID_HEIGHT * CELL_SIZE
        house_x = LAWN_X - house_width
        house_y = LAWN_Y
        
        pygame.draw.rect(surface, (150, 100, 50), 
                        (house_x, house_y, house_width, house_height))
        
        # 房子窗户
        for i in range(GRID_HEIGHT):
            window_y = house_y + i * CELL_SIZE + CELL_SIZE//2 - 10
            pygame.draw.rect(surface, (100, 200, 255), 
                            (house_x + 10, window_y, 30, 20))
    
    def draw_ui(self, surface):
        """绘制UI"""
        # 阳光显示
        sun_bg_rect = pygame.Rect(10, 10, 120, 50)
        pygame.draw.rect(surface, COLORS['ui_bg'], sun_bg_rect, border_radius=5)
        pygame.draw.rect(surface, (100, 100, 150), sun_bg_rect, 2, border_radius=5)
        
        sun_text = FONT_MEDIUM.render(f"阳光: {self.sun}", True, COLORS['text_yellow'])
        surface.blit(sun_text, (20, 20))
        
        # 波数显示
        wave_text = FONT_MEDIUM.render(f"波数: {self.wave}", True, COLORS['text_white'])
        surface.blit(wave_text, (20, 70))
        
        # 分数显示
        score_text = FONT_SMALL.render(f"分数: {self.score}", True, COLORS['text_green'])
        surface.blit(score_text, (20, 110))
        
        # 僵尸击杀数
        kill_text = FONT_SMALL.render(f"击杀: {self.zombies_killed}", True, COLORS['text_green'])
        surface.blit(kill_text, (20, 130))
        
        # 波次进度条
        progress_width = 200
        progress_height = 20
        progress_x = SCREEN_WIDTH // 2 - progress_width // 2
        progress_y = 20
        
        # 背景
        pygame.draw.rect(surface, (30, 60, 100), 
                        (progress_x, progress_y, progress_width, progress_height))
        
        # 进度
        progress = min(1.0, self.wave_timer / self.wave_duration)
        progress_fill = int(progress_width * progress)
        pygame.draw.rect(surface, (100, 200, 255), 
                        (progress_x, progress_y, progress_fill, progress_height))
        
        # 进度文字
        time_left = int(self.wave_duration - self.wave_timer)
        progress_text = FONT_SMALL.render(f"下一波: {time_left}秒", True, COLORS['text_white'])
        surface.blit(progress_text, (progress_x + progress_width//2 - progress_text.get_width()//2, 
                                   progress_y + 2))
    
    def draw_plant_cards(self, surface):
        """绘制植物卡片"""
        card_width = 80
        card_height = 100
        card_spacing = 5
        start_x = SCREEN_WIDTH - card_width - 10
        start_y = 10
        
        for i, card in enumerate(self.plant_cards):
            x = start_x
            y = start_y + i * (card_height + card_spacing)
            
            # 卡片背景
            can_afford = self.sun >= card['cost']
            if can_afford and card['cooldown'] <= 0:
                bg_color = COLORS['plant_green']
            else:
                bg_color = (60, 100, 40)
            
            card_rect = pygame.Rect(x, y, card_width, card_height)
            pygame.draw.rect(surface, bg_color, card_rect, border_radius=5)
            pygame.draw.rect(surface, (100, 100, 150), card_rect, 2, border_radius=5)
            
            # 冷却覆盖
            if card['cooldown'] > 0:
                card['cooldown'] -= 0.016  # 大约每帧减少
                cool_height = int(card_height * (card['cooldown'] / 7.5))
                cool_rect = pygame.Rect(x, y, card_width, cool_height)
                pygame.draw.rect(surface, (0, 0, 0, 150), cool_rect)
            
            # 植物图标
            icon_size = 20
            icon_x = x + card_width // 2
            icon_y = y + 30
            
            if card['type'] == PlantType.SUNFLOWER:
                pygame.draw.circle(surface, COLORS['sun_yellow'], (icon_x, icon_y), icon_size)
            elif card['type'] == PlantType.PEASHOOTER:
                pygame.draw.circle(surface, COLORS['plant_green'], (icon_x, icon_y), icon_size)
            elif card['type'] == PlantType.WALLNUT:
                pygame.draw.circle(surface, (150, 100, 50), (icon_x, icon_y), icon_size)
            elif card['type'] == PlantType.SNOWPEA:
                pygame.draw.circle(surface, (100, 180, 220), (icon_x, icon_y), icon_size)
            elif card['type'] == PlantType.POTATOMINE:
                pygame.draw.rect(surface, (150, 100, 50), 
                                (icon_x - 15, icon_y - 10, 30, 20))
            
            # 植物名称
            name_text = FONT_SMALL.render(card['name'], True, COLORS['text_white'])
            surface.blit(name_text, (x + card_width//2 - name_text.get_width()//2, y + 5))
            
            # 植物花费
            cost_text = FONT_SMALL.render(str(card['cost']), True, COLORS['text_yellow'])
            surface.blit(cost_text, (x + card_width//2 - cost_text.get_width()//2, y + 80))
    
    def draw_menu(self, surface):
        """绘制菜单"""
        # 半透明背景
        overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 200))
        surface.blit(overlay, (0, 0))
        
        # 游戏标题
        title_text = FONT_MEDIUM.render("植物大战僵尸", True, COLORS['text_green'])
        surface.blit(title_text, (SCREEN_WIDTH//2 - title_text.get_width()//2, 100))
        
        # 开始游戏按钮
        start_rect = pygame.Rect(SCREEN_WIDTH//2 - 100, 200, 200, 50)
        pygame.draw.rect(surface, COLORS['plant_green'], start_rect, border_radius=8)
        pygame.draw.rect(surface, (100, 100, 150), start_rect, 2, border_radius=8)
        
        start_text = FONT_MEDIUM.render("开始游戏", True, COLORS['text_white'])
        surface.blit(start_text, (SCREEN_WIDTH//2 - start_text.get_width()//2, 215))
        
        # 游戏说明
        instructions = [
            "游戏目标: 保护房子不被僵尸吃掉！",
            "操作说明:",
            "1. 点击植物卡片选择植物",
            "2. 在草坪上点击放置植物",
            "3. 收集阳光购买植物",
            "4. 生存5波攻击获得胜利",
            "",
            "植物介绍:",
            "向日葵: 产生阳光",
            "豌豆射手: 发射豌豆",
            "坚果墙: 高生命值",
            "寒冰射手: 减速僵尸",
            "土豆地雷: 爆炸伤害"
        ]
        
        y_offset = 280
        for line in instructions:
            text = FONT_SMALL.render(line, True, COLORS['text_white'])
            surface.blit(text, (SCREEN_WIDTH//2 - text.get_width()//2, y_offset))
            y_offset += 20
        
        return start_rect
    
    def draw_game_over(self, surface):
        """绘制游戏结束画面"""
        overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 200))
        surface.blit(overlay, (0, 0))
        
        if self.won:
            title_text = FONT_MEDIUM.render("恭喜胜利！", True, COLORS['text_yellow'])
        else:
            title_text = FONT_MEDIUM.render("游戏结束", True, COLORS['text_red'])
        
        surface.blit(title_text, (SCREEN_WIDTH//2 - title_text.get_width()//2, 100))
        
        # 统计信息
        stats = [
            f"最终分数: {self.score}",
            f"击杀僵尸: {self.zombies_killed}",
            f"最高波数: {self.wave}",
            f"剩余阳光: {self.sun}"
        ]
        
        y_offset = 150
        for stat in stats:
            stat_text = FONT_MEDIUM.render(stat, True, COLORS['text_green'])
            surface.blit(stat_text, (SCREEN_WIDTH//2 - stat_text.get_width()//2, y_offset))
            y_offset += 40
        
        # 重新开始按钮
        restart_rect = pygame.Rect(SCREEN_WIDTH//2 - 100, 350, 200, 50)
        pygame.draw.rect(surface, COLORS['plant_green'], restart_rect, border_radius=8)
        pygame.draw.rect(surface, (100, 100, 150), restart_rect, 2, border_radius=8)
        
        restart_text = FONT_MEDIUM.render("重新开始", True, COLORS['text_white'])
        surface.blit(restart_text, (SCREEN_WIDTH//2 - restart_text.get_width()//2, 365))
        
        return restart_rect
    
    def draw(self, surface):
        """绘制游戏"""
        # 绘制背景
        self.draw_background(surface)
        
        # 绘制阳光
        for sun in self.suns:
            sun.draw(surface)
        
        # 绘制植物
        for plant in self.plants:
            plant.draw(surface)
        
        # 绘制僵尸
        for zombie in self.zombies:
            zombie.draw(surface)
        
        # 绘制子弹
        for bullet in self.bullets:
            bullet.draw(surface)
        
        # 绘制UI
        self.draw_ui(surface)
        
        # 绘制植物卡片
        self.draw_plant_cards(surface)
        
        # 绘制网格（调试用）
        if False:  # 设置为True显示网格
            for y in range(GRID_HEIGHT + 1):
                pygame.draw.line(surface, (255, 255, 255, 100), 
                               (LAWN_X, LAWN_Y + y * CELL_SIZE),
                               (LAWN_X + GRID_WIDTH * CELL_SIZE, LAWN_Y + y * CELL_SIZE))
            for x in range(GRID_WIDTH + 1):
                pygame.draw.line(surface, (255, 255, 255, 100), 
                               (LAWN_X + x * CELL_SIZE, LAWN_Y),
                               (LAWN_X + x * CELL_SIZE, LAWN_Y + GRID_HEIGHT * CELL_SIZE))
        
        # 显示选中的植物预览
        if self.selected_plant:
            mouse_pos = pygame.mouse.get_pos()
            grid_x = int((mouse_pos[0] - LAWN_X) / CELL_SIZE)
            grid_y = int((mouse_pos[1] - LAWN_Y) / CELL_SIZE)
            
            if 0 <= grid_x < GRID_WIDTH and 0 <= grid_y < GRID_HEIGHT:
                # 绘制预览
                preview_rect = pygame.Rect(
                    LAWN_X + grid_x * CELL_SIZE,
                    LAWN_Y + grid_y * CELL_SIZE,
                    CELL_SIZE, CELL_SIZE
                )
                pygame.draw.rect(surface, (255, 255, 255, 100), preview_rect, 2)
        
        # 绘制菜单或游戏结束画面
        if self.in_menu:
            self.menu_button = self.draw_menu(surface)
        elif self.game_over or self.won:
            self.restart_button = self.draw_game_over(surface)
        
        # 显示暂停
        if self.paused:
            pause_text = FONT_MEDIUM.render("游戏暂停", True, COLORS['text_red'])
            surface.blit(pause_text, (SCREEN_WIDTH//2 - pause_text.get_width()//2, 
                                     SCREEN_HEIGHT//2 - 50))

def main():
    """主函数"""
    game = Game()
    running = True
    
    while running:
        dt = clock.tick(FPS) / 1000.0
        
        # 获取鼠标位置
        mouse_pos = pygame.mouse.get_pos()
        
        # 处理事件
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            
            elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                if game.in_menu:
                    # 菜单界面
                    if hasattr(game, 'menu_button') and game.menu_button.collidepoint(mouse_pos):
                        game.in_menu = False
                
                elif game.game_over or game.won:
                    # 游戏结束界面
                    if hasattr(game, 'restart_button') and game.restart_button.collidepoint(mouse_pos):
                        game = Game()  # 重新开始游戏
                
                else:
                    # 游戏界面
                    # 检查是否点击植物卡片
                    for i, card in enumerate(game.plant_cards):
                        card_x = SCREEN_WIDTH - 80 - 10
                        card_y = 10 + i * (100 + 5)
                        card_rect = pygame.Rect(card_x, card_y, 80, 100)
                        
                        if card_rect.collidepoint(mouse_pos) and game.sun >= card['cost'] and card['cooldown'] <= 0:
                            game.selected_plant = card['type']
                            game.selected_plant_cost = card['cost']
                            break
                    
                    # 检查是否收集阳光
                    if not game.check_sun_collection(mouse_pos):
                        # 检查是否放置植物
                        if game.selected_plant:
                            # 计算网格位置
                            grid_x = int((mouse_pos[0] - LAWN_X) / CELL_SIZE)
                            grid_y = int((mouse_pos[1] - LAWN_Y) / CELL_SIZE)
                            
                            if 0 <= grid_x < GRID_WIDTH and 0 <= grid_y < GRID_HEIGHT:
                                # 放置植物
                                if game.place_plant(grid_x, grid_y, game.selected_plant, game.selected_plant_cost):
                                    # 找到对应的卡片并设置冷却
                                    for card in game.plant_cards:
                                        if card['type'] == game.selected_plant:
                                            card['cooldown'] = 7.5
                                            break
                                
                                game.selected_plant = None
            
            elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 3:  # 右键
                # 取消选中的植物
                game.selected_plant = None
            
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    if not game.in_menu and not game.game_over and not game.won:
                        game.selected_plant = None
                    else:
                        running = False
                elif event.key == pygame.K_p:
                    game.paused = not game.paused
                elif event.key == pygame.K_SPACE:
                    # 生成测试阳光
                    test_sun_x = random.randint(200, SCREEN_WIDTH - 200)
                    test_sun_y = random.randint(100, SCREEN_HEIGHT - 200)
                    game.spawn_sun(test_sun_x, test_sun_y)
        
        # 更新游戏
        if not game.paused and not game.in_menu and not game.game_over and not game.won:
            game.update(dt)
        
        # 绘制游戏
        game.draw(screen)
        
        # 显示FPS
        fps = int(clock.get_fps())
        fps_text = FONT_SMALL.render(f"FPS: {fps}", True, COLORS['text_white'])
        screen.blit(fps_text, (10, SCREEN_HEIGHT - 30))
        
        pygame.display.flip()
    
    pygame.quit()
    sys.exit()

if __name__ == "__main__":
    main()