import pygame
import math
import random
import sys

# 初始化
pygame.init()

# ---------- 窗口设置 ----------
WIDTH, HEIGHT = 1000, 700
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("深海捕鱼大师 - Deep Sea Fishing")
clock = pygame.time.Clock()
FPS = 60

# ---------- 颜色常量 ----------
DEEP_BLUE = (5, 25, 60)
WATER_BLUE = (15, 55, 130)
WHITE = (255, 255, 255)
YELLOW = (255, 240, 50)
RED = (230, 40, 40)
GREEN = (40, 200, 40)
BLACK = (0, 0, 0)
ORANGE = (255, 140, 0)
GRAY = (120, 130, 150)

# ---------- 游戏参数 ----------
FISH_TYPES = {
    "clown": {"color": (255, 100, 50), "size": (30, 18), "score": 10, "speed_range": (1.5, 3.0)},
    "tropical": {"color": (50, 180, 220), "size": (40, 24), "score": 20, "speed_range": (2.0, 3.5)},
    "shark": {"color": (100, 110, 130), "size": (70, 35), "score": 50, "speed_range": (2.5, 4.0)},
    "puffer": {"color": (60, 180, 80), "size": (35, 30), "score": 30, "speed_range": (2.0, 4.5)},
}
MAX_FISH = 12          # 屏幕上最多鱼的数量
HARPOON_COOLDOWN = 18  # 帧（约0.3秒）

