import tkinter as tk
import math
import random

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

# ========================
# 火箭状态（✅ 全部提前定义）
# ========================
x = WIDTH // 2
y = HEIGHT - 80
vx = 0
vy = 0
thrust = 0.0
fuel = 100.0
altitude = 0.0
speed = 0.0
g_force = 1.0
heat = 0.0
stage = 0
score = 0
game_over = False
paused = False

# 碎片
debris = []

# 消息
messages = []

# ========================
# Tkinter
# ========================
root = tk.Tk()
root.title("🚀 火箭发射模拟器 · 终极封死版")
root.resizable(False, False)

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

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

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

# ========================
# 主题
# ========================
themes = {
    "🌤️ 经典发射": {"bg": "#87CEEB", "fg": "#000000"},
    "🌙 夜空": {"bg": "#0D1B2A", "fg": "#FFFFFF"},
    "🔥 火星": {"bg": "#8B2500", "fg": "#FFD700"},
    "🌌 深空": {"bg": "#02010A", "fg": "#CCCCCC"},
    "🛰️ 太空站": {"bg": "#1B263B", "fg": "#00FFFF"},
    "🌈 彩虹轨道": {"bg": "#4A148C", "fg": "#FFD600"},
}

def apply_theme(name):
    t = themes[name]
    root.configure(bg=t["bg"])
    panel.configure(bg=t["bg"])
    info.configure(bg=t["bg"], fg=t["fg"])
    canvas.configure(background=t["bg"])

# ========================
# 安全颜色函数（✅ 核心修复）
# ========================
def safe_color(r, g, b):
    r = max(0, min(255, int(r)))
    g = max(0, min(255, int(g)))
    b = max(0, min(255, int(b)))
    return f"#{r:02x}{g:02x}{b:02x}"

# ========================
# 天空背景
# ========================
def draw_sky():
    canvas.delete("sky")
    for i in range(HEIGHT):
        ratio = i / HEIGHT
        if altitude < 5000:
            r = 135 + (30 - 135) * ratio
            g = 206 + (144 - 206) * ratio
            b = 250 + (255 - 250) * ratio
        elif altitude < 50000:
            r = 30
            g = 144
            b = 255
        else:
            r = 0
            g = 0
            b = 0
        canvas.create_line(0, i, WIDTH, i,
                           fill=safe_color(r, g, b), tags="sky")

# ========================
# 火箭
# ========================
def draw_rocket():
    canvas.delete("rocket")
    canvas.create_rectangle(x - 10, y - 40, x + 10, y + 20,
                            fill="#CCCCCC", outline="#666666", width=2, tags="rocket")
    canvas.create_polygon(x - 10, y - 40, x + 10, y - 40, x, y - 70,
                          fill="#FF4444", outline="#990000", tags="rocket")
    canvas.create_rectangle(x - 12, y + 10, x - 6, y + 20,
                            fill="#666666", outline="#333333", tags="rocket")
    canvas.create_rectangle(x + 6, y + 10, x + 12, y + 20,
                            fill="#666666", outline="#333333", tags="rocket")

# ========================
# 喷焰
# ========================
def draw_flame():
    canvas.delete("flame")
    if thrust <= 0:
        return
    for i in range(20):
        fx = x + random.uniform(-6, 6)
        fy = y + 20 + i * 3
        r = 255
        g = 200 - i * 8
        b = 50 - i * 2
        canvas.create_oval(fx - 3, fy - 3, fx + 3, fy + 3,
                           fill=safe_color(r, g, b), outline="", tags="flame")

# ========================
# 碎片（一级分离）
# ========================
def draw_debris():
    canvas.delete("debris")
    for d in debris[:]:
        canvas.create_rectangle(d["x"] - 5, d["y"] - 5,
                                d["x"] + 5, d["y"] + 5,
                                fill="#888888", outline="", tags="debris")
        d["x"] += d["vx"]
        d["y"] += d["vy"]
        d["life"] -= 1
        if d["life"] <= 0:
            debris.remove(d)

# ========================
# 仪表
# ========================
def draw_ui():
    canvas.delete("ui")

    # 高度
    canvas.create_text(20, 20, anchor="nw",
                       text=f"高度: {altitude/1000:.1f} km",
                       fill="#FFFFFF", font=("Consolas", 12), tags="ui")

    # 速度
    canvas.create_text(20, 45, anchor="nw",
                       text=f"速度: {speed:.1f} m/s",
                       fill="#FFFFFF", font=("Consolas", 12), tags="ui")

    # 燃油
    fuel_color = "#00FF00" if fuel > 20 else "#FF0000"
    canvas.create_rectangle(20, 70, 220, 90, outline="#FFFFFF", tags="ui")
    canvas.create_rectangle(20, 70, 20 + fuel * 2, 90,
                            fill=fuel_color, outline="", tags="ui")
    canvas.create_text(120, 100, text=f"燃油: {fuel:.0f}%",
                       fill="#FFFFFF", font=("Consolas", 10), tags="ui")

    # 推力
    canvas.create_rectangle(20, 120, 220, 140, outline="#FFFFFF", tags="ui")
    canvas.create_rectangle(20, 120, 20 + thrust * 2, 140,
                            fill="#FFD600", outline="", tags="ui")
    canvas.create_text(120, 150, text=f"推力: {thrust:.0f}%",
                       fill="#FFFFFF", font=("Consolas", 10), tags="ui")

    # G力
    g_color = "#FF0000" if g_force > 5 else "#FFFFFF"
    canvas.create_text(WIDTH - 20, 20, anchor="ne",
                       text=f"G力: {g_force:.1f}G",
                       fill=g_color, font=("Consolas", 12), tags="ui")

    # 热盾
    heat_color = "#FF0000" if heat > 100 else "#FFD600"
    canvas.create_text(WIDTH - 20, 45, anchor="ne",
                       text=f"热盾: {heat:.0f}°C",
                       fill=heat_color, font=("Consolas", 12), tags="ui")

    # 阶段
    stages = ["🔥 点火升空", "🌤️ 突破对流层", "🚀 突破卡门线",
              "🛰️ 进入轨道", "🎯 对接空间站"]
    canvas.create_text(WIDTH // 2, 20, text=stages[stage],
                       fill="#FFFF00", font=("Consolas", 14, "bold"), tags="ui")

    # 得分
    canvas.create_text(WIDTH - 20, 70, anchor="ne",
                       text=f"得分: {score}",
                       fill="#FFFFFF", font=("Consolas", 12), tags="ui")

