import pygame
import sys
import math
import random

pygame.init()
pygame.display.set_caption("航海模拟器 · 中文显示")

WIDTH, HEIGHT = 900, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
FPS = 60

# ============ 中文字体加载 ============
def get_chinese_font(size, bold=False):
    """尝试多种常见中文字体，确保中文正常渲染"""
    candidates = [
        "microsoftyahei", "msyh", "simhei", "simsun",
        "notosanscjksc", "notosanscjk", "notosanssc",
        "pingfangsc", "pingfang", "heiti", "stheiti",
        "wenquanyimicrohei", "wenquanyizenhei",
        "arialunicodems", "dejavusans",
    ]
    for name in candidates:
        try:
            path = pygame.font.match_font(name, bold=bold)
        except TypeError:
            path = pygame.font.match_font(name)
        if path:
            try:
                return pygame.font.Font(path, size)
            except Exception:
                continue
    # 兜底：系统默认（某些系统下中文会变方块）
    return pygame.font.SysFont("sans-serif", size, bold=bold)

FONT_HUD   = get_chinese_font(22, True)
FONT_HUD2  = get_chinese_font(18)
FONT_TIP   = get_chinese_font(16)

# ============ 常量 ============
SEA_TOP = 320
SKY_TOP = (108, 172, 224)
SKY_BOT = (218, 240, 250)

# ============ 帆船 ============
class Boat:
    def __init__(self):
        self.x = WIDTH // 2
        self.y = SEA_TOP + 60
        self.speed = 3.0
        self.target_speed = 3.0
        self.tilt = 0.0
        self.scroll = 0.0
        self.heading = 0.0

boat = Boat()

# ============ 绘制函数 ============
def draw_sky(surf):
    for y in range(0, SEA_TOP):
        r = y / SEA_TOP
        col = (
            int(SKY_TOP[0] + (SKY_BOT[0] - SKY_TOP[0]) * r),
            int(SKY_TOP[1] + (SKY_BOT[1] - SKY_TOP[1]) * r),
            int(SKY_TOP[2] + (SKY_BOT[2] - SKY_TOP[2]) * r),
        )
        pygame.draw.line(surf, col, (0, y), (WIDTH, y))

def draw_sun(surf, cx, cy):
    for r in range(70, 0, -5):
        alpha = int((70 - r) / 70 * 90)
        halo = pygame.Surface((r * 2, r * 2), pygame.SRCALPHA)
        pygame.draw.circle(halo, (255, 235, 150, alpha), (r, r), r)
        surf.blit(halo, (cx - r, cy - r))
    pygame.draw.circle(surf, (255, 246, 200), (cx, cy), 38)
    pygame.draw.circle(surf, (255, 255, 235), (cx, cy), 30)

def draw_cloud(surf, x, y, scale):
    w, h = int(180 * scale), int(90 * scale)
    cloud = pygame.Surface((w, h), pygame.SRCALPHA)
    puffs = [(40, 55, 28), (70, 42, 24), (100, 54, 30),
             (128, 52, 22), (64, 68, 24), (104, 70, 20)]
    for px, py, pr in puffs:
        pygame.draw.circle(cloud, (255, 255, 255, 215),
                           (int(px * scale), int(py * scale)), int(pr * scale))
    surf.blit(cloud, (int(x - 90 * scale), int(y - 45 * scale)))

def draw_islands(surf, scroll):
    cycle = 1600
    base_list = [(180, 58, 88), (620, 42, 68), (1080, 72, 100), (1480, 50, 78)]
    off = scroll % cycle
    for base_x, h, w in base_list:
        for k in (-1, 0, 1):
            x = base_x + k * cycle - off
            if -240 < x < WIDTH + 240:
                pts = [
                    (x - w, SEA_TOP + 2),
                    (x - w * 0.6, SEA_TOP - h * 0.68),
                    (x - w * 0.18, SEA_TOP - h),
                    (x + w * 0.3, SEA_TOP - h * 0.58),
                    (x + w, SEA_TOP + 2),
                ]
                pygame.draw.polygon(surf, (68, 102, 96), pts)

def draw_sea(surf, t, scroll):
    for y in range(SEA_TOP, HEIGHT):
        r = (y - SEA_TOP) / (HEIGHT - SEA_TOP)
        col = (int(16 + 44 * r), int(78 + 74 * r), int(138 + 82 * r))
        pygame.draw.line(surf, col, (0, y), (WIDTH, y))

    for i in range(6):
        y0 = SEA_TOP + 10 + i * 45
        if y0 > HEIGHT + 10:
            break
        amp = 5 + i * 1.2
        freq = 0.011 + i * 0.0016
        col = (min(255, 62 + i * 14),
               min(255, 140 + i * 12),
               min(255, 200 + i * 6))
        pts = []
        for x in range(-10, WIDTH + 20, 8):
            yy = y0 + math.sin((x + scroll * (20 + i * 10) * 0.5 + t * 40) * freq) * amp
            pts.append((x, yy))
        pygame.draw.lines(surf, col, False, pts, 2)

