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

# 初始化pygame
pygame.init()

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

# 颜色定义
GRASS_COLOR = (100, 180, 100)
GRID_COLOR = (80, 150, 80)
SKY_COLOR = (135, 206, 235)
SUN_COLOR = (255, 255, 0)
PLANT_GREEN = (50, 200, 50)
ZOMBIE_GREEN = (100, 200, 100)
PEA_COLOR = (50, 200, 50)
BULLET_COLOR = (255, 100, 50)
TEXT_COLOR = (255, 255, 255)
TEXT_SHADOW = (0, 0, 0)
UI_BG_COLOR = (40, 100, 40)
CARD_COLOR = (200, 150, 50)
CARD_HOVER = (220, 170, 70)
BUTTON_COLOR = (60, 140, 60)
BUTTON_HOVER = (80, 160, 80)
RED = (255, 50, 50)
YELLOW = (255, 255, 0)
PURPLE = (180, 0, 255)
ORANGE = (255, 165, 0)

# 创建字体
try:
    font_small = pygame.font.Font(None, 24)
    font_medium = pygame.font.Font(None, 36)
    font_large = pygame.font.Font(None, 48)
    font_huge = pygame.font.Font(None, 72)
    font_score = pygame.font.Font(None, 64)
except:
    font_small = pygame.font.SysFont(None, 24)
    font_medium = pygame.font.SysFont(None, 36)
    font_large = pygame.font.SysFont(None, 48)
    font_huge = pygame.font.SysFont(None, 72)
    font_score = pygame.font.SysFont(None, 64)

# 游戏配置
class Config:
    GRID_SIZE = 80
    GRID_COLS = 9
    GRID_ROWS = 5
    GAME_WIDTH = GRID_COLS * GRID_SIZE
    GAME_HEIGHT = GRID_ROWS * GRID_SIZE
    UI_WIDTH = SCREEN_WIDTH - GAME_WIDTH
    
    # 植物配置
    SUN_COST = 50
    PEASHOOTER_COST = 100
    SUNFLOWER_COST = 50
    WALLNUT_COST = 50
    CHERRY_BOMB_COST = 150
    
    # 游戏参数
    INITIAL_SUN = 200
    SPAWN_INTERVAL = 3000  # 毫秒
    WAVE_INTERVAL = 30000  # 毫秒
    SUN_DROP_INTERVAL = 5000  # 毫秒
    SUN_VALUE = 25
    
    # 僵尸参数
    ZOMBIE_HEALTH = 100
    ZOMBIE_SPEED = 0.5
    CONE_ZOMBIE_HEALTH = 200
    BUCKET_ZOMBIE_HEALTH = 300

# 植物类型枚举
class PlantType(Enum):
    SUNFLOWER = "sunflower"
    PEASHOOTER = "peashooter"
    WALLNUT = "wallnut"
    CHERRY_BOMB = "cherrybomb"

# 僵尸类型枚举
class ZombieType(Enum):
    NORMAL = "normal"
    CONE = "cone"
    BUCKET = "bucket"

# 太阳类
class Sun:
    def __init__(self, x, y, value=Config.SUN_VALUE):
        self.x = x
        self.y = y
        self.value = value
        self.size = 30
        self.fall_speed = 1
        self.fall_distance = 0
        self.max_fall = 100
        self.collected = False
        self.collect_anim = 0
        self.pulse = 0
        
    def update(self):
        if not self.collected:
            if self.fall_distance < self.max_fall:
                self.y += self.fall_speed
                self.fall_distance += self.fall_speed
            self.pulse += 0.1
        else:
            self.collect_anim += 1
            self.size = max(0, self.size - 1)
            
    def draw(self, surface):
        if self.collect_anim > 20:
            return
            
        pulse_size = math.sin(self.pulse) * 3
        
        # 太阳发光效果
        for i in range(3, 0, -1):
            glow_size = self.size + i * 5 + pulse_size
            pygame.draw.circle(surface, (*SUN_COLOR, 100 - i*20), 
                             (int(self.x), int(self.y)), int(glow_size))
        
        # 太阳主体
        pygame.draw.circle(surface, SUN_COLOR, 
                         (int(self.x), int(self.y)), self.size + pulse_size)
        
        # 太阳光芒
        for i in range(8):
            angle = math.radians(i * 45)
            length = 20 + pulse_size
            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 + length)
            end_y = self.y + math.sin(angle) * (self.size + length)
            pygame.draw.line(surface, SUN_COLOR, 
                           (start_x, start_y), (end_x, end_y), 4)
            
    def check_collect(self, mouse_pos):
        if self.collected:
            return False
            
        distance = math.sqrt((self.x - mouse_pos[0])**2 + (self.y - mouse_pos[1])**2)
        if distance < self.size + 10:
            self.collected = True
            return True
        return False

