import pygame
import sys
import math
import random
from datetime import datetime

# 初始化pygame
pygame.init()

# 屏幕设置
WIDTH, HEIGHT = 1000, 700
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("火箭发射台模拟系统 - 817班 奚悠然")

# 颜色定义
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 50, 50)
ORANGE = (255, 150, 50)
YELLOW = (255, 255, 100)
BLUE = (50, 100, 255)
LIGHT_BLUE = (100, 150, 255)
GRAY = (100, 100, 100)
DARK_GRAY = (50, 50, 50)
GREEN = (50, 200, 50)
LIGHT_GRAY = (200, 200, 200)
BROWN = (150, 100, 50)
DARK_BROWN = (100, 70, 30)
SKY_BLUE = (135, 206, 235)
NIGHT_BLUE = (10, 20, 40)
STAR_YELLOW = (255, 255, 200)

# 字体
title_font = pygame.font.SysFont("microsoftyahei", 40, bold=True)
font_large = pygame.font.SysFont("microsoftyahei", 28)
font_medium = pygame.font.SysFont("microsoftyahei", 24)
font_small = pygame.font.SysFont("microsoftyahei", 20)
font_tiny = pygame.font.SysFont("microsoftyahei", 16)

# 火箭状态
class Rocket:
    def __init__(self):
        self.height = 300
        self.fuel = 100.0
        self.oxygen = 100.0
        self.temperature = 20.0
        self.pressure = 1.0
        self.velocity = 0.0
        self.altitude = 0.0
        self.engine_power = 0.0
        self.launched = False
        self.stage = 1
        self.countdown = 10.0
        self.counting = False
        self.launch_time = None
        self.flame_particles = []
        self.smoke_particles = []
        self.stars = []
        self.night_mode = False
        self.day_night_cycle = 0
        self.create_stars()
        
    def create_stars(self):
        self.stars = []
        for _ in range(100):
            x = random.randint(0, WIDTH)
            y = random.randint(0, HEIGHT//2)
            size = random.uniform(0.5, 2.0)
            brightness = random.uniform(0.5, 1.0)
            self.stars.append((x, y, size, brightness))
    
    def update(self, dt):
        # 日夜循环
        self.day_night_cycle += dt * 0.05
        if self.day_night_cycle >= 2 * math.pi:
            self.day_night_cycle -= 2 * math.pi
        
        # 根据日夜循环计算天空颜色
        day_factor = (math.sin(self.day_night_cycle) + 1) / 2
        if day_factor > 0.7:
            self.night_mode = False
        elif day_factor < 0.3:
            self.night_mode = True
        
        # 倒计时
        if self.counting and not self.launched:
            self.countdown -= dt
            if self.countdown <= 0:
                self.launch()
                self.launch_time = datetime.now()
        
        # 火箭飞行物理模拟
        if self.launched:
            # 燃料消耗
            fuel_consumption = self.engine_power * 0.5
            self.fuel = max(0, self.fuel - fuel_consumption * dt)
            
            # 氧气消耗
            oxygen_consumption = self.engine_power * 0.3
            self.oxygen = max(0, self.oxygen - oxygen_consumption * dt)
            
            # 温度变化
            temp_change = self.engine_power * 10 - 2
            self.temperature += temp_change * dt
            
            # 压力变化
            pressure_change = (self.altitude / 10000) * 0.1
            self.pressure = max(0.1, 1.0 - pressure_change)
            
            # 速度和高度计算
            thrust = self.engine_power * 1000
            gravity = 9.81
            drag = 0.01 * self.velocity**2
            
            acceleration = (thrust - gravity - drag) / 100
            self.velocity += acceleration * dt
            self.altitude += self.velocity * dt
            
            # 分级分离
            if self.stage == 1 and self.altitude > 5000 and self.fuel < 30:
                self.stage = 2
                self.fuel = 80.0
                self.oxygen = 80.0
            
            # 发动机关闭
            if self.fuel <= 0 or self.oxygen <= 0:
                self.engine_power = 0
            
            # 火焰粒子效果
            if self.engine_power > 0:
                for _ in range(int(self.engine_power * 5)):
                    particle_x = WIDTH//2 + random.randint(-10, 10)
                    particle_y = HEIGHT - 100 - self.height + random.randint(-5, 5)
                    speed = random.uniform(2, 5) * self.engine_power
                    size = random.uniform(2, 5)
                    life = random.uniform(0.5, 1.5)
                    self.flame_particles.append([particle_x, particle_y, speed, size, life])
                    
                for _ in range(int(self.engine_power * 3)):
                    particle_x = WIDTH//2 + random.randint(-20, 20)
                    particle_y = HEIGHT - 100 - self.height + random.randint(-10, 10)
                    speed = random.uniform(0.5, 1.5) * self.engine_power
                    size = random.uniform(3, 8)
                    life = random.uniform(1, 3)
                    self.smoke_particles.append([particle_x, particle_y, speed, size, life])
        
        # 更新粒子
        for particle in self.flame_particles[:]:
            particle[1] += particle[2] * 10
            particle[4] -= dt
            if particle[4] <= 0:
                self.flame_particles.remove(particle)
        
        for particle in self.smoke_particles[:]:
            particle[1] += particle[2] * 5
            particle[3] += 0.1
            particle[4] -= dt
            if particle[4] <= 0:
                self.smoke_particles.remove(particle)
    
    def launch(self):
        self.launched = True
        self.engine_power = 1.0
    
    def increase_power(self):
        if self.launched and self.fuel > 0 and self.oxygen > 0:
            self.engine_power = min(1.5, self.engine_power + 0.1)
    
    def decrease_power(self):
        if self.launched:
            self.engine_power = max(0, self.engine_power - 0.1)
    
    def start_countdown(self):
        if not self.launched:
            self.counting = True
    
    def reset(self):
        self.__init__()
    
    def get_sky_color(self):
        if self.night_mode:
            return NIGHT_BLUE
        else:
            # 根据日夜循环计算天空颜色
            day_factor = (math.sin(self.day_night_cycle) + 1) / 2
            r = int(135 * day_factor + 10 * (1 - day_factor))
            g = int(206 * day_factor + 20 * (1 - day_factor))
            b = int(235 * day_factor + 40 * (1 - day_factor))
            return (r, g, b)

# 创建火箭实例
rocket = Rocket()

# 按钮类
class Button:
    def __init__(self, x, y, width, height, text, color, hover_color):
        self.rect = pygame.Rect(x, y, width, height)
        self.text = text
        self.color = color
        self.hover_color = hover_color
        self.current_color = color
        self.hovered = False
    
    def draw(self, surface):
        pygame.draw.rect(surface, self.current_color, self.rect, border_radius=8)
        pygame.draw.rect(surface, WHITE, self.rect, 2, border_radius=8)
        
        text_surf = font_medium.render(self.text, True, WHITE)
        text_rect = text_surf.get_rect(center=self.rect.center)
        surface.blit(text_surf, text_rect)
    
    def check_hover(self, pos):
        self.hovered = self.rect.collidepoint(pos)
        self.current_color = self.hover_color if self.hovered else self.color
        return self.hovered
    
    def is_clicked(self, pos, event):
        if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
            return self.rect.collidepoint(pos)
        return False

# 创建按钮
buttons = [
    Button(50, 600, 150, 50, "启动倒计时", GREEN, (30, 180, 30)),
    Button(220, 600, 150, 50, "增大推力", ORANGE, (220, 120, 30)),
    Button(390, 600, 150, 50, "减小推力", RED, (200, 50, 30)),
    Button(560, 600, 150, 50, "重置系统", BLUE, (40, 90, 220)),
    Button(730, 600, 150, 50, "日夜切换", DARK_GRAY, (70, 70, 70))
]

# 仪表盘类
class Gauge:
    def __init__(self, x, y, label, unit, min_val, max_val):
        self.x = x
        self.y = y
        self.label = label
        self.unit = unit
        self.min_val = min_val
        self.max_val = max_val
    
    def draw(self, surface, value, color):
        # 绘制仪表背景
        pygame.draw.rect(surface, DARK_GRAY, (self.x, self.y, 200, 100), border_radius=10)
        pygame.draw.rect(surface, LIGHT_GRAY, (self.x, self.y, 200, 100), 2, border_radius=10)
        
        # 绘制标签
        label_surf = font_small.render(self.label, True, WHITE)
        surface.blit(label_surf, (self.x + 10, self.y + 10))
        
        # 绘制数值
        value_text = f"{value:.1f} {self.unit}"
        value_surf = font_medium.render(value_text, True, color)
        surface.blit(value_surf, (self.x + 100 - value_surf.get_width()//2, self.y + 40))
        
        # 绘制进度条
        bar_width = 180
        bar_height = 15
        bar_x = self.x + 10
        bar_y = self.y + 75
        
        # 背景条
        pygame.draw.rect(surface, BLACK, (bar_x, bar_y, bar_width, bar_height))
        
        # 前景条
        fill_width = (value - self.min_val) / (self.max_val - self.min_val) * bar_width
        fill_width = max(0, min(fill_width, bar_width))
        pygame.draw.rect(surface, color, (bar_x, bar_y, fill_width, bar_height))

# 创建仪表盘
gauges = [
    Gauge(50, 120, "燃料", "%", 0, 100),
    Gauge(280, 120, "氧气", "%", 0, 100),
    Gauge(510, 120, "温度", "°C", 0, 200),
    Gauge(740, 120, "压力", "atm", 0, 2),
    Gauge(50, 250, "速度", "m/s", 0, 1000),
    Gauge(280, 250, "高度", "km", 0, 100),
    Gauge(510, 250, "发动机功率", "%", 0, 150),
    Gauge(740, 250, "飞行阶段", "", 1, 2)
]

# 主循环
clock = pygame.time.Clock()
running = True

while running:
    dt = clock.tick(60) / 1000.0  # 转换为秒
    mouse_pos = pygame.mouse.get_pos()
    
    # 处理事件
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        
        # 检查按钮点击
        for button in buttons:
            if button.is_clicked(mouse_pos, event):
                if button.text == "启动倒计时":
                    rocket.start_countdown()
                elif button.text == "增大推力":
                    rocket.increase_power()
                elif button.text == "减小推力":
                    rocket.decrease_power()
                elif button.text == "重置系统":
                    rocket.reset()
                elif button.text == "日夜切换":
                    rocket.night_mode = not rocket.night_mode
                    rocket.day_night_cycle = math.pi if rocket.night_mode else 0
        
        # 键盘控制
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE and not rocket.launched:
                rocket.start_countdown()
            elif event.key == pygame.K_UP and rocket.launched:
                rocket.increase_power()
            elif event.key == pygame.K_DOWN and rocket.launched:
                rocket.decrease_power()
            elif event.key == pygame.K_r:
                rocket.reset()
            elif event.key == pygame.K_n:
                rocket.night_mode = not rocket.night_mode
                rocket.day_night_cycle = math.pi if rocket.night_mode else 0
    
    # 更新火箭状态
    rocket.update(dt)
    
    # 更新按钮悬停状态
    for button in buttons:
        button.check_hover(mouse_pos)
    
    # 绘制背景
    sky_color = rocket.get_sky_color()
    screen.fill(sky_color)
    
    # 绘制星星（夜晚模式）
    if rocket.night_mode:
        for star in rocket.stars:
            x, y, size, brightness = star
            color = (int(STAR_YELLOW[0] * brightness), 
                    int(STAR_YELLOW[1] * brightness), 
                    int(STAR_YELLOW[2] * brightness))
            pygame.draw.circle(screen, color, (x, y), size)
    
    # 绘制地平线
    pygame.draw.rect(screen, DARK_BROWN, (0, HEIGHT-150, WIDTH, 150))
    
    # 绘制标题栏
    pygame.draw.rect(screen, DARK_GRAY, (0, 0, WIDTH, 80))
    title = title_font.render("火箭发射台模拟系统 -实验中学 817班 奚悠然", True, YELLOW)
    screen.blit(title, (WIDTH//2 - title.get_width()//2, 10))
    
    # 绘制信息栏
    info_rect = pygame.Rect(0, HEIGHT-230, WIDTH, 80)
    pygame.draw.rect(screen, (30, 30, 50), info_rect)
    pygame.draw.rect(screen, BLUE, info_rect, 2)
    
    # 状态信息
    status_text = "准备发射" if not rocket.launched else f"飞行中 - 阶段 {rocket.stage}"
    status_color = GREEN if not rocket.launched else YELLOW
    status_surf = font_large.render(f"状态: {status_text}", True, status_color)
    screen.blit(status_surf, (20, HEIGHT-210))
    
    # 倒计时/飞行时间
    if rocket.counting and not rocket.launched:
        time_text = f"倒计时: {rocket.countdown:.1f} 秒"
    elif rocket.launched and rocket.launch_time:
        flight_time = (datetime.now() - rocket.launch_time).total_seconds()
        time_text = f"飞行时间: {flight_time:.1f} 秒"
    else:
        time_text = "等待发射指令"
    
    time_surf = font_medium.render(time_text, True, LIGHT_BLUE)
    screen.blit(time_surf, (20, HEIGHT-170))
    
    # 控制提示
    controls = "空格:启动倒计时  ↑:增大推力  ↓:减小推力  R:重置  N:日夜切换"
    controls_surf = font_tiny.render(controls, True, LIGHT_GRAY)
    screen.blit(controls_surf, (WIDTH//2 - controls_surf.get_width()//2, HEIGHT-140))
    
    # 绘制发射台
    launch_pad_y = HEIGHT - 150
    launch_pad_width = 200
    launch_pad_height = 20
    
    # 发射台底座
    pygame.draw.rect(screen, GRAY, (WIDTH//2 - launch_pad_width//2, launch_pad_y, launch_pad_width, launch_pad_height))
    
    # 发射台支架
    for i in range(-2, 3):
        if i == 0:
            continue
        x_offset = i * 40
        pygame.draw.polygon(screen, DARK_GRAY, [
            (WIDTH//2 + x_offset - 10, launch_pad_y),
            (WIDTH//2 + x_offset + 10, launch_pad_y),
            (WIDTH//2 + x_offset, launch_pad_y - 100)
        ])
    
    # 绘制火箭
    rocket_width = 30
    rocket_x = WIDTH//2
    rocket_y = launch_pad_y - rocket.height
    
    # 火箭主体
    rocket_body = [
        (rocket_x, rocket_y),
        (rocket_x - rocket_width, rocket_y + rocket.height - 50),
        (rocket_x - rocket_width//2, rocket_y + rocket.height),
        (rocket_x + rocket_width//2, rocket_y + rocket.height),
        (rocket_x + rocket_width, rocket_y + rocket.height - 50)
    ]
    
    # 火箭颜色（根据温度变化）
    temp_factor = min(1.0, rocket.temperature / 100)
    rocket_color = (
        int(200 + 55 * temp_factor),
        int(200 - 100 * temp_factor),
        int(200 - 200 * temp_factor)
    )
    
    pygame.draw.polygon(screen, rocket_color, rocket_body)
    
    # 火箭装饰
    pygame.draw.polygon(screen, RED, [
        (rocket_x, rocket_y),
        (rocket_x - 20, rocket_y + 40),
        (rocket_x + 20, rocket_y + 40)
    ])
    
    # 火箭窗口
    pygame.draw.circle(screen, LIGHT_BLUE, (rocket_x, rocket_y + 100), 15)
    
    # 火箭分级标识
    if rocket.stage == 1:
        stage_color = ORANGE
    else:
        stage_color = GREEN
    
    pygame.draw.rect(screen, stage_color, (rocket_x - 25, rocket_y + rocket.height - 40, 50, 10))
    
    # 绘制火焰
    if rocket.engine_power > 0:
        # 火焰粒子
        for particle in rocket.flame_particles:
            x, y, speed, size, life = particle
            alpha = int(255 * life)
            flame_color = (
                random.randint(200, 255),
                random.randint(100, 200),
                random.randint(0, 100)
            )
            
            # 创建临时surface绘制半透明火焰
            flame_surf = pygame.Surface((int(size*2), int(size*2)), pygame.SRCALPHA)
            pygame.draw.circle(flame_surf, (*flame_color, alpha), (int(size), int(size)), int(size))
            screen.blit(flame_surf, (x - size, y - size))
        
        # 主火焰
        flame_height = 50 + rocket.engine_power * 30
        flame_points = [
            (rocket_x - rocket_width//2, rocket_y + rocket.height),
            (rocket_x - 15, rocket_y + rocket.height + flame_height),
            (rocket_x, rocket_y + rocket.height + flame_height + 20),
            (rocket_x + 15, rocket_y + rocket.height + flame_height),
            (rocket_x + rocket_width//2, rocket_y + rocket.height)
        ]
        
        # 火焰颜色渐变
        flame_colors = []
        for i in range(5):
            r = 255
            g = int(100 + 100 * (i/4))
            b = int(50 * (i/4))
            flame_colors.append((r, g, b))
        
        pygame.draw.polygon(screen, YELLOW, flame_points)
        pygame.draw.polygon(screen, ORANGE, flame_points, 2)
    
    # 绘制烟雾粒子
    for particle in rocket.smoke_particles:
        x, y, speed, size, life = particle
        alpha = int(200 * life)
        smoke_color = (150, 150, 150, alpha)
        
        # 创建临时surface绘制半透明烟雾
        smoke_surf = pygame.Surface((int(size*2), int(size*2)), pygame.SRCALPHA)
        pygame.draw.circle(smoke_surf, smoke_color, (int(size), int(size)), int(size))
        screen.blit(smoke_surf, (x - size, y - size))
    
    # 绘制仪表盘
    gauge_values = [
        rocket.fuel,
        rocket.oxygen,
        rocket.temperature,
        rocket.pressure,
        rocket.velocity,
        rocket.altitude / 1000,  # 转换为km
        rocket.engine_power * 100,
        rocket.stage
    ]
    
    gauge_colors = [
        GREEN if rocket.fuel > 20 else RED,
        GREEN if rocket.oxygen > 20 else RED,
        ORANGE if rocket.temperature < 100 else RED,
        GREEN if rocket.pressure > 0.5 else RED,
        BLUE,
        LIGHT_BLUE,
        YELLOW if rocket.engine_power < 100 else RED,
        GREEN if rocket.stage == 2 else ORANGE
    ]
    
    for i, gauge in enumerate(gauges):
        gauge.draw(screen, gauge_values[i], gauge_colors[i])
    
    # 绘制按钮
    for button in buttons:
        button.draw(screen)
    
    # 更新显示
    pygame.display.flip()

# 退出游戏
pygame.quit()
sys.exit()