import tkinter as tk
import math
import random
import time

# ========================
# 全局配置
# ========================
WIDTH, HEIGHT = 900, 600
FPS = 60

# ========================
# 船舶状态（全部提前定义 + global 锁死）
# ========================
ship_x = 0.0          # 船只世界坐标 X
ship_y = 0.0          # 船只世界坐标 Y
ship_heading = 0.0    # 船头朝向（弧度）
ship_speed = 0.0       # 当前速度（节）
ship_rudder = 0.0      # 舵角 -1~1
throttle = 0.5         # 油门 0~1
fuel = 100.0           # 燃油百分比
health = 100.0         # 船体耐久
cargos = 0             # 当前货物数
max_cargos = 5         # 最大货物
anchor_down = False     # 锚是否放下
sail_raised = True     # 帆是否升起
weather = "☀️ 晴天"     # 天气
time_of_day = "day"    # 时段
game_time = 6.0        # 游戏内时间（小时）
day_count = 1          # 天数

# ========================
# 任务系统
# ========================
score = 0
combo = 0
mission_step = 0
missions = [
    "⚓ 任务1：出港！松开锚，向前航行",
    "⚓ 任务2：右转航向 90°，驶向浮标",
    "⚓ 任务3：在浮标附近收集货物（碰撞）",
    "⚓ 任务4：左转航向 270°，返回港口",
    "⚓ 任务5：减速到 2 节以下，抛锚靠岸",
]
message = ""
message_timer = 0

# ========================
# 世界物体
# ========================
buoys = []       # 浮标 [x, y, collected]
cargo_boxes = [] # 货物箱 [x, y, collected]
rocks = []       # 暗礁 [x, y, radius]
ships_ai = []    # AI 船只 [x, y, heading, speed, color]
port_pos = (0, 0)  # 港口位置

# ========================
# Tkinter 窗口
# ========================
root = tk.Tk()
root.title("⚓ 航海模拟器")
root.resizable(False, False)

main_canvas = tk.Canvas(root, width=WIDTH, height=HEIGHT, highlightthickness=0)
main_canvas.pack()

panel = tk.Frame(root)
panel.pack(fill="x")

info_label = tk.Label(panel, font=("Consolas", 10))
info_label.pack(side="left", padx=10)

task_label = tk.Label(panel, font=("Consolas", 9, "bold"))
task_label.pack(side="left", padx=10)

msg_label = tk.Label(panel, font=("Consolas", 9))
msg_label.pack(side="left", padx=10)

# ========================
# 主题
# ========================
themes = {
    "🌊 经典海洋": {"bg": "#1A237E", "fg": "#E8EAF6", "water": "#1565C0", "shore": "#FDD835"},
    "🌙 夜航模式": {"bg": "#0D1B2A", "fg": "#778DA9", "water": "#0D47A1", "shore": "#415A77"},
    "🌅 夕阳远航": {"bg": "#3E1F47", "fg": "#FFD700", "water": "#D84315", "shore": "#FF6F00"},
    "❄️ 冰海探险": {"bg": "#E3F2FD", "fg": "#0D47A1", "water": "#90CAF9", "shore": "#ECEFF1"},
    "🌴 热带海岛": {"bg": "#004D40", "fg": "#FFAB91", "water": "#00ACC1", "shore": "#FFCA28"},
    "🌫️ 浓雾迷航": {"bg": "#B0BEC5", "fg": "#37474F", "water": "#90A4AE", "shore": "#78909C"},
}

current_theme = "🌊 经典海洋"

def apply_theme(name):
    global current_theme
    current_theme = name
    t = themes[name]
    root.configure(bg=t["bg"])
    panel.configure(bg=t["bg"])
    info_label.configure(bg=t["bg"], fg=t["fg"])
    task_label.configure(bg=t["bg"], fg=t["fg"])
    msg_label.configure(bg=t["bg"], fg=t["fg"])
    draw_scene()