def draw_gull(surf, x, y, scale, phase):
    flap = math.sin(phase) * 6 * scale
    col = (74, 78, 88)
    lw = max(1, int(2 * scale))
    left = [(x, y), (x - 10 * scale, y - 5 * scale - flap), (x - 20 * scale, y - 2 * scale)]
    right = [(x, y), (x + 10 * scale, y - 5 * scale - flap), (x + 20 * scale, y - 2 * scale)]
    pygame.draw.lines(surf, col, False, left, lw)
    pygame.draw.lines(surf, col, False, right, lw)

def draw_boat(surf, cx, cy, tilt):
    SW, SH = 320, 320
    bs = pygame.Surface((SW, SH), pygame.SRCALPHA)
    ox, oy = SW // 2, SH - 70

    # 船体
    hull = [
        (ox - 95, oy - 20), (ox + 65, oy - 20),
        (ox + 100, oy - 42), (ox + 90, oy - 12),
        (ox + 68, oy + 12), (ox - 70, oy + 12),
        (ox - 102, oy - 10),
    ]
    pygame.draw.polygon(bs, (104, 62, 36), hull)
    pygame.draw.polygon(bs, (68, 38, 20), hull, 2)

    # 甲板
    deck = [
        (ox - 90, oy - 20), (ox + 65, oy - 20),
        (ox + 98, oy - 37), (ox + 85, oy - 26),
        (ox - 88, oy - 12),
    ]
    pygame.draw.polygon(bs, (172, 122, 70), deck)

    # 舷窗
    for i in range(4):
        px = ox - 52 + i * 34
        pygame.draw.circle(bs, (255, 222, 128), (px, oy - 3), 6)
        pygame.draw.circle(bs, (80, 50, 30), (px, oy - 3), 6, 2)

    # 桅杆
    mast_top = (ox - 10, oy - 180)
    pygame.draw.line(bs, (96, 66, 42), (ox - 5, oy - 16), mast_top, 7)
    pygame.draw.line(bs, (72, 48, 30), (ox - 5, oy - 16), mast_top, 2)

    # 帆桁
    pygame.draw.line(bs, (112, 76, 46), (ox - 55, oy - 138), (ox + 74, oy - 146), 5)

    # 主帆
    sail_fill = (248, 245, 234)
    sail_line = (202, 194, 176)
    main = [(ox - 12, oy - 176), (ox - 92, oy - 108),
            (ox - 82, oy - 44), (ox - 6, oy - 36)]
    pygame.draw.polygon(bs, sail_fill, main)
    pygame.draw.polygon(bs, sail_line, main, 2)

    # 前帆
    jib = [(ox - 6, oy - 174), (ox + 96, oy - 38), (ox + 12, oy - 34)]
    pygame.draw.polygon(bs, (244, 241, 230), jib)
    pygame.draw.polygon(bs, sail_line, jib, 2)

    # 小旗
    flag = [(ox - 10, oy - 180), (ox + 24, oy - 170), (ox - 10, oy - 160)]
    pygame.draw.polygon(bs, (218, 66, 62), flag)

    # 旋转
    angle = -tilt * 7.0
    rotated = pygame.transform.rotozoom(bs, angle, 1.0)
    rect = rotated.get_rect(center=(cx, cy - 92))
    surf.blit(rotated, rect)

def draw_wake(surf, cx, cy, speed, t):
    if speed < 0.6:
        return
    power = speed / 10.0
    for i in range(8):
        px = cx + 92 - i * 12 - (t * 70) % 12
        py = cy + 6 + math.sin(i * 0.9 + t * 3.0) * 3
        r = int((6 - i * 0.6) * power)
        if r > 0:
            foam = pygame.Surface((r * 2, r * 2), pygame.SRCALPHA)
            pygame.draw.circle(foam, (255, 255, 255, 130), (r, r), r)
            surf.blit(foam, (px - r, py - r))

    for i in range(10):
        px = cx - 100 - i * 10 - (t * 40) % 10
        py = cy + 4 + math.sin(i * 0.6 - t * 2.2) * 4
        r = int((5 - i * 0.45) * power)
        if r > 0:
            foam = pygame.Surface((r * 2, r * 2), pygame.SRCALPHA)
            pygame.draw.circle(foam, (255, 255, 255, 100), (r, r), r)
            surf.blit(foam, (px - r, py - r))

def draw_hud(surf, boat):
    # 信息面板
    panel = pygame.Surface((280, 145), pygame.SRCALPHA)
    pygame.draw.rect(panel, (8, 38, 56, 200), panel.get_rect(), border_radius=16)
    pygame.draw.rect(panel, (116, 198, 228, 220), panel.get_rect(), 2, border_radius=16)
    surf.blit(panel, (20, 20))

    title = FONT_HUD.render("⚓ 航行状态", True, (255, 224, 130))
    surf.blit(title, (40, 34))

    pygame.draw.line(surf, (96, 168, 200), (40, 66), (280, 66), 1)

    spd = FONT_HUD2.render("航速：%.1f 节" % boat.speed, True, (222, 244, 255))
    surf.blit(spd, (40, 78))

    hdg = FONT_HUD2.render("航向：%03d°" % (int(boat.heading) % 360), True, (222, 244, 255))
    surf.blit(hdg, (40, 106))

    if boat.target_speed >= 8.0:
        sail_txt, sail_col = "帆力：满帆", (140, 245, 160)
    elif boat.target_speed >= 5.0:
        sail_txt, sail_col = "帆力：中帆", (255, 228, 130)
    elif boat.target_speed >= 2.0:
        sail_txt, sail_col = "帆力：半帆", (255, 200, 120)
    else:
        sail_txt, sail_col = "帆力：收帆", (255, 150, 140)
    sail = FONT_HUD2.render(sail_txt, True, sail_col)
    surf.blit(sail, (160, 78))

    # 横倾指示条
    bar_x, bar_y, bar_w, bar_h = 160, 114, 100, 14
    pygame.draw.rect(surf, (20, 60, 80), (bar_x, bar_y, bar_w, bar_h), border_radius=7)
    center = bar_x + bar_w // 2
    pygame.draw.line(surf, (150, 200, 220),
                     (center, bar_y - 2), (center, bar_y + bar_h + 2), 1)
    knob_x = int(center + boat.tilt * (bar_w // 2 - 4))
    pygame.draw.circle(surf, (255, 210, 110), (knob_x, bar_y + bar_h // 2), 6)
    pygame.draw.circle(surf, (120, 70, 20), (knob_x, bar_y + bar_h // 2), 6, 1)

    # 底部提示
    tip_bg = pygame.Surface((640, 36), pygame.SRCALPHA)
    pygame.draw.rect(tip_bg, (6, 32, 48, 190), tip_bg.get_rect(), border_radius=18)
    pygame.draw.rect(tip_bg, (90, 160, 190, 200), tip_bg.get_rect(), 1, border_radius=18)
    surf.blit(tip_bg, (WIDTH // 2 - 320, HEIGHT - 50))

    tip = FONT_TIP.render(
        "← → / A D 转舵     ↑ ↓ / W S 升降帆     ESC 退出",
        True, (200, 232, 248))
    surf.blit(tip, (WIDTH // 2 - tip.get_width() // 2, HEIGHT - 42))

# ============ 主循环 ============
def main():
    t = 0.0
    running = True

    clouds = [{
        'x': random.uniform(-100, WIDTH),
        'y': random.uniform(30, 190),
        'scale': random.uniform(0.55, 1.4),
        'drift': random.uniform(0.4, 1.1),
    } for _ in range(6)]

    gulls = [{
        'x': random.uniform(0, WIDTH),
        'y': random.uniform(80, 280),
        'speed': random.uniform(22, 48),
        'phase': random.uniform(0, 6.28),
        'scale': random.uniform(0.7, 1.3),
    } for _ in range(5)]

    while running:
        dt = clock.tick(FPS) / 1000.0
        t += dt

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
                running = False

        keys = pygame.key.get_pressed()

        # 升降帆
        if keys[pygame.K_UP] or keys[pygame.K_w]:
            boat.target_speed = min(10.0, boat.target_speed + 4.0 * dt)
        if keys[pygame.K_DOWN] or keys[pygame.K_s]:
            boat.target_speed = max(0.0, boat.target_speed - 4.0 * dt)

        boat.speed += (boat.target_speed - boat.speed) * min(1.0, dt * 1.8)

        # 舵
        steer = 0.0
        if keys[pygame.K_LEFT] or keys[pygame.K_a]:
            steer -= 1.0
        if keys[pygame.K_RIGHT] or keys[pygame.K_d]:
            steer += 1.0

        boat.tilt += (steer - boat.tilt) * min(1.0, dt * 4.5)
        boat.heading += steer * 55 * dt
        boat.x += steer * 55 * dt * (0.35 + boat.speed / 12.0)
        boat.x = max(200, min(WIDTH - 200, boat.x))
        boat.scroll += boat.speed * 20 * dt

        # ---- 绘制 ----
        draw_sky(screen)
        draw_sun(screen, 760, 90)

        for c in clouds:
            c['x'] -= (c['drift'] * 14 + boat.speed * 7) * dt
            if c['x'] < -180:
                c['x'] = WIDTH + 180
                c['y'] = random.uniform(30, 190)
                c['scale'] = random.uniform(0.55, 1.4)
            draw_cloud(screen, c['x'], c['y'], c['scale'])

        draw_islands(screen, boat.scroll * 0.16)
        draw_sea(screen, t, boat.scroll)

        for g in gulls:
            g['x'] -= g['speed'] * dt
            if g['x'] < -60:
                g['x'] = WIDTH + 60
                g['y'] = random.uniform(80, 280)
                g['phase'] = random.uniform(0, 6.28)
            draw_gull(screen, g['x'], g['y'], g['scale'], t * 6.0 + g['phase'])

        bob = math.sin(t * 2.3) * 3.2
        draw_boat(screen, boat.x, boat.y + bob, boat.tilt)
        draw_wake(screen, boat.x, boat.y + bob, boat.speed, t)
        draw_hud(screen, boat)

        pygame.display.flip()

    pygame.quit()
    sys.exit()

if __name__ == "__main__":
    main()