# 植物基类
class Plant:
    def __init__(self, x, y, plant_type: PlantType, health=100):
        self.x = x
        self.y = y
        self.type = plant_type
        self.health = health
        self.max_health = health
        self.width = Config.GRID_SIZE
        self.height = Config.GRID_SIZE
        self.shoot_timer = 0
        self.sun_produce_timer = 0
        self.animation = 0
        self.is_exploding = False
        self.explode_timer = 0
        
        if plant_type == PlantType.SUNFLOWER:
            self.shoot_interval = 10000  # 10秒生产一个太阳
            self.sun_produce_value = 25
        elif plant_type == PlantType.PEASHOOTER:
            self.shoot_interval = 1500  # 1.5秒发射一颗豌豆
        elif plant_type == PlantType.CHERRY_BOMB:
            self.explode_radius = 150
            self.explode_damage = 1000
            
    def update(self):
        self.animation += 0.1
        self.shoot_timer += 1
        
        if self.type == PlantType.SUNFLOWER:
            self.sun_produce_timer += 1
            
    def can_shoot(self):
        return self.shoot_timer >= self.shoot_interval / (1000/60)  # 转换为帧数
        
    def can_produce_sun(self):
        return self.sun_produce_timer >= self.shoot_interval / (1000/60)
        
    def reset_shoot_timer(self):
        self.shoot_timer = 0
        
    def reset_sun_timer(self):
        self.sun_produce_timer = 0
        
    def take_damage(self, damage):
        self.health -= damage
        return self.health <= 0
        
    def get_rect(self):
        return pygame.Rect(self.x, self.y, self.width, self.height)
        
    def draw(self, surface):
        if self.type == PlantType.SUNFLOWER:
            self.draw_sunflower(surface)
        elif self.type == PlantType.PEASHOOTER:
            self.draw_peashooter(surface)
        elif self.type == PlantType.WALLNUT:
            self.draw_wallnut(surface)
        elif self.type == PlantType.CHERRY_BOMB:
            self.draw_cherrybomb(surface)
            
        # 绘制生命条
        if self.health < self.max_health:
            health_width = 40
            health_height = 5
            health_ratio = self.health / self.max_health
            
            # 生命条背景
            pygame.draw.rect(surface, (100, 0, 0), 
                           (self.x + (self.width - health_width)//2, 
                            self.y - 10, health_width, health_height))
            
            # 当前生命
            if health_ratio > 0:
                current_width = int(health_width * health_ratio)
                health_color = (0, 255, 0) if health_ratio > 0.5 else (255, 255, 0)
                pygame.draw.rect(surface, health_color, 
                               (self.x + (self.width - health_width)//2, 
                                self.y - 10, current_width, health_height))
                                
    def draw_sunflower(self, surface):
        # 向日葵花盘
        center_x = self.x + self.width//2
        center_y = self.y + self.height//2
        flower_size = 30 + math.sin(self.animation) * 3
        
        # 花瓣
        for i in range(8):
            angle = math.radians(i * 45)
            petal_length = 20
            petal_x = center_x + math.cos(angle) * (flower_size + petal_length)
            petal_y = center_y + math.sin(angle) * (flower_size + petal_length)
            pygame.draw.ellipse(surface, YELLOW, 
                              (petal_x - 10, petal_y - 5, 20, 10))
        
        # 花盘
        pygame.draw.circle(surface, ORANGE, (center_x, center_y), flower_size)
        
        # 花盘纹理
        for i in range(12):
            angle = math.radians(i * 30)
            line_x = center_x + math.cos(angle) * flower_size
            line_y = center_y + math.sin(angle) * flower_size
            pygame.draw.line(surface, (200, 100, 0), 
                           (center_x, center_y), (line_x, line_y), 2)
        
        # 茎
        stem_width = 8
        pygame.draw.rect(surface, PLANT_GREEN, 
                        (center_x - stem_width//2, center_y + flower_size, 
                         stem_width, self.height - center_y + self.y - flower_size))
        
        # 叶子
        leaf_size = 15
        pygame.draw.ellipse(surface, PLANT_GREEN, 
                          (center_x - 20, center_y + 10, leaf_size*2, leaf_size))
        pygame.draw.ellipse(surface, PLANT_GREEN, 
                          (center_x, center_y + 10, leaf_size*2, leaf_size))
        
    def draw_peashooter(self, surface):
        # 豌豆射手主体
        center_x = self.x + self.width//2
        center_y = self.y + self.height//2
        
        # 头部
        head_radius = 25
        pygame.draw.circle(surface, PLANT_GREEN, (center_x, center_y), head_radius)
        
        # 嘴巴
        mouth_width = 20
        mouth_height = 10
        pygame.draw.ellipse(surface, (50, 150, 50), 
                          (center_x - mouth_width//2, center_y - 5, 
                           mouth_width, mouth_height))
        
        # 茎
        stem_width = 15
        stem_height = 30
        pygame.draw.rect(surface, PLANT_GREEN, 
                        (center_x - stem_width//2, center_y + head_radius, 
                         stem_width, stem_height))
        
        # 叶子
        leaf_size = 20
        pygame.draw.ellipse(surface, (80, 200, 80), 
                          (center_x - 25, center_y + 20, leaf_size, leaf_size//2))
        pygame.draw.ellipse(surface, (80, 200, 80), 
                          (center_x + 5, center_y + 20, leaf_size, leaf_size//2))
        
    def draw_wallnut(self, surface):
        # 坚果墙
        center_x = self.x + self.width//2
        center_y = self.y + self.height//2
        nut_radius = 30
        
        # 坚果主体
        pygame.draw.circle(surface, (150, 100, 50), (center_x, center_y), nut_radius)
        
        # 裂纹效果（根据生命值）
        if self.health < self.max_health * 0.7:
            # 绘制裂纹
            pygame.draw.line(surface, (100, 70, 30), 
                           (center_x - 10, center_y - 5), 
                           (center_x + 10, center_y + 5), 2)
        if self.health < self.max_health * 0.4:
            pygame.draw.line(surface, (100, 70, 30), 
                           (center_x - 5, center_y - 10), 
                           (center_x + 5, center_y + 10), 2)
        
        # 高光
        pygame.draw.circle(surface, (180, 130, 80), 
                         (center_x - 10, center_y - 10), 8)
        
    def draw_cherrybomb(self, surface):
        # 樱桃炸弹
        center_x = self.x + self.width//2
        center_y = self.y + self.height//2
        
        # 炸弹主体
        bomb_radius = 25
        pygame.draw.circle(surface, RED, (center_x, center_y), bomb_radius)
        
        # 引信
        fuse_length = 20
        pygame.draw.line(surface, (100, 100, 100), 
                       (center_x, center_y - bomb_radius), 
                       (center_x, center_y - bomb_radius - fuse_length), 3)
        
        # 火花
        if self.is_exploding:
            spark_size = 5 + math.sin(self.explode_timer * 0.5) * 3
            pygame.draw.circle(surface, YELLOW, 
                             (center_x, center_y - bomb_radius - fuse_length), 
                             spark_size)
        
        # 高光
        pygame.draw.circle(surface, (255, 150, 150), 
                         (center_x - 8, center_y - 8), 8)

# 豌豆类
class Pea:
    def __init__(self, x, y, damage=20):
        self.x = x
        self.y = y
        self.damage = damage
        self.speed = 5
        self.radius = 6
        self.trail = []
        
    def update(self):
        self.x += self.speed
        
        # 更新轨迹
        self.trail.append((self.x, self.y))
        if len(self.trail) > 5:
            self.trail.pop(0)
            
    def is_off_screen(self):
        return self.x > Config.GAME_WIDTH + 50
        
    def get_rect(self):
        return pygame.Rect(self.x - self.radius, self.y - self.radius, 
                          self.radius * 2, self.radius * 2)
        
    def draw(self, surface):
        # 绘制轨迹
        for i, (trail_x, trail_y) in enumerate(self.trail):
            alpha = int(255 * (i / len(self.trail)))
            size = int(self.radius * (i / len(self.trail)))
            pygame.draw.circle(surface, (*PEA_COLOR, alpha), 
                             (int(trail_x), int(trail_y)), size)
        
        # 绘制豌豆
        pygame.draw.circle(surface, PEA_COLOR, (int(self.x), int(self.y)), self.radius)
        
        # 高光
        pygame.draw.circle(surface, (150, 255, 150), 
                         (int(self.x - 2), int(self.y - 2)), 2)

# 僵尸类
class Zombie:
    def __init__(self, row, zombie_type: ZombieType = ZombieType.NORMAL):
        self.row = row
        self.type = zombie_type
        self.x = Config.GAME_WIDTH + 50
        self.y = row * Config.GRID_SIZE + Config.GRID_SIZE//2
        self.speed = Config.ZOMBIE_SPEED
        self.animation = 0
        
        if zombie_type == ZombieType.NORMAL:
            self.health = Config.ZOMBIE_HEALTH
            self.damage = 10
            self.color = ZOMBIE_GREEN
        elif zombie_type == ZombieType.CONE:
            self.health = Config.CONE_ZOMBIE_HEALTH
            self.damage = 15
            self.color = (150, 200, 150)
        elif zombie_type == ZombieType.BUCKET:
            self.health = Config.BUCKET_ZOMBIE_HEALTH
            self.damage = 20
            self.color = (100, 100, 150)
            
        self.max_health = self.health
        self.width = 40
        self.height = 60
        self.eating = False
        self.eat_timer = 0
        self.arm_swing = 0
        
    def update(self):
        self.animation += 0.1
        if not self.eating:
            self.x -= self.speed
            self.arm_swing = math.sin(self.animation * 2) * 5
        else:
            self.eat_timer += 1
            self.arm_swing = math.sin(self.eat_timer * 0.2) * 10
            
    def take_damage(self, damage):
        self.health -= damage
        return self.health <= 0
        
    def is_off_screen(self):
        return self.x < -100
        
    def get_rect(self):
        return pygame.Rect(self.x - self.width//2, self.y - self.height//2, 
                          self.width, self.height)
        
    def draw(self, surface):
        center_x = int(self.x)
        center_y = int(self.y)
        
        # 绘制僵尸
        if self.type == ZombieType.NORMAL:
            self.draw_normal_zombie(surface, center_x, center_y)
        elif self.type == ZombieType.CONE:
            self.draw_cone_zombie(surface, center_x, center_y)
        elif self.type == ZombieType.BUCKET:
            self.draw_bucket_zombie(surface, center_x, center_y)
            
        # 绘制生命条
        if self.health < self.max_health:
            health_width = 40
            health_height = 5
            health_ratio = self.health / self.max_health
            
            # 生命条背景
            pygame.draw.rect(surface, (100, 0, 0), 
                           (center_x - health_width//2, center_y - 40, 
                            health_width, health_height))
            
            # 当前生命
            if health_ratio > 0:
                current_width = int(health_width * health_ratio)
                health_color = (0, 255, 0) if health_ratio > 0.5 else (255, 255, 0)
                pygame.draw.rect(surface, health_color, 
                               (center_x - health_width//2, center_y - 40, 
                                current_width, health_height))
                                
    def draw_normal_zombie(self, surface, x, y):
        # 身体
        pygame.draw.rect(surface, self.color, 
                        (x - 15, y - 20, 30, 40))
        
        # 头部
        pygame.draw.circle(surface, self.color, (x, y - 25), 15)
        
        # 眼睛
        pygame.draw.circle(surface, (255, 255, 255), (x - 5, y - 28), 4)
        pygame.draw.circle(surface, (255, 255, 255), (x + 5, y - 28), 4)
        pygame.draw.circle(surface, (0, 0, 0), (x - 5, y - 28), 2)
        pygame.draw.circle(surface, (0, 0, 0), (x + 5, y - 28), 2)
        
        # 嘴巴
        if self.eating:
            pygame.draw.ellipse(surface, (100, 0, 0), 
                              (x - 8, y - 20, 16, 8))
        else:
            pygame.draw.arc(surface, (100, 0, 0), 
                          (x - 8, y - 20, 16, 8), 0, math.pi, 2)
        
        # 手臂
        arm_y = y - 5
        pygame.draw.line(surface, self.color, 
                        (x - 20, arm_y), 
                        (x - 30 + self.arm_swing, arm_y - 10), 6)
        pygame.draw.line(surface, self.color, 
                        (x + 20, arm_y), 
                        (x + 30 - self.arm_swing, arm_y - 10), 6)
        
        # 腿
        leg_y = y + 20
        pygame.draw.line(surface, (50, 100, 50), 
                        (x - 10, leg_y), 
                        (x - 10, leg_y + 20), 6)
        pygame.draw.line(surface, (50, 100, 50), 
                        (x + 10, leg_y), 
                        (x + 10, leg_y + 20), 6)
        
    def draw_cone_zombie(self, surface, x, y):
        # 绘制普通僵尸
        self.draw_normal_zombie(surface, x, y)
        
        # 路障
        cone_points = [
            (x, y - 40),  # 顶部
            (x - 25, y - 15),  # 左下
            (x + 25, y - 15)   # 右下
        ]
        pygame.draw.polygon(surface, (150, 150, 150), cone_points)
        pygame.draw.polygon(surface, (100, 100, 100), cone_points, 2)
        
    def draw_bucket_zombie(self, surface, x, y):
        # 绘制普通僵尸
        self.draw_normal_zombie(surface, x, y)
        
        # 铁桶
        pygame.draw.rect(surface, (100, 100, 150), 
                        (x - 20, y - 40, 40, 20))
        pygame.draw.rect(surface, (80, 80, 120), 
                        (x - 20, y - 40, 40, 20), 2)
        
        # 桶底
        pygame.draw.rect(surface, (120, 120, 180), 
                        (x - 18, y - 20, 36, 5))

# 卡片类
class Card:
    def __init__(self, x, y, plant_type: PlantType, cost, cooldown=5000):
        self.x = x
        self.y = y
        self.type = plant_type
        self.cost = cost
        self.width = 100
        self.height = 120
        self.cooldown = cooldown
        self.current_cooldown = 0
        self.selected = False
        self.hover = False
        
    def update(self):
        if self.current_cooldown > 0:
            self.current_cooldown -= 1
            
    def can_use(self, sun_amount):
        return self.current_cooldown <= 0 and sun_amount >= self.cost
        
    def use(self):
        self.current_cooldown = self.cooldown / (1000/60)  # 转换为帧数
        
    def check_hover(self, pos):
        self.hover = (self.x <= pos[0] <= self.x + self.width and 
                     self.y <= pos[1] <= self.y + self.height)
        return self.hover
        
    def draw(self, surface):
        # 卡片背景
        color = CARD_HOVER if self.hover or self.selected else CARD_COLOR
        if self.current_cooldown > 0:
            color = (150, 150, 150)
            
        pygame.draw.rect(surface, color, 
                        (self.x, self.y, self.width, self.height), border_radius=10)
        pygame.draw.rect(surface, (100, 100, 100), 
                        (self.x, self.y, self.width, self.height), 3, border_radius=10)
        
        # 冷却效果
        if self.current_cooldown > 0:
            cooldown_ratio = self.current_cooldown / (self.cooldown / (1000/60))
            cooldown_height = int(self.height * cooldown_ratio)
            pygame.draw.rect(surface, (0, 0, 0, 150), 
                           (self.x, self.y, self.width, cooldown_height), border_radius=10)
        
        # 植物图标
        icon_size = 40
        icon_x = self.x + self.width//2
        icon_y = self.y + 30
        
        if self.type == PlantType.SUNFLOWER:
            pygame.draw.circle(surface, YELLOW, (icon_x, icon_y), icon_size//2)
        elif self.type == PlantType.PEASHOOTER:
            pygame.draw.circle(surface, PLANT_GREEN, (icon_x, icon_y), icon_size//2)
        elif self.type == PlantType.WALLNUT:
            pygame.draw.circle(surface, (150, 100, 50), (icon_x, icon_y), icon_size//2)
        elif self.type == PlantType.CHERRY_BOMB:
            pygame.draw.circle(surface, RED, (icon_x, icon_y), icon_size//2)
        
        # 花费
        cost_text = font_small.render(str(self.cost), True, YELLOW)
        surface.blit(cost_text, (self.x + 10, self.y + 90))
        
        # 太阳图标
        pygame.draw.circle(surface, YELLOW, (self.x + 30, self.y + 100), 8)

# 游戏主类
class PlantsVsZombies:
    def __init__(self):
        self.state = "menu"
        self.plants = []
        self.zombies = []
        self.peas = []
        self.suns = []
        self.cards = []
        self.sun_amount = Config.INITIAL_SUN
        self.wave = 1
        self.score = 0
        self.wave_timer = 0
        self.sun_drop_timer = 0
        self.spawn_timer = 0
        self.selected_card = None
        self.game_over = False
        self.win = False
        self.init_cards()
        self.init_menu()
        
    def init_cards(self):
        card_x = Config.GAME_WIDTH + 20
        card_y = 100
        
        self.cards = [
            Card(card_x, card_y, PlantType.SUNFLOWER, Config.SUNFLOWER_COST, 7500),
            Card(card_x, card_y + 140, PlantType.PEASHOOTER, Config.PEASHOOTER_COST, 5000),
            Card(card_x, card_y + 280, PlantType.WALLNUT, Config.WALLNUT_COST, 30000),
            Card(card_x, card_y + 420, PlantType.CHERRY_BOMB, Config.CHERRY_BOMB_COST, 30000)
        ]
        
    def init_menu(self):
        self.buttons = []
        
    def start_game(self):
        self.state = "playing"
        self.plants = []
        self.zombies = []
        self.peas = []
        self.suns = []
        self.sun_amount = Config.INITIAL_SUN
        self.wave = 1
        self.score = 0
        self.wave_timer = 0
        self.sun_drop_timer = 0
        self.spawn_timer = 0
        self.selected_card = None
        self.game_over = False
        self.win = False
        
    def get_grid_position(self, x, y):
        """将屏幕坐标转换为网格位置"""
        if x < 0 or x >= Config.GAME_WIDTH or y < 0 or y >= Config.GAME_HEIGHT:
            return None
            
        col = x // Config.GRID_SIZE
        row = y // Config.GRID_SIZE
        
        if col >= Config.GRID_COLS or row >= Config.GRID_ROWS:
            return None
            
        return (col, row)
        
    def is_grid_occupied(self, col, row):
        """检查网格是否已被占用"""
        grid_rect = pygame.Rect(col * Config.GRID_SIZE, row * Config.GRID_SIZE, 
                               Config.GRID_SIZE, Config.GRID_SIZE)
        
        for plant in self.plants:
            if plant.get_rect().colliderect(grid_rect):
                return True
        return False
        
    def spawn_zombie(self):
        """生成僵尸"""
        if len(self.zombies) < 10 + self.wave * 2:  # 限制僵尸数量
            row = random.randint(0, Config.GRID_ROWS - 1)
            
            # 根据波数选择僵尸类型
            rand_val = random.random()
            zombie_type = ZombieType.NORMAL
            
            if self.wave >= 3 and rand_val < 0.3:
                zombie_type = ZombieType.CONE
            if self.wave >= 5 and rand_val < 0.1:
                zombie_type = ZombieType.BUCKET
                
            self.zombies.append(Zombie(row, zombie_type))
            
    def drop_sun(self, x=None, y=None):
        """生成太阳"""
        if x is None:
            x = random.randint(50, Config.GAME_WIDTH - 50)
        if y is None:
            y = random.randint(50, Config.GAME_HEIGHT - 50)
            
        self.suns.append(Sun(x, y))
        
    def update(self):
        if self.state == "playing" and not self.game_over and not self.win:
            # 更新计时器
            self.wave_timer += 1
            self.sun_drop_timer += 1
            self.spawn_timer += 1
            
            # 每波生成僵尸
            if self.spawn_timer >= Config.SPAWN_INTERVAL / (1000/60):
                for _ in range(min(3, 1 + self.wave // 2)):
                    self.spawn_zombie()
                self.spawn_timer = 0
                
            # 下一波
            if self.wave_timer >= Config.WAVE_INTERVAL / (1000/60):
                self.wave += 1
                self.wave_timer = 0
                
            # 自动生成太阳
            if self.sun_drop_timer >= Config.SUN_DROP_INTERVAL / (1000/60):
                self.drop_sun()
                self.sun_drop_timer = 0
                
            # 更新植物
            for plant in self.plants[:]:
                plant.update()
                
                # 向日葵生产太阳
                if plant.type == PlantType.PEASHOOTER and plant.can_shoot():
                    # 豌豆射手发射豌豆
                    pea = Pea(plant.x + Config.GRID_SIZE//2, 
                            plant.y + Config.GRID_SIZE//2)
                    self.peas.append(pea)
                    plant.reset_shoot_timer()
                    
                elif plant.type == PlantType.SUNFLOWER and plant.can_produce_sun():
                    # 向日葵生产太阳
                    self.drop_sun(plant.x + Config.GRID_SIZE//2, 
                                plant.y + Config.GRID_SIZE//2)
                    plant.reset_sun_timer()
                    
                elif plant.type == PlantType.CHERRY_BOMB and plant.is_exploding:
                    plant.explode_timer += 1
                    if plant.explode_timer > 30:  # 爆炸持续时间
                        # 爆炸伤害
                        for zombie in self.zombies[:]:
                            distance = math.sqrt((plant.x - zombie.x)**2 + (plant.y - zombie.y)**2)
                            if distance < plant.explode_radius:
                                if zombie.take_damage(plant.explode_damage):
                                    self.zombies.remove(zombie)
                                    self.score += 50
                        self.plants.remove(plant)
                        
            # 更新豌豆
            for pea in self.peas[:]:
                pea.update()
                
                # 检查豌豆是否击中僵尸
                pea_rect = pea.get_rect()
                for zombie in self.zombies[:]:
                    if pea_rect.colliderect(zombie.get_rect()):
                        if pea in self.peas:
                            self.peas.remove(pea)
                        if zombie.take_damage(pea.damage):
                            self.zombies.remove(zombie)
                            self.score += 10
                        break
                        
                if pea.is_off_screen():
                    if pea in self.peas:
                        self.peas.remove(pea)
                        
            # 更新僵尸
            for zombie in self.zombies[:]:
                zombie.update()
                
                # 检查僵尸是否吃到植物
                zombie.eating = False
                zombie_rect = zombie.get_rect()
                for plant in self.plants:
                    plant_rect = plant.get_rect()
                    if (zombie_rect.colliderect(plant_rect) and 
                        abs(zombie.row * Config.GRID_SIZE + Config.GRID_SIZE//2 - plant.y) < 10):
                        
                        zombie.eating = True
                        if zombie.eat_timer % 60 == 0:  # 每秒攻击一次
                            if plant.take_damage(zombie.damage):
                                self.plants.remove(plant)
                        break
                        
                if zombie.is_off_screen():
                    self.game_over = True
                    
            # 更新太阳
            for sun in self.suns[:]:
                sun.update()
                if sun.collect_anim > 20:
                    self.suns.remove(sun)
                    
            # 更新卡片
            for card in self.cards:
                card.update()
                
            # 检查胜利条件
            if self.wave > 10:
                self.win = True
                
    def draw_background(self, surface):
        """绘制背景"""
        # 草地
        surface.fill(GRASS_COLOR, (0, 0, Config.GAME_WIDTH, Config.GAME_HEIGHT))
        
        # 网格
        for col in range(Config.GRID_COLS + 1):
            x = col * Config.GRID_SIZE
            pygame.draw.line(surface, GRID_COLOR, (x, 0), (x, Config.GAME_HEIGHT))
        for row in range(Config.GRID_ROWS + 1):
            y = row * Config.GRID_SIZE
            pygame.draw.line(surface, GRID_COLOR, (0, y), (Config.GAME_WIDTH, y))
            
        # 天空背景
        surface.fill(SKY_COLOR, (Config.GAME_WIDTH, 0, Config.UI_WIDTH, SCREEN_HEIGHT))
        
    def draw_menu(self, surface):
        """绘制菜单"""
        self.draw_background(surface)
        
        # 标题
        title = font_huge.render("植物大战僵尸", True, PLANT_GREEN)
        title_shadow = font_huge.render("植物大战僵尸", True, TEXT_SHADOW)
        surface.blit(title_shadow, (SCREEN_WIDTH//2 - title.get_width()//2 + 3, 103))
        surface.blit(title, (SCREEN_WIDTH//2 - title.get_width()//2, 100))
        
        # 开始提示
        start_text = font_medium.render("按任意键开始游戏", True, YELLOW)
        surface.blit(start_text, (SCREEN_WIDTH//2 - start_text.get_width()//2, 250))
        
        # 游戏说明
        instructions = [
            "游戏说明:",
            "1. 收集太阳购买植物",
            "2. 在草地上种植植物防御僵尸",
            "3. 防止僵尸进入房子",
            "4. 存活10波僵尸即可胜利",
            "",
            "植物介绍:",
            "• 向日葵: 生产太阳",
            "• 豌豆射手: 发射豌豆攻击",
            "• 坚果墙: 阻挡僵尸前进",
            "• 樱桃炸弹: 爆炸清除区域僵尸"
        ]
        
        for i, text in enumerate(instructions):
            text_surf = font_small.render(text, True, TEXT_COLOR)
            surface.blit(text_surf, (50, 350 + i * 25))
            
    def draw_game(self, surface):
        """绘制游戏"""
        # 绘制背景
        self.draw_background(surface)
        
        # 绘制太阳
        for sun in self.suns:
            sun.draw(surface)
            
        # 绘制植物
        for plant in self.plants:
            plant.draw(surface)
            
        # 绘制豌豆
        for pea in self.peas:
            pea.draw(surface)
            
        # 绘制僵尸
        for zombie in self.zombies:
            zombie.draw(surface)
            
        # 绘制UI
        self.draw_ui(surface)
        
    def draw_ui(self, surface):
        """绘制用户界面"""
        # UI背景
        ui_bg = pygame.Rect(Config.GAME_WIDTH, 0, Config.UI_WIDTH, SCREEN_HEIGHT)
        pygame.draw.rect(surface, UI_BG_COLOR, ui_bg)
        
        # 太阳数量
        sun_text = font_large.render(f"太阳: {self.sun_amount}", True, YELLOW)
        surface.blit(sun_text, (Config.GAME_WIDTH + 20, 20))
        
        # 波数
        wave_text = font_medium.render(f"波数: {self.wave}/10", True, TEXT_COLOR)
        surface.blit(wave_text, (Config.GAME_WIDTH + 20, 70))
        
        # 分数
        score_text = font_medium.render(f"分数: {self.score}", True, TEXT_COLOR)
        surface.blit(score_text, (Config.GAME_WIDTH + 20, 550))
        
        # 绘制卡片
        for card in self.cards:
            card.draw(surface)
            
        # 显示选中的植物
        if self.selected_card:
            mouse_x, mouse_y = pygame.mouse.get_pos()
            grid_pos = self.get_grid_position(mouse_x, mouse_y)
            
            if grid_pos:
                col, row = grid_pos
                plant_x = col * Config.GRID_SIZE
                plant_y = row * Config.GRID_SIZE
                
                # 绘制预览
                preview_surf = pygame.Surface((Config.GRID_SIZE, Config.GRID_SIZE), pygame.SRCALPHA)
                if self.selected_card.type == PlantType.SUNFLOWER:
                    pygame.draw.circle(preview_surf, (*YELLOW, 150), 
                                     (Config.GRID_SIZE//2, Config.GRID_SIZE//2), 20)
                elif self.selected_card.type == PlantType.PEASHOOTER:
                    pygame.draw.circle(preview_surf, (*PLANT_GREEN, 150), 
                                     (Config.GRID_SIZE//2, Config.GRID_SIZE//2), 20)
                elif self.selected_card.type == PlantType.WALLNUT:
                    pygame.draw.circle(preview_surf, (*(150, 100, 50), 150), 
                                     (Config.GRID_SIZE//2, Config.GRID_SIZE//2), 20)
                elif self.selected_card.type == PlantType.CHERRY_BOMB:
                    pygame.draw.circle(preview_surf, (*RED, 150), 
                                     (Config.GRID_SIZE//2, Config.GRID_SIZE//2), 20)
                    
                surface.blit(preview_surf, (plant_x, plant_y))
                
    def draw_game_over(self, surface):
        """绘制游戏结束界面"""
        self.draw_game(surface)
        
        # 半透明覆盖
        overlay = pygame.Surface((SCREEN_WIDTH, SCREEN_HEIGHT))
        overlay.set_alpha(150)
        overlay.fill((0, 0, 0))
        surface.blit(overlay, (0, 0))
        
        if self.win:
            # 胜利界面
            win_text = font_huge.render("胜利!", True, YELLOW)
            score_text = font_large.render(f"最终分数: {self.score}", True, TEXT_COLOR)
            
            surface.blit(win_text, (SCREEN_WIDTH//2 - win_text.get_width()//2, 200))
            surface.blit(score_text, (SCREEN_WIDTH//2 - score_text.get_width()//2, 300))
        else:
            # 失败界面
            lose_text = font_huge.render("游戏结束", True, RED)
            score_text = font_large.render(f"最终分数: {self.score}", True, TEXT_COLOR)
            wave_text = font_medium.render(f"到达波数: {self.wave}", True, TEXT_COLOR)
            
            surface.blit(lose_text, (SCREEN_WIDTH//2 - lose_text.get_width()//2, 200))
            surface.blit(score_text, (SCREEN_WIDTH//2 - score_text.get_width()//2, 300))
            surface.blit(wave_text, (SCREEN_WIDTH//2 - wave_text.get_width()//2, 370))
        
        # 重新开始提示
        restart_text = font_medium.render("按R重新开始，ESC返回菜单", True, TEXT_COLOR)
        surface.blit(restart_text, (SCREEN_WIDTH//2 - restart_text.get_width()//2, 500))
        
    def handle_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
                
            elif event.type == pygame.MOUSEBUTTONDOWN:
                mouse_pos = pygame.mouse.get_pos()
                
                if self.state == "menu":
                    self.start_game()
                    
                elif self.state == "playing":
                    if event.button == 1:  # 左键点击
                        # 收集太阳
                        for sun in self.suns[:]:
                            if sun.check_collect(mouse_pos):
                                self.sun_amount += sun.value
                                self.suns.remove(sun)
                                break
                        else:
                            # 检查卡片点击
                            for card in self.cards:
                                if card.check_hover(mouse_pos) and card.can_use(self.sun_amount):
                                    self.selected_card = card
                                    card.selected = True
                                    break
                            else:
                                # 放置植物
                                if self.selected_card:
                                    grid_pos = self.get_grid_position(*mouse_pos)
                                    if grid_pos:
                                        col, row = grid_pos
                                        if not self.is_grid_occupied(col, row):
                                            plant_x = col * Config.GRID_SIZE
                                            plant_y = row * Config.GRID_SIZE
                                            
                                            if self.selected_card.type == PlantType.SUNFLOWER:
                                                plant = Plant(plant_x, plant_y, PlantType.SUNFLOWER, 100)
                                            elif self.selected_card.type == PlantType.PEASHOOTER:
                                                plant = Plant(plant_x, plant_y, PlantType.PEASHOOTER, 100)
                                            elif self.selected_card.type == PlantType.WALLNUT:
                                                plant = Plant(plant_x, plant_y, PlantType.WALLNUT, 400)
                                            elif self.selected_card.type == PlantType.CHERRY_BOMB:
                                                plant = Plant(plant_x, plant_y, PlantType.CHERRY_BOMB, 100)
                                                plant.is_exploding = True
                                                
                                            self.plants.append(plant)
                                            self.sun_amount -= self.selected_card.cost
                                            self.selected_card.use()
                                            self.selected_card.selected = False
                                            self.selected_card = None
                                    
            elif event.type == pygame.MOUSEMOTION:
                if self.state == "playing":
                    mouse_pos = pygame.mouse.get_pos()
                    for card in self.cards:
                        card.check_hover(mouse_pos)
                        
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    if self.state == "playing" or self.game_over or self.win:
                        self.state = "menu"
                    elif self.state == "menu":
                        pygame.quit()
                        sys.exit()
                        
                elif event.key == pygame.K_r and (self.game_over or self.win):
                    self.start_game()
                    
                elif self.state == "menu":
                    self.start_game()

    def draw(self, surface):
        if self.state == "menu":
            self.draw_menu(surface)
        elif self.state == "playing":
            if self.game_over or self.win:
                self.draw_game_over(surface)
            else:
                self.draw_game(surface)

def main():
    game = PlantsVsZombies()
    
    while True:
        game.handle_events()
        game.update()
        game.draw(screen)
        pygame.display.flip()
        clock.tick(FPS)

if __name__ == "__main__":
    main()