# ---------- 辅助函数 ----------
def draw_fish(surf, pos, size, color, facing_right):
    """用基本形状绘制一条鱼"""
    x, y = pos
    w, h = size
    # 身体（椭圆）
    body_rect = pygame.Rect(0, 0, w, h)
    body_rect.center = (x, y)
    pygame.draw.ellipse(surf, color, body_rect)
    # 尾巴（三角形）
    tail_offset = -w//2 if facing_right else w//2
    tail_dir = 1 if facing_right else -1
    tail_points = [
        (x + tail_offset, y - h//2),
        (x + tail_offset - tail_dir * 8, y),
        (x + tail_offset, y + h//2)
    ]
    pygame.draw.polygon(surf, color, tail_points)
    # 眼睛
    eye_x = x + w//4 * (1 if facing_right else -1)
    pygame.draw.circle(surf, WHITE, (int(eye_x), y - 3), 4)
    pygame.draw.circle(surf, BLACK, (int(eye_x + 1), y - 3), 2)
    # 特殊纹理（小丑鱼的条纹）
    if color == (255, 100, 50):
        stripe_x = x - w//6
        pygame.draw.line(surf, WHITE, (stripe_x, y - h//3), (stripe_x, y + h//3), 3)

def draw_cannon(surf, center, angle):
    """绘制炮台（底座+炮管）"""
    x, y = center
    # 底座
    pygame.draw.circle(surf, GRAY, (x, y), 25)
    pygame.draw.circle(surf, (60, 70, 80), (x, y), 18)
    # 炮管（矩形旋转）
    barrel_length = 50
    barrel_width = 12
    # 计算炮管矩形未旋转时的四个角
    rect_points = [
        (-barrel_width//2, -barrel_length//2),
        (barrel_width//2, -barrel_length//2),
        (barrel_width//2, barrel_length//2),
        (-barrel_width//2, barrel_length//2)
    ]
    rotated = []
    cos_a, sin_a = math.cos(angle), math.sin(angle)
    for px, py in rect_points:
        rx = px * cos_a - py * sin_a
        ry = px * sin_a + py * cos_a
        rotated.append((x + rx, y - ry))  # 注意 y 轴翻转
    pygame.draw.polygon(surf, (180, 180, 190), rotated)
    pygame.draw.polygon(surf, (120, 120, 130), rotated, 2)

def draw_bubble(surf, pos, size):
    """绘制气泡"""
    pygame.draw.circle(surf, (200, 220, 255, 80), pos, size, 1)
    pygame.draw.circle(surf, WHITE, (pos[0]-size//3, pos[1]-size//3), size//4)

# ---------- 鱼类对象 ----------
class Fish:
    def __init__(self):
        self.type = random.choice(list(FISH_TYPES.keys()))
        props = FISH_TYPES[self.type]
        self.color = props["color"]
        self.size = props["size"]
        self.score = props["score"]
        speed = random.uniform(*props["speed_range"])
        # 水平方向随机
        self.vx = random.uniform(speed * 0.8, speed) * random.choice([1, -1])
        self.vy = random.uniform(-0.5, 0.5)
        self.x = random.uniform(100, WIDTH - 100)
        self.y = random.uniform(80, HEIGHT - 150)  # 避免炮台区域
        self.facing_right = self.vx > 0

    def update(self):
        self.x += self.vx
        self.y += self.vy
        self.facing_right = self.vx > 0
        # 边界反弹
        if self.x < 0:
            self.x = 0
            self.vx *= -1
        if self.x > WIDTH:
            self.x = WIDTH
            self.vx *= -1
        if self.y < 20:
            self.y = 20
            self.vy *= -1
        if self.y > HEIGHT - 130:
            self.y = HEIGHT - 130
            self.vy *= -1

    def draw(self, surf):
        draw_fish(surf, (int(self.x), int(self.y)), self.size, self.color, self.facing_right)

    def get_rect(self):
        return pygame.Rect(self.x - self.size[0]//2, self.y - self.size[1]//2, *self.size)

# ---------- 鱼叉对象 ----------
class Harpoon:
    def __init__(self, x, y, angle):
        self.speed = 12
        self.vx = math.cos(angle) * self.speed
        self.vy = -math.sin(angle) * self.speed
        self.x = x
        self.y = y
        self.alive = True
        self.angle = angle

    def update(self):
        self.x += self.vx
        self.y += self.vy
        if self.x < 0 or self.x > WIDTH or self.y < 0 or self.y > HEIGHT:
            self.alive = False

    def draw(self, surf):
        # 绘制细长鱼叉
        length = 20
        cos_a, sin_a = math.cos(self.angle), math.sin(self.angle)
        tip = (self.x + length * cos_a, self.y - length * sin_a)
        base = (self.x - 5 * cos_a, self.y + 5 * sin_a)
        pygame.draw.line(surf, YELLOW, base, tip, 4)
        pygame.draw.circle(surf, RED, (int(tip[0]), int(tip[1])), 3)

# ---------- 主游戏类 ----------
class Game:
    def __init__(self):
        self.fishes = []
        self.harpoons = []
        self.score = 0
        self.cooldown = 0
        self.cannon_x = WIDTH // 2
        self.cannon_y = HEIGHT - 60
        # 气泡列表（纯装饰）
        self.bubbles = [(random.randint(50, WIDTH-50), random.randint(50, HEIGHT-100), random.randint(5, 15)) for _ in range(20)]
        self.font_large = pygame.font.Font(None, 48)
        self.font_medium = pygame.font.Font(None, 32)

    def spawn_fish(self):
        while len(self.fishes) < MAX_FISH:
            self.fishes.append(Fish())

    def shoot(self, mouse_pos):
        if self.cooldown > 0:
            return
        # 计算角度
        dx = mouse_pos[0] - self.cannon_x
        dy = self.cannon_y - mouse_pos[1]  # 屏幕坐标Y轴向下，所以取反
        angle = math.atan2(dy, dx)
        self.harpoons.append(Harpoon(self.cannon_x, self.cannon_y, angle))
        self.cooldown = HARPOON_COOLDOWN

    def update(self):
        # 冷却倒计时
        if self.cooldown > 0:
            self.cooldown -= 1

        # 更新鱼
        for fish in self.fishes:
            fish.update()
        # 更新鱼叉
        for harpoon in self.harpoons:
            harpoon.update()

        # 碰撞检测：鱼叉 vs 鱼
        harpoons_to_remove = []
        fishes_to_remove = []
        for h in self.harpoons:
            h_rect = pygame.Rect(h.x - 2, h.y - 2, 4, 4)
            for f in self.fishes:
                if f.get_rect().colliderect(h_rect):
                    harpoons_to_remove.append(h)
                    fishes_to_remove.append(f)
                    self.score += f.score
                    break
        # 移除碰撞的鱼叉和鱼
        for h in harpoons_to_remove:
            if h in self.harpoons:
                self.harpoons.remove(h)
        for f in fishes_to_remove:
            if f in self.fishes:
                self.fishes.remove(f)

        # 移除越界鱼叉
        self.harpoons = [h for h in self.harpoons if h.alive]

        # 补充鱼群
        self.spawn_fish()

        # 气泡随机漂动
        for i in range(len(self.bubbles)):
            bx, by, size = self.bubbles[i]
            by -= random.uniform(0.2, 0.8)  # 上升
            bx += random.uniform(-0.3, 0.3)
            if by < -20:
                by = HEIGHT + 20
                bx = random.randint(50, WIDTH-50)
                size = random.randint(5, 15)
            self.bubbles[i] = (bx, by, size)

    def draw_background(self, surf):
        # 渐变海洋背景
        for y in range(HEIGHT):
            ratio = y / HEIGHT
            r = int(5 + ratio * 20)
            g = int(25 + ratio * 40)
            b = int(60 + ratio * 80)
            pygame.draw.line(surf, (r, g, b), (0, y), (WIDTH, y))
        # 海底沙地
        pygame.draw.rect(surf, (194, 178, 128), (0, HEIGHT-50, WIDTH, 50))
        # 海底石头
        for i in range(5):
            cx = random.randint(50 + i*200, 150 + i*200)
            pygame.draw.ellipse(surf, (100, 100, 80), (cx, HEIGHT-70, 80, 40))
        # 珊瑚
        for i in range(4):
            cx = 80 + i*250
            pygame.draw.polygon(surf, (220, 100, 80), [(cx, HEIGHT-50), (cx-10, HEIGHT-80), (cx+5, HEIGHT-70), (cx+15, HEIGHT-95), (cx+25, HEIGHT-70), (cx+20, HEIGHT-50)])
        # 气泡
        for (bx, by, size) in self.bubbles:
            draw_bubble(surf, (int(bx), int(by)), int(size))

    def draw_ui(self, surf):
        # 得分面板
        score_text = self.font_large.render(f"SCORE: {self.score}", True, WHITE)
        surf.blit(score_text, (20, 20))
        # 冷却提示
        if self.cooldown > 0:
            cd_text = self.font_medium.render("RELOADING...", True, ORANGE)
        else:
            cd_text = self.font_medium.render("READY - Click to shoot!", True, GREEN)
        surf.blit(cd_text, (WIDTH - 300, 20))
        # 操作提示
        hint = self.font_medium.render("Move mouse to aim, Left click to fire harpoon", True, (180, 180, 200))
        surf.blit(hint, (20, HEIGHT - 35))

    def run(self):
        running = True
        while running:
            # 事件处理
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    running = False
                elif event.type == pygame.MOUSEBUTTONDOWN:
                    if event.button == 1:
                        self.shoot(pygame.mouse.get_pos())

            # 更新
            self.update()

            # 绘制
            self.draw_background(screen)
            # 绘制鱼
            for fish in self.fishes:
                fish.draw(screen)
            # 绘制鱼叉
            for harpoon in self.harpoons:
                harpoon.draw(screen)
            # 绘制炮台（根据鼠标实时瞄准）
            mouse_x, mouse_y = pygame.mouse.get_pos()
            angle = math.atan2(self.cannon_y - mouse_y, mouse_x - self.cannon_x)
            draw_cannon(screen, (self.cannon_x, self.cannon_y), angle)
            # 绘制UI
            self.draw_ui(screen)

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

        pygame.quit()
        sys.exit()

# ---------- 启动游戏 ----------
if __name__ == "__main__":
    game = Game()
    game.run()