import pygame
import random

pygame.init()

# ============窗口常量============
WIDTH = 960
HEIGHT = 550
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("植物大战僵尸‑完整版")
clock = pygame.time.Clock()
FPS = 60

# ============颜色定义============
GRASS_GREEN = (75, 175, 55)
PEASHOOTER_COLOR = (20, 150, 25)
SUNFLOWER_COLOR = (255, 200, 30)
WALLNUT_COLOR = (120, 80, 30)
ZOMBIE_COLOR = (100, 60, 35)
CONE_ZOMBIE_COLOR = (160, 90, 40)
PEA_COLOR = (50, 210, 50)
SUN_COLOR = (255, 215, 0)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
WHITE = (255, 255, 255)

# ============字体（修复SysFont报错）============
font = pygame.font.Font(None, 32)
small_font = pygame.font.Font(None, 24)

# ============网格设置============
ROW_COUNT = 5
CELL_HEIGHT = HEIGHT // ROW_COUNT
CELL_WIDTH = 80

# ============全局游戏数据============
plants = []
peas = []
zombies = []
sun_items = []
sun_score = 150
zombie_spawn_timer = 0
game_over = False
plant_cooldown = 0

# ============植物类型常量============
PEASHOOTER = 1
SUNFLOWER = 2
WALLNUT = 3

# ============植物类============
class Plant:
    def __init__(self, row, col, plant_type):
        self.row = row
        self.col = col
        self.x = col * CELL_WIDTH
        self.y = row * CELL_HEIGHT
        self.type = plant_type
        self.cd = 0
        self.hp = 300
        self.sun_cd = 0

    def update(self):
        self.cd += 1
        if self.type == PEASHOOTER:
            if self.cd >= 90:
                peas.append([self.x + 60, self.y + 25, self.row])
                self.cd = 0
        elif self.type == SUNFLOWER:
            self.sun_cd += 1
            if self.sun_cd >= 180:
                sun_items.append([self.x + 30, self.y])
                self.sun_cd = 0

    def draw(self):
        if self.type == PEASHOOTER:
            pygame.draw.rect(screen, PEASHOOTER_COLOR, (self.x + 10, self.y + 10, 60, 60))
        elif self.type == SUNFLOWER:
            pygame.draw.circle(screen, SUNFLOWER_COLOR, (int(self.x + 40), int(self.y + 40)), 28)
        elif self.type == WALLNUT:
            pygame.draw.rect(screen, WALLNUT_COLOR, (self.x + 8, self.y + 8, 64, 64))

# ============僵尸类============
class Zombie:
    def __init__(self, row):
        self.row = row
        self.x = WIDTH
        self.y = row * CELL_HEIGHT
        self.speed = 1
        self.attack_timer = 0
        self.eating_plant = None
        #20%概率生成路障僵尸
        if random.random() < 0.2:
            self.hp = 1
            self.is_cone = True
        else:
            self.hp = 5
            self.is_cone = False

    def update(self):
        # 判断当前行有没有阻挡的植物
        blocked = False
        for p in plants:
            if p.row == self.row and p.x + 70 > self.x and p.x < self.x + 50:
                blocked = True
                self.eating_plant = p
                break
        if blocked:
            self.attack_timer += 1
            if self.attack_timer >= 60:
                self.eating_plant.hp -= 10
                self.attack_timer = 0
        else:
            self.x -= self.speed
            self.eating_plant = None

    def draw(self):
        if self.is_cone:
            pygame.draw.rect(screen, CONE_ZOMBIE_COLOR, (self.x, self.y + 5, 50, 70))
        else:
            pygame.draw.rect(screen, ZOMBIE_COLOR, (self.x, self.y + 5, 50, 70))
        hp_text = small_font.render(str(self.hp), True, RED)
        screen.blit(hp_text, (self.x + 10, self.y - 15))

# ============主循环============
running = True
while running:
    clock.tick(FPS)
    plant_cooldown += 1

    #事件监听
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        if event.type == pygame.MOUSEBUTTONDOWN and not game_over:
            mx, my = pygame.mouse.get_pos()
            r = my // CELL_HEIGHT
            c = mx // CELL_WIDTH
            #收集阳光
            for sun in sun_items[:]:
                sx, sy = sun
                if abs(mx - sx) < 25 and abs(my - sy) < 25:
                    sun_score += 25
                    sun_items.remove(sun)
                    break
            else:
                #判断格子是否已有植物
                occupied = False
                for p in plants:
                    if p.row == r and p.col == c:
                        occupied = True
                        break
                if not occupied and plant_cooldown > 20:
                    # 左键：豌豆射手 100阳光
                    if event.button == 1 and sun_score >= 100:
                        plants.append(Plant(r, c, PEASHOOTER))
                        sun_score -= 100
                        plant_cooldown = 0
                    # 中键：向日葵 50阳光
                    elif event.button == 2 and sun_score >= 50:
                        plants.append(Plant(r, c, SUNFLOWER))
                        sun_score -= 50
                        plant_cooldown = 0
                    #右键：坚果墙 50阳光
                    elif event.button == 3 and sun_score >= 50:
                        plants.append(Plant(r, c, WALLNUT))
                        sun_score -= 50
                        plant_cooldown = 0

    if not game_over:
        #生成僵尸
        zombie_spawn_timer += 1
        spawn_interval = max(100, 220 - len(zombies)*8)
        if zombie_spawn_timer >= spawn_interval:
            rand_row = random.randint(0, ROW_COUNT - 1)
            zombies.append(Zombie(rand_row))
            zombie_spawn_timer = 0

        #更新植物，删除血量归零植物
        for p in plants[:]:
            p.update()
            if p.hp <= 0:
                plants.remove(p)

        #更新豌豆+碰撞检测
        new_peas = []
        for pea in peas:
            px, py, pr = pea
            px += 5
            hit = False
            for z in zombies[:]:
                if z.row == pr and z.x < px < z.x + 50:
                    z.hp -= 1
                    hit = True
                    if z.hp <= 0:
                        zombies.remove(z)
                    break
            if not hit and px < WIDTH:
                new_peas.append([px, py, pr])
        peas = new_peas

        #更新僵尸
        for z in zombies:
            z.update()
            if z.x < 40:
                game_over = True

        #阳光自动下落
        for s in sun_items[:]:
            s[1] += 0.8
            if s[1] > HEIGHT - 30:
                sun_items.remove(s)

    # ============绘制画面============
    screen.fill(GRASS_GREEN)
    #网格线
    for i in range(ROW_COUNT + 1):
        pygame.draw.line(screen, BLACK, (0, i * CELL_HEIGHT), (WIDTH, i * CELL_HEIGHT), 2)
    for j in range(13):
        pygame.draw.line(screen, BLACK, (j * CELL_WIDTH, 0), (j * CELL_WIDTH, HEIGHT), 1)

    #绘制植物
    for p in plants:
        p.draw()
    #绘制豌豆
    for pea in peas:
        pygame.draw.circle(screen, PEA_COLOR, (int(pea[0]), int(pea[1])), 6)
    #绘制僵尸
    for z in zombies:
        z.draw()
    #绘制掉落阳光
    for sun in sun_items:
        sx, sy = sun
        pygame.draw.circle(screen, SUN_COLOR, (int(sx), int(sy)), 18)

    #UI文字
    sun_text = font.render(f"阳光: {sun_score}", True, BLACK)
    screen.blit(sun_text, (20, 10))
    tip1 = small_font.render("左键=豌豆射手(100)",True,BLACK)
    tip2 = small_font.render("中键=向日葵(50)｜右键=坚果(50)",True,BLACK)
    screen.blit(tip1,(20,45))
    screen.blit(tip2,(20,70))

    if game_over:
        over_text = font.render("游戏结束！僵尸入侵成功", True, RED)
        screen.blit(over_text, (WIDTH//2-150, HEIGHT//2))

    pygame.display.flip()

pygame.quit()
