import pygame
import math
import random

# 初始化Pygame
pygame.init()
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("火箭发射模拟器")
clock = pygame.time.Clock()

# 颜色常量
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GRAY = (80, 80, 80)
RED = (220, 30, 30)
ORANGE = (255, 140, 20)
YELLOW = (255, 220, 0)
BLUE = (60, 140, 255)
GREEN = (40, 200, 80)

# 火箭初始数据
rocket_x = WIDTH // 2
rocket_y = HEIGHT - 120
rocket_speed_y = 0
thrust = 0
max_thrust = 1.2
gravity = 0.12
is_launch = False

# 火焰粒子列表
particles = []

# 随机星空背景
stars = []
for _ in range(220):
    sx = random.randint(0, WIDTH)
    sy = random.randint(0, HEIGHT)
    star_size = random.uniform(0.4, 2.1)
    stars.append([sx, sy, star_size])

# ==========【修复字体代码】==========
# 不使用SysFont，改用安全方式，捕获所有异常
try:
    # 使用系统默认字体名称
    font = pygame.font.SysFont("consolas", 22, bold=False)
    font_big = pygame.font.SysFont("consolas", 30, bold=False)
except Exception:
    # 终极兜底方案：使用默认内置字体，不会触发win32 sysfont bug
    font = pygame.font.Font(None, 22)
    font_big = pygame.font.Font(None, 30)


def create_fire(px, py):
    """生成推进器火焰粒子"""
    for _ in range(6):
        offset_x = random.uniform(-13, 13)
        speed_y = random.uniform(3, 7.2)
        life_time = random.randint(20, 46)
        fire_color = random.choice([ORANGE, YELLOW, RED])
        particles.append([px + offset_x, py, speed_y, life_time, fire_color])


def draw_rocket(x, y):
    """绘制火箭模型"""
    # 箭体主体
    pygame.draw.rect(screen, WHITE, (x - 12, y - 50, 24, 60))
    # 整流罩头锥
    pygame.draw.polygon(screen, WHITE, [(x, y - 65), (x - 14, y - 50), (x + 14, y - 50)])
    # 尾翼
    pygame.draw.polygon(screen, GRAY, [(x - 12, y + 10), (x - 28, y + 25), (x - 12, y + 5)])
    pygame.draw.polygon(screen, GRAY, [(x + 12, y + 10), (x + 28, y + 25), (x + 12, y + 5)])
    # 舷窗
    pygame.draw.circle(screen, BLUE, (x, y - 25), 7)


def main_loop():
    global rocket_y, rocket_speed_y, thrust, is_launch
    running = True
    while running:
        screen.fill(BLACK)

        # 绘制星空
        for star in stars:
            pygame.draw.circle(screen, WHITE, (int(star[0]), int(star[1])), star[2])

        # 事件监听
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE and not is_launch:
                    is_launch = True

        keys = pygame.key.get_pressed()

        # 火箭飞行物理运算
        if is_launch:
            if keys[pygame.K_UP] and thrust < max_thrust:
                thrust += 0.03
            if keys[pygame.K_DOWN] and thrust > 0:
                thrust -= 0.03

            rocket_speed_y -= thrust
            rocket_speed_y += gravity
            rocket_y += rocket_speed_y

            # 有推力才喷出火焰
            if thrust > 0.1:
                create_fire(rocket_x, rocket_y + 15)

        # 更新粒子系统
        alive_particles = []
        for p in particles:
            p[1] += p[2]
            p[3] -= 1
            if p[3] > 0:
                radius = int(p[3] / 8)
                pygame.draw.circle(screen, p[4], (int(p[0]), int(p[1])), radius)
                alive_particles.append(p)
        particles[:] = alive_particles

        draw_rocket(rocket_x, rocket_y)

        # HUD信息面板
        text_thrust = font.render(f"推力: {thrust:.2f}  [↑加大 | ↓减小]", True, WHITE)
        text_vel = font.render(f"上升速度: {-rocket_speed_y:.2f} m/s", True, WHITE)
        screen.blit(text_thrust, (20, 18))
        screen.blit(text_vel, (20, 48))

        if not is_launch:
            start_tip = font_big.render("按下【空格键】发射火箭", True, GREEN)
            screen.blit(start_tip, (WIDTH // 2 - 180, HEIGHT // 2))

        # 地面标线
        pygame.draw.line(screen, (50, 50, 50), (0, HEIGHT - 40), (WIDTH, HEIGHT - 40), 3)

        # 坠落地面重置火箭
        if rocket_y > HEIGHT - 100:
            rocket_y = HEIGHT - 120
            rocket_speed_y = 0
            thrust = 0
            is_launch = False

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


if __name__ == "__main__":
    main_loop()
    pygame.quit()