# ========================
# 消息（✅ 颜色绝对安全）
# ========================
def draw_messages():
    canvas.delete("msg")
    for i, msg in enumerate(messages[-5:]):
        canvas.create_text(WIDTH // 2, 80 + i * 20,
                           text=msg,
                           fill="#FFFF00",  # ✅ 固定合法颜色
                           font=("Consolas", 10),
                           tags="msg")

# ========================
# 物理更新
# ========================
def update_physics():
    global x, y, vx, vy, thrust, fuel, altitude, speed
    global g_force, heat, stage, score, game_over, debris

    if game_over or paused:
        return

    dt = 1 / FPS

    # 重力（随高度递减）
    gravity = 9.81 * (6371000 / (6371000 + altitude)) ** 2

    # 推力
    thrust_acc = (thrust / 100) * 15

    # 净加速度
    net_acc = thrust_acc - gravity
    g_force = abs(net_acc) / 9.81 + 1

    # 速度 & 位置
    vy -= net_acc * dt
    y += vy * dt * 0.1
    altitude = max(0, (HEIGHT - 80 - y) * 100)

    speed = abs(vy * 10)

    # 燃油消耗
    if thrust > 0:
        fuel -= (thrust / 100) * 2.0 * dt
        if fuel <= 0:
            fuel = 0
            thrust = 0

    # 热盾
    heat += max(0, (speed - 200) * 0.01)
    if heat > 100:
        score -= 10
        heat = 100

    # 一级分离（10km）
    if altitude > 10000 and stage == 0:
        stage = 1
        score += 500
        messages.append("🚀 一级分离！")
        for _ in range(10):
            debris.append({
                "x": x,
                "y": y + 40,
                "vx": random.uniform(-2, 2),
                "vy": random.uniform(1, 3),
                "life": 60
            })

    # 突破卡门线（50km）
    if altitude > 50000 and stage == 1:
        stage = 2
        score += 1000
        messages.append("🌌 突破卡门线！进入太空！")

    # 入轨（2400km）
    if altitude > 2400000 and 300 < speed < 400 and stage == 2:
        stage = 3
        score += 2000
        messages.append("🛰️ 成功进入轨道！")

    # 对接（接近空间站）
    if abs(x - WIDTH // 2) < 5 and 340 < speed < 360 and stage == 3:
        stage = 4
        score += 3000
        messages.append("🎯 对接成功！任务完成！")
        game_over = True

    if fuel <= 0 and altitude < 2400000:
        messages.append("💥 燃料耗尽！任务失败！")
        game_over = True

# ========================
# 场景绘制
# ========================
def draw_scene():
    draw_sky()
    draw_debris()
    draw_flame()
    draw_rocket()
    draw_ui()
    draw_messages()

# ========================
# 游戏循环
# ========================
def game_loop():
    update_physics()
    draw_scene()

    if game_over:
        canvas.create_text(WIDTH // 2, HEIGHT // 2,
                           text="🎉 任务完成！\n按 R 重开",
                           fill="#00FF00",
                           font=("Consolas", 28, "bold"))

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

# ========================
# 控制
# ========================
def key_down(e):
    global thrust, game_over, paused
    global x, y, vy, stage, score, fuel, heat, g_force, debris, messages

    if game_over:
        if e.keysym == "r":
            restart_game()
        return

    if e.keysym in ("space", "w", "Up"):
        thrust = min(100, thrust + 5)
    if e.keysym in ("s", "Down", "x"):
        thrust = max(0, thrust - 5)
    if e.keysym in ("a", "Left"):
        x -= 5
    if e.keysym in ("d", "Right"):
        x += 5
    if e.keysym == "1":
        thrust = 25
    if e.keysym == "2":
        thrust = 50
    if e.keysym == "3":
        thrust = 75
    if e.keysym == "4":
        thrust = 100
    if e.keysym == "p":
        paused = not paused
    if e.keysym == "r":
        restart_game()

def restart_game():
    global x, y, vx, vy, thrust, fuel, altitude, speed
    global g_force, heat, stage, score, game_over, paused
    global debris, messages

    x = WIDTH // 2
    y = HEIGHT - 80
    vx = vy = 0
    thrust = 0
    fuel = 100
    altitude = speed = 0
    g_force = heat = 0
    stage = 0
    score = 0
    game_over = False
    paused = False
    debris.clear()
    messages.clear()
    messages.append("🚀 准备发射！按 Space 点火！")

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

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

# ========================
# 启动
# ========================
apply_theme("🌤️ 经典发射")
messages.append("🚀 准备发射！按 Space 点火！")
game_loop()
root.mainloop()