import pygame
import random
import sys
import math   # 修复1：导入 math 模块，用于 sin

# ---------- 基础配置 ----------
WIDTH, HEIGHT = 800, 600
FPS = 60
BLUE_DEEP = (10, 40, 80)
BLUE_SHALLOW = (20, 120, 180)
WHITE = (255, 255, 255)
RED = (220, 60, 60)
GREEN = (60, 200, 120)
YELLOW = (240, 220, 80)

pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("潜水员戴夫 - Pygame Demo")
clock = pygame.time.Clock()

# ---- 安全字体初始化（修复2：防止 SysFont 崩溃）----
try:
    font = pygame.font.SysFont("simhei", 24)   # 尝试使用黑体
except Exception:
    font = pygame.font.Font(None, 24)          # 失败则使用默认字体


# ---------- 潜水员 ----------
class Diver(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.Surface((36, 48))
        self.image.fill(YELLOW)
        # 画个简易潜水员：头+身体
        pygame.draw.circle(self.image, WHITE, (18, 12), 8)
        self.rect = self.image.get_rect(center=(WIDTH // 2, 80))
        self.speed = 4
        self.oxygen = 100          # 氧气
        self.hp = 100              # 血量
        self.score = 0             # 收集得分

    def update(self, keys):
        if keys[pygame.K_LEFT]:
            self.rect.x -= self.speed
        if keys[pygame.K_RIGHT]:
            self.rect.x += self.speed
        if keys[pygame.K_UP]:
            self.rect.y -= self.speed
        if keys[pygame.K_DOWN]:
            self.rect.y += self.speed
        # 边界限制
        self.rect.clamp_ip(screen.get_rect())
        # 氧气随下潜深度消耗更快
        depth_factor = 1 + (self.rect.y / HEIGHT) * 1.5
        self.oxygen -= 0.05 * depth_factor
        if self.oxygen <= 0:
            self.oxygen = 0
            self.hp -= 0.5


# ---------- 鱼类（可收集）----------
class Fish(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.Surface((28, 18))
        self.image.fill(GREEN)
        self.rect = self.image.get_rect(
            x=random.randint(0, WIDTH - 28),
            y=random.randint(150, HEIGHT - 20)
        )
        self.value = random.choice([10, 20, 30])   # 不同鱼不同分
        self.timer = 0

    def update(self):
        self.timer += 1
        # 左右摆动：使用 math.sin（修复：pygame.math.sin 不存在）
        self.rect.x += int(2 * math.sin(self.timer / 20.0))


# ---------- 危险生物（鲨鱼）----------
class Shark(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.Surface((60, 30))
        self.image.fill(RED)
        self.rect = self.image.get_rect(
            x=WIDTH,
            y=random.randint(150, HEIGHT - 30)
        )
        self.speed = random.uniform(2.5, 4.0)

    def update(self):
        self.rect.x -= self.speed
        if self.rect.right < 0:
            self.kill()


# ---------- 宝箱（收集物）----------
class Treasure(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.Surface((24, 24))
        self.image.fill(YELLOW)
        self.rect = self.image.get_rect(
            x=random.randint(0, WIDTH - 24),
            y=random.randint(200, HEIGHT - 24)
        )


# ---------- 气泡特效 ----------
class Bubble(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        r = random.randint(2, 5)
        self.image = pygame.Surface((r * 2, r * 2), pygame.SRCALPHA)
        pygame.draw.circle(self.image, (255, 255, 255, 180), (r, r), r)
        self.rect = self.image.get_rect(center=(x, y))
        self.speed = random.uniform(1.0, 2.5)

    def update(self):
        self.rect.y -= self.speed
        if self.rect.bottom < 0:
            self.kill()


# ---------- 游戏主循环 ----------
def draw_hud(d):
    """绘制氧气/血量/分数 HUD"""
    pygame.draw.rect(screen, (0, 0, 0), (10, 10, 204, 24), 1)
    pygame.draw.rect(screen, BLUE_SHALLOW, (12, 12, d.oxygen * 2, 20))
    o2_text = font.render(f"氧气 {int(d.oxygen)}%", True, WHITE)
    screen.blit(o2_text, (12, 38))

    pygame.draw.rect(screen, (0, 0, 0), (10, 70, 204, 24), 1)
    pygame.draw.rect(screen, RED, (12, 72, d.hp * 2, 20))
    hp_text = font.render(f"血量 {int(d.hp)}%", True, WHITE)
    screen.blit(hp_text, (12, 98))

    score_text = font.render(f"得分 {d.score}", True, YELLOW)
    screen.blit(score_text, (WIDTH - 140, 12))


def main():
    diver = Diver()
    divers = pygame.sprite.Group(diver)
    fishes = pygame.sprite.Group()
    sharks = pygame.sprite.Group()
    treasures = pygame.sprite.Group()
    bubbles = pygame.sprite.Group()

    # 初始填充一些鱼和宝箱
    for _ in range(6):
        fishes.add(Fish())
    for _ in range(3):
        treasures.add(Treasure())

    spawn_timers = {"fish": 0, "shark": 0, "treasure": 0}
    running = True

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

        keys = pygame.key.get_pressed()

        # --- 更新 ---
        divers.update(keys)
        fishes.update()
        sharks.update()
        treasures.update()
        bubbles.update()

        # 持续冒泡
        if random.random() < 0.3:
            bubbles.add(Bubble(
                diver.rect.centerx + random.randint(-15, 15),
                diver.rect.bottom
            ))

        # 定时生成鱼
        spawn_timers["fish"] += 1
        if spawn_timers["fish"] > 120:
            spawn_timers["fish"] = 0
            if len(fishes) < 10:
                fishes.add(Fish())

        # 定时生成鲨鱼
        spawn_timers["shark"] += 1
        if spawn_timers["shark"] > 300:
            spawn_timers["shark"] = 0
            if len(sharks) < 3:
                sharks.add(Shark())

        # 收集鱼
        hit_fish = pygame.sprite.spritecollide(diver, fishes, True)
        for f in hit_fish:
            diver.score += f.value

        # 收集宝箱
        hit_treasure = pygame.sprite.spritecollide(diver, treasures, True)
        for t in hit_treasure:
            diver.score += 50
            diver.oxygen = min(100, diver.oxygen + 20)   # 宝箱补气
        # 补充宝箱
        if spawn_timers["fish"] % 60 == 0 and len(treasures) < 4:
            treasures.add(Treasure())

        # 撞到鲨鱼：扣血 + 击退
        hit_shark = pygame.sprite.spritecollide(diver, sharks, False)
        for s in hit_shark:
            diver.hp -= 15
            diver.rect.y -= 30
            diver.rect.clamp_ip(screen.get_rect())

        # 死亡判定
        if diver.hp <= 0:
            running = False

        # --- 绘制 ---
        # 渐变背景：上浅下深
        for y in range(HEIGHT):
            c = (
                int(BLUE_SHALLOW[0] + (BLUE_DEEP[0] - BLUE_SHALLOW[0]) * y / HEIGHT),
                int(BLUE_SHALLOW[1] + (BLUE_DEEP[1] - BLUE_SHALLOW[1]) * y / HEIGHT),
                int(BLUE_SHALLOW[2] + (BLUE_DEEP[2] - BLUE_SHALLOW[2]) * y / HEIGHT),
            )
            pygame.draw.line(screen, c, (0, y), (WIDTH, y))

        bubbles.draw(screen)
        fishes.draw(screen)
        treasures.draw(screen)
        sharks.draw(screen)
        divers.draw(screen)
        draw_hud(diver)

        if not running:
            over = font.render(f"游戏结束  最终得分 {diver.score}", True, WHITE)
            screen.blit(over, (WIDTH // 2 - 160, HEIGHT // 2))

        pygame.display.flip()
        clock.tick(FPS)

    pygame.quit()
    sys.exit()


if __name__ == "__main__":
    main()