# ========================
# 生成世界
# ========================
def generate_world():
    global buoys, cargo_boxes, rocks, ships_ai, port_pos
    buoys = []
    cargo_boxes = []
    rocks = []
    ships_ai = []

    # 浮标（导航点）
    for i in range(6):
        angle = random.uniform(0, math.pi * 2)
        dist = random.uniform(300, 1500)
        bx = math.cos(angle) * dist
        by = math.sin(angle) * dist
        buoys.append([bx, by, False])

    # 货物箱
    for i in range(8):
        angle = random.uniform(0, math.pi * 2)
        dist = random.uniform(200, 1200)
        cx = math.cos(angle) * dist
        cy = math.sin(angle) * dist
        cargo_boxes.append([cx, cy, False])

    # 暗礁
    for i in range(10):
        angle = random.uniform(0, math.pi * 2)
        dist = random.uniform(400, 2000)
        rx = math.cos(angle) * dist
        ry = math.sin(angle) * dist
        rr = random.uniform(15, 40)
        rocks.append([rx, ry, rr])

    # AI 船只
    colors = ["#E53935", "#FB8C00", "#43A047", "#8E24AA"]
    for i in range(3):
        angle = random.uniform(0, math.pi * 2)
        dist = random.uniform(600, 2500)
        ax = math.cos(angle) * dist
        ay = math.sin(angle) * dist
        ah = random.uniform(0, math.pi * 2)
        spd = random.uniform(1.5, 4.0)
        ships_ai.append([ax, ay, ah, spd, colors[i]])

    port_pos = (0, 0)

generate_world()

# ========================
# 消息系统
# ========================
def show_message(text):
    global message, message_timer
    message = text
    message_timer = 3.0

# ========================
# 绘制海水（✅ 无半透明）
# ========================
def draw_water():
    main_canvas.delete("water")
    t = themes[current_theme]

    # 远处深水 → 近处浅水，用水平条纹模拟
    bands = 30
    for i in range(bands):
        y = HEIGHT // 2 + i * (HEIGHT // 2 // bands)
        ratio = i / bands
        r = int(21 * (1 - ratio) + 13 * ratio)
        g = int(101 * (1 - ratio) + 71 * ratio)
        b = int(192 * (1 - ratio) + 169 * ratio)
        main_canvas.create_line(0, y, WIDTH, y, fill=f"#{r:02x}{g:02x}{b:02x}", tags="water")

    # 波光（小白线）
    random.seed(int(time.time() * 2))
    for _ in range(40):
        wx = random.randint(0, WIDTH)
        wy = random.randint(HEIGHT // 2 + 10, HEIGHT - 10)
        main_canvas.create_line(wx, wy, wx + random.randint(5, 15), wy,
                                fill="#FFFFFF", width=1, tags="water")
    random.seed()

# ========================
# 绘制天空
# ========================
def draw_sky():
    main_canvas.delete("sky")
    t = themes[current_theme]

    for y in range(HEIGHT // 2):
        ratio = y / (HEIGHT / 2)
        if time_of_day == "day":
            r = int(135 * (1 - ratio) + 30 * ratio)
            g = int(206 * (1 - ratio) + 144 * ratio)
            b = int(250 * (1 - ratio) + 255 * ratio)
        elif time_of_day == "night":
            r = int(5 * (1 - ratio) + 0 * ratio)
            g = int(10 * (1 - ratio) + 0 * ratio)
            b = int(30 * (1 - ratio) + 15 * ratio)
        elif time_of_day == "dawn":
            r = int(255 * (1 - ratio) + 100 * ratio)
            g = int(120 * (1 - ratio) + 60 * ratio)
            b = int(50 * (1 - ratio) + 80 * ratio)
        else:  # dusk
            r = int(200 * (1 - ratio) + 60 * ratio)
            g = int(60 * (1 - ratio) + 20 * ratio)
            b = int(80 * (1 - ratio) + 40 * ratio)

        main_canvas.create_line(0, y, WIDTH, y, fill=f"#{r:02x}{g:02x}{b:02x}", tags="sky")

    # 太阳 / 月亮
    if time_of_day == "day":
        sx, sy = WIDTH * 0.75, HEIGHT * 0.18
        for r in range(30, 46, 4):
            main_canvas.create_oval(sx - r, sy - r, sx + r, sy + r,
                                    fill="#FFD700", outline="", tags="sky")
    elif time_of_day == "night":
        mx, my = WIDTH * 0.75, HEIGHT * 0.18
        main_canvas.create_oval(mx - 25, my - 25, mx + 25, my + 25,
                                fill="#FFF9C4", outline="", tags="sky")
        for _ in range(15):
            stx = random.randint(20, WIDTH - 20)
            sty = random.randint(10, HEIGHT // 2 - 20)
            main_canvas.create_text(stx, sty, text="✦", fill="#FFFFFF", font=("", 8), tags="sky")

    # 云
    if weather in ("☀️ 晴天", "🌅 夕阳远航"):
        for cx, cy in [(150, 60), (350, 90), (600, 50), (750, 80)]:
            draw_cloud(cx, cy, "#FFFFFF")
    elif weather == "⛅ 多云":
        for cx, cy in [(120, 50), (300, 70), (500, 40), (700, 80), (800, 55)]:
            draw_cloud(cx, cy, "#CCCCCC")
    elif weather in ("🌧️ 雨天", "⛈️ 雷暴"):
        for cx, cy in [(100, 45), (280, 65), (450, 50), (650, 75), (780, 55)]:
            draw_cloud(cx, cy, "#888888")
        # 雨线
        for _ in range(60):
            rx = random.randint(0, WIDTH)
            ry = random.randint(HEIGHT // 2 - 80, HEIGHT // 2 - 10)
            main_canvas.create_line(rx, ry, rx - 3, ry + 10,
                                    fill="#64B5F6", width=1, tags="sky")
        if weather == "⛈️ 雷暴":
            lx = random.randint(200, WIDTH - 200)
            ly = random.randint(30, 80)
            pts = [lx, ly]
            for _ in range(5):
                lx += random.randint(-15, 15)
                ly += random.randint(15, 30)
                pts.extend([lx, ly])
            main_canvas.create_line(*pts, fill="#FFF176", width=3, tags="sky")

def draw_cloud(cx, cy, color):
    for dx, dy, r in [(0, 0, 22), (-18, 4, 16), (18, 4, 16), (-35, 8, 12), (35, 8, 12)]:
        main_canvas.create_oval(cx + dx, cy + dy, cx + dx + r * 2, cy + dy + r * 2,
                                fill=color, outline="", tags="sky")

# ========================
# 绘制港口
# ========================
def draw_port(screen_x, screen_y):
    # 码头
    main_canvas.create_rectangle(screen_x - 40, screen_y - 5, screen_x + 40, screen_y + 15,
                                 fill="#795548", outline="#5D4037", width=2, tags="world")
    # 灯塔
    lx = screen_x + 50
    ly = screen_y - 40
    main_canvas.create_rectangle(lx - 6, ly, lx + 6, ly + 50,
                                 fill="#FFFFFF", outline="#333333", width=1, tags="world")
    main_canvas.create_polygon(lx - 10, ly, lx + 10, ly, lx, ly - 15,
                                fill="#FF5252", outline="", tags="world")
    # 灯光
    if time_of_day == "night":
        main_canvas.create_oval(lx - 20, ly - 30, lx + 20, ly - 10,
                                fill="#FFD600", outline="", tags="world")
    # 旗帜
    main_canvas.create_line(screen_x - 50, screen_y - 5, screen_x - 50, screen_y - 35,
                            fill="#333333", width=2, tags="world")
    main_canvas.create_polygon(screen_x - 50, screen_y - 35, screen_x - 65, screen_y - 28,
                                screen_x - 50, screen_y - 21,
                                fill="#FF1744", outline="", tags="world")

# ========================
# 绘制船只（俯视）
# ========================
def draw_ship(sx, sy, heading, color="#D32F2F", is_player=False):
    # 船体（菱形）
    length = 28
    width = 12
    cos_h = math.cos(heading)
    sin_h = math.sin(heading)

    # 四个角
    bow = (sx + cos_h * length, sy + sin_h * length)
    stern = (sx - cos_h * length * 0.8, sy - sin_h * length * 0.8)
    port = (sx + sin_h * width, sy - cos_h * width)
    stbd = (sx - sin_h * width, sy + cos_h * width)

    main_canvas.create_polygon(
        bow[0], bow[1],
        stbd[0], stbd[1],
        stern[0], stern[1],
        port[0], port[1],
        fill=color, outline="#212121", width=2, tags="world"
    )

    # 船头三角（船首旗）
    nose_x = sx + cos_h * (length + 4)
    nose_y = sy + sin_h * (length + 4)
    side1_x = sx + cos_h * length + sin_h * 6
    side1_y = sy + sin_h * length - cos_h * 6
    side2_x = sx + cos_h * length - sin_h * 6
    side2_y = sy + sin_h * length + cos_h * 6
    flag_color = "#FFD600" if is_player else "#FFFFFF"
    main_canvas.create_polygon(nose_x, nose_y, side1_x, side1_y, side2_x, side2_y,
                                fill=flag_color, outline="", tags="world")

    # 桅杆 + 帆
    if sail_raised or not is_player:
        mast_x = sx + cos_h * 5
        mast_y = sy + sin_h * 5
        sail_w = 8
        main_canvas.create_line(mast_x, mast_y - 15, mast_x, mast_y + 5,
                                fill="#5D4037", width=2, tags="world")
        # 帆（三角形）
        sail_tip = (mast_x + cos_h * sail_w, mast_y + sin_h * sail_w - 5)
        main_canvas.create_polygon(
            mast_x, mast_y - 15,
            sail_tip[0], sail_tip[1],
            mast_x, mast_y + 2,
            fill="#FFF8E1" if is_player else "#E8EAF6", outline="#999999", width=1, tags="world"
        )

    # 玩家标记
    if is_player:
        main_canvas.create_oval(sx - 3, sy - 3, sx + 3, sy + 3,
                                 fill="#FFD600", outline="", tags="world")

# ========================
# 绘制浮标
# ========================
def draw_buoy(sx, sy, collected):
    if collected:
        return
    main_canvas.create_oval(sx - 8, sy - 8, sx + 8, sy + 8,
                             fill="#FF6F00", outline="#E65100", width=2, tags="world")
    main_canvas.create_polygon(sx, sy - 14, sx - 4, sy - 8, sx + 4, sy - 8,
                                fill="#FF6F00", outline="", tags="world")

# ========================
# 绘制货物箱
# ========================
def draw_cargo(sx, sy, collected):
    if collected:
        return
    main_canvas.create_rectangle(sx - 8, sy - 8, sx + 8, sy + 8,
                                  fill="#FFAB00", outline="#FF6F00", width=2, tags="world")
    main_canvas.create_line(sx - 8, sy, sx + 8, sy, fill="#FF6F00", width=1, tags="world")
    main_canvas.create_line(sx, sy - 8, sx, sy + 8, fill="#FF6F00", width=1, tags="world")

# ========================
# 绘制暗礁
# ========================
def draw_rock(sx, sy, radius):
    main_canvas.create_oval(sx - radius, sy - radius * 0.6,
                             sx + radius, sy + radius * 0.6,
                             fill="#616161", outline="#424242", width=2, tags="world")
    # 锯齿顶部
    pts = []
    for i in range(5):
        ax = sx - radius + i * radius * 0.5
        ay = sy - radius * 0.6 - random.uniform(2, 8)
        pts.extend([ax, ay])
    if len(pts) >= 4:
        main_canvas.create_polygon(sx - radius, sy - radius * 0.6, *pts,
                                    sx + radius, sy - radius * 0.6,
                                    fill="#757575", outline="", tags="world")

# ========================
# 绘制罗盘/航向指示器
# ========================
def draw_compass():
    cx, cy, r = WIDTH - 70, 70, 50
    main_canvas.create_oval(cx - r, cy - r, cx + r, cy + r,
                             fill="#212121", outline="#FFD600", width=2, tags="hud")
    # 刻度
    for i in range(36):
        angle = i * 10 * math.pi / 180
        x1 = cx + (r - 5) * math.sin(angle)
        y1 = cy - (r - 5) * math.cos(angle)
        x2 = cx + r * math.sin(angle)
        y2 = cy - r * math.cos(angle)
        main_canvas.create_line(x1, y1, x2, y2, fill="#FFD600", width=1, tags="hud")
    # N/S/E/W
    for label, angle_deg in [("N", 0), ("E", 90), ("S", 180), ("W", 270)]:
        a = angle_deg * math.pi / 180
        lx = cx + (r - 18) * math.sin(a)
        ly = cy - (r - 18) * math.cos(a)
        main_canvas.create_text(lx, ly, text=label, fill="#FFD600",
                                font=("Consolas", 9, "bold"), tags="hud")
    # 船头指针（相对航向）
    ptr_angle = ship_heading
    px = cx + (r - 10) * math.sin(ptr_angle)
    py = cy - (r - 10) * math.cos(ptr_angle)
    main_canvas.create_line(cx, cy, px, py, fill="#FF5252", width=3, tags="hud")
    main_canvas.create_oval(cx - 4, cy - 4, cx + 4, cy + 4,
                             fill="#FF5252", outline="", tags="hud")

# ========================
# 绘制小地图
# ========================
def draw_minimap():
    mx, my, mr = 80, HEIGHT - 80, 60
    main_canvas.create_oval(mx - mr, my - mr, mx + mr, my + mr,
                             fill="#0D47A1", outline="#FFD600", width=2, tags="hud")
    # 港口（中心）
    main_canvas.create_rectangle(mx - 3, my - 3, mx + 3, my + 3,
                                  fill="#FFD600", outline="", tags="hud")
    # 浮标
    for bx, by, collected in buoys:
        if collected:
            continue
        dx = (bx - ship_x) / 30
        dy = (by - ship_y) / 30
        if math.sqrt(dx * dx + dy * dy) < mr:
            sx = mx + dx
            sy = my + dy
            main_canvas.create_oval(sx - 2, sy - 2, sx + 2, sy + 2,
                                    fill="#FF6F00", outline="", tags="hud")
    # 暗礁
    for rx, ry, rr in rocks:
        dx = (rx - ship_x) / 30
        dy = (ry - ship_y) / 30
        if math.sqrt(dx * dx + dy * dy) < mr:
            sx = mx + dx
            sy = my + dy
            main_canvas.create_oval(sx - 2, sy - 2, sx + 2, sy + 2,
                                    fill="#FF5252", outline="", tags="hud")
    # 玩家船头方向
    px = mx + mr * 0.7 * math.sin(ship_heading)
    py = my - mr * 0.7 * math.cos(ship_heading)
    main_canvas.create_line(mx, my, px, py, fill="#FFFFFF", width=2, tags="hud")

# ========================
# 绘制 HUD
# ========================
def draw_hud():
    main_canvas.delete("hud")

    # 速度（节）
    spd_txt = f"⚓ {ship_speed:.1f} kn"
    main_canvas.create_text(WIDTH // 2, HEIGHT - 80, text=spd_txt,
                            fill="#00E5FF", font=("Consolas", 14, "bold"), tags="hud")

    # 航向
    hdg_deg = int(math.degrees(ship_heading) % 360)
    main_canvas.create_text(WIDTH // 2, HEIGHT - 55, text=f"HDG: {hdg_deg}°",
                            fill="#FFD600", font=("Consolas", 11), tags="hud")

    # 坐标
    main_canvas.create_text(WIDTH // 2, HEIGHT - 35, text=f"LAT: {ship_y/100:.2f}°  LON: {ship_x/100:.2f}°",
                            fill="#B0BEC5", font=("Consolas", 9), tags="hud")

    # 燃油
    fuel_color = "#FF5252" if fuel < 20 else "#FFD600"
    main_canvas.create_text(120, HEIGHT - 80, text=f"FUEL: {int(fuel)}%",
                            fill=fuel_color, font=("Consolas", 11, "bold"), tags="hud")

    # 耐久
    main_canvas.create_text(120, HEIGHT - 55, text=f"HULL: {int(health)}%",
                            fill="#FF5252" if health < 30 else "#69F0AE",
                            font=("Consolas", 11, "bold"), tags="hud")

    # 货物
    main_canvas.create_text(120, HEIGHT - 35, text=f"CARGO: {cargos}/{max_cargos}",
                            fill="#FFAB00", font=("Consolas", 11, "bold"), tags="hud")

    # 锚 / 帆状态
    anchor_txt = "⚓ DOWN" if anchor_down else "⚓ UP"
    sail_txt = "⛵ RAISED" if sail_raised else "⛵ FURLED"
    main_canvas.create_text(WIDTH - 120, HEIGHT - 80, text=anchor_txt,
                            fill="#FFD600" if anchor_down else "#69F0AE",
                            font=("Consolas", 11, "bold"), tags="hud")
    main_canvas.create_text(WIDTH - 120, HEIGHT - 55, text=sail_txt,
                            fill="#FFD600" if sail_raised else "#B0BEC5",
                            font=("Consolas", 11, "bold"), tags="hud")

    # 时间
    time_txt = f"🕐 Day {day_count}  {int(game_time):02d}:{int((game_time%1)*60):02d}"
    main_canvas.create_text(WIDTH - 120, HEIGHT - 35, text=time_txt,
                            fill="#B0BEC5", font=("Consolas", 10), tags="hud")

    # 罗盘
    draw_compass()
    # 小地图
    draw_minimap()

    # 天气图标
    main_canvas.create_text(280, HEIGHT - 80, text=weather,
                            fill="#B0BEC5", font=("Consolas", 11), tags="hud")

# ========================
# 世界坐标 → 屏幕坐标
# ========================
def world_to_screen(wx, wy):
    dx = wx - ship_x
    dy = wy - ship_y
    # 旋转：船头朝上（屏幕上方 = 船头方向）
    cos_h = math.cos(-ship_heading)
    sin_h = math.sin(-ship_heading)
    rx = dx * cos_h - dy * sin_h
    ry = dx * sin_h + dy * cos_h
    sx = WIDTH // 2 + rx
    sy = HEIGHT // 2 - ry  # 屏幕 Y 向下，世界 Y 向上
    return sx, sy

# ========================
# 绘制世界物体
# ========================
def draw_world_objects():
    main_canvas.delete("world")

    # 港口
    psx, psy = world_to_screen(port_pos[0], port_pos[1])
    if -100 < psx < WIDTH + 100 and -100 < psy < HEIGHT + 100:
        draw_port(psx, psy)

    # 暗礁
    for rx, ry, rr in rocks:
        sx, sy = world_to_screen(rx, ry)
        if -100 < sx < WIDTH + 100 and -100 < sy < HEIGHT + 100:
            draw_rock(sx, sy, min(rr, 30))

    # 浮标
    for bx, by, collected in buoys:
        if collected:
            continue
        sx, sy = world_to_screen(bx, by)
        if -50 < sx < WIDTH + 50 and -50 < sy < HEIGHT + 50:
            draw_buoy(sx, sy, collected)

    # 货物
    for cx, cy, collected in cargo_boxes:
        if collected:
            continue
        sx, sy = world_to_screen(cx, cy)
        if -50 < sx < WIDTH + 50 and -50 < sy < HEIGHT + 50:
            draw_cargo(sx, sy, collected)

    # AI 船只
    for ax, ay, ah, asp, ac in ships_ai:
        sx, sy = world_to_screen(ax, ay)
        if -50 < sx < WIDTH + 50 and -50 < sy < HEIGHT + 50:
            draw_ship(sx, sy, ah + ship_heading, color=ac, is_player=False)

    # 玩家船
    draw_ship(WIDTH // 2, HEIGHT // 2, 0, color="#D32F2F", is_player=True)

# ========================
# 场景总绘制
# ========================
def draw_scene():
    draw_sky()
    draw_water()
    draw_world_objects()
    draw_hud()

# ========================
# 物理更新（✅ global 全部锁死）
# ========================
def update_physics(dt):
    global ship_x, ship_y, ship_heading, ship_speed, ship_rudder
    global throttle, fuel, health, cargos, anchor_down, sail_raised
    global weather, time_of_day, game_time, day_count
    global score, combo, mission_step, message_timer
    global buoys, cargo_boxes, rocks, ships_ai

    if health <= 0:
        return

    # 时间推进
    game_time += dt * 0.5
    if game_time >= 24:
        game_time -= 24
        day_count += 1
    if 6 <= game_time < 18:
        time_of_day = "day"
    elif 18 <= game_time < 20:
        time_of_day = "dusk"
    elif 20 <= game_time or game_time < 4:
        time_of_day = "night"
    else:
        time_of_day = "dawn"

    # 天气影响
    wind_factor = 1.0
    if weather == "⛈️ 雷暴":
        wind_factor = 0.5
    elif weather == "🌧️ 雨天":
        wind_factor = 0.7
    elif weather == "⛅ 多云":
        wind_factor = 0.9

    # 锚定：不能移动
    if anchor_down:
        ship_speed *= 0.95
        fuel -= throttle * 0.005 * dt * FPS
    else:
        # 舵效：速度越高转向越快
        ship_heading += ship_rudder * (ship_speed / 10.0) * dt * wind_factor

        # 目标速度
        target_speed = throttle * 12.0 * wind_factor
        if not sail_raised:
            target_speed *= 0.3

        # 加速/减速
        ship_speed += (target_speed - ship_speed) * 0.5 * dt

        # 燃油消耗
        fuel -= throttle * 0.015 * dt * FPS
        if fuel <= 0:
            fuel = 0
            throttle = 0

    # 前进
    ship_x += ship_speed * math.cos(ship_heading) * dt * 5
    ship_y += ship_speed * math.sin(ship_heading) * dt * 5

    # AI 船只移动
    for i in range(len(ships_ai)):
        ships_ai[i][0] += math.cos(ships_ai[i][2]) * ships_ai[i][3] * dt * 5
        ships_ai[i][1] += math.sin(ships_ai[i][2]) * ships_ai[i][3] * dt * 5
        # 简单避障：靠近暗礁就转向
        for rx, ry, rr in rocks:
            dist = math.sqrt((ships_ai[i][0] - rx) ** 2 + (ships_ai[i][1] - ry) ** 2)
            if dist < rr + 30:
                ships_ai[i][2] += 0.3 * dt
                break

    # 碰撞检测
    # 浮标收集
    for i in range(len(buoys)):
        if not buoys[i][2]:
            dist = math.sqrt((ship_x - buoys[i][0]) ** 2 + (ship_y - buoys[i][1]) ** 2)
            if dist < 30:
                buoys[i][2] = True
                score += 100 * (combo + 1)
                combo += 1
                show_message(f"🚩 浮标通过！+{100 * combo}")
                if mission_step == 1:
                    mission_step = 2
                    score += 500

    # 货物收集
    for i in range(len(cargo_boxes)):
        if not cargo_boxes[i][2]:
            dist = math.sqrt((ship_x - cargo_boxes[i][0]) ** 2 + (ship_y - cargo_boxes[i][1]) ** 2)
            if dist < 25 and cargos < max_cargos:
                cargo_boxes[i][2] = True
                cargos += 1
                score += 200
                show_message(f"📦 货物已装载！({cargos}/{max_cargos})")
                if mission_step == 2 and cargos >= 3:
                    mission_step = 3
                    score += 500

    # 暗礁碰撞
    for rx, ry, rr in rocks:
        dist = math.sqrt((ship_x - rx) ** 2 + (ship_y - ry) ** 2)
        if dist < rr + 8:
            health -= 15 * dt * FPS
            ship_speed *= 0.8
            show_message("💥 撞上暗礁！船体受损！")
            break

    # AI 船只碰撞
    for ax, ay, ah, asp, ac in ships_ai:
        dist = math.sqrt((ship_x - ax) ** 2 + (ship_y - ay) ** 2)
        if dist < 25:
            health -= 5 * dt * FPS
            ship_speed *= 0.9
            show_message("⚠ 与船只碰撞！")
            break

    # 港口靠岸检测
    port_dist = math.sqrt((ship_x - port_pos[0]) ** 2 + (ship_y - port_pos[1]) ** 2)
    if port_dist < 60:
        if ship_speed < 2 and anchor_down:
            if mission_step == 3:
                mission_step = 4
                score += 500
                show_message("🏆 成功靠港！任务完成！")
            elif cargos > 0:
                score += cargos * 300
                show_message(f"📦 卸货完成！+{cargos * 300}")
                cargos = 0

    # 任务检测
    if mission_step == 0 and not anchor_down and ship_speed > 1:
        mission_step = 1
        score += 500
        show_message("⚓ 出港成功！驶向浮标！")
    if mission_step == 4 and cargos == 0:
        mission_step = 5
        score += 1000
        show_message("🎉 所有任务完成！")

    # 消息计时
    if message_timer > 0:
        message_timer -= dt

# ========================
# 游戏循环
# ========================
def game_loop():
    dt = 1.0 / FPS
    update_physics(dt)
    draw_scene()

    # 信息面板
    info_label.config(text=f"⚓ {score} pts | 连击 x{combo} | 距港口 {int(math.sqrt(ship_x**2 + ship_y**2))}m")
    task_label.config(text=missions[min(mission_step, len(missions)-1)] if health > 0 else "💀 船体沉没")
    msg_label.config(text=message if message_timer > 0 else "")

    if health <= 0:
        main_canvas.create_text(WIDTH // 2, HEIGHT // 2, text="💀 船体沉没",
                                fill="#FF0000", font=("Consolas", 36, "bold"))
        main_canvas.create_text(WIDTH // 2, HEIGHT // 2 + 50, text="按 R 重新开始",
                                fill="#FFFFFF", font=("Consolas", 16))

    root.after(int(1000 / FPS), game_loop)

# ========================
# 键盘控制
# ========================
def key_down(e):
    global ship_rudder, throttle, anchor_down, sail_raised
    global health, score, mission_step, combo, fuel
    global ship_x, ship_y, ship_heading, ship_speed
    global buoys, cargo_boxes, rocks, ships_ai, port_pos, day_count, game_time

    if health <= 0:
        if e.keysym == "r":
            health = 100
            fuel = 100
            cargos = 0
            combo = 0
            score = 0
            mission_step = 0
            ship_x = ship_y = 0
            ship_heading = 0
            ship_speed = 0
            throttle = 0.5
            anchor_down = False
            sail_raised = True
            generate_world()
            show_message("🔄 新航程开始！")
        return

    if e.keysym in ("a", "Left"):
        ship_rudder = -1
    if e.keysym in ("d", "Right"):
        ship_rudder = 1
    if e.keysym in ("w", "Up"):
        throttle = min(1.0, throttle + 0.05)
    if e.keysym in ("s", "Down"):
        throttle = max(0.0, throttle - 0.05)
    if e.keysym == "space":
        anchor_down = not anchor_down
        show_message("⚓ 锚已" + ("放下" if anchor_down else "收起"))
    if e.keysym == "f":
        sail_raised = not sail_raised
        show_message("⛵ 帆已" + ("升起" if sail_raised else "收起"))
    if e.keysym == "r":
        health = 100
        fuel = 100
        cargos = 0
        combo = 0
        score = 0
        mission_step = 0
        ship_x = ship_y = 0
        ship_heading = 0
        ship_speed = 0
        throttle = 0.5
        anchor_down = False
        sail_raised = True
        generate_world()
        show_message("🔄 重新出发！")

def key_up(e):
    global ship_rudder
    if e.keysym in ("a", "d", "Left", "Right"):
        ship_rudder = 0

root.bind("<KeyPress>", key_down)
root.bind("<KeyRelease>", key_up)

# ========================
# 天气 / 时间按钮
# ========================
for w in ["☀️ 晴天", "⛅ 多云", "🌧️ 雨天", "⛈️ 雷暴", "🌫️ 大雾"]:
    tk.Button(panel, text=w, font=("Comic Sans MS", 8),
              command=lambda w=w: globals().update(weather=w)).pack(side="left", padx=2)

# ========================
# 换肤按钮
# ========================
for name in themes:
    tk.Button(panel, text=name, font=("Comic Sans MS", 8),
              command=lambda n=name: apply_theme(n)).pack(side="right", padx=2)

# ========================
# 启动
# ========================
show_message("⚓ 欢迎登船！按 SPACE 收锚，W/S 控制油门，A/D 掌舵")
apply_theme("🌊 经典海洋")
game_loop()
root.mainloop()
