import pygame
import random
import sys
import math
import os  # 引入 os 模块用于查找字体文件

# --- 初始化设置 ---
pygame.init()
clock = pygame.time.Clock()

# --- 屏幕设置 ---
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("全方位星际求生")

# --- 颜色定义 ---
BLACK = (10, 10, 20) 
WHITE = (255, 255, 255)
RED = (255, 50, 50)
CYAN = (0, 255, 255)
ORANGE = (255, 165, 0)
ASTEROID_COLOR = (150, 150, 150)

# --- 游戏常量 ---
PLAYER_SPEED = 7
ASTEROID_SPEED_MIN = 3
ASTEROID_SPEED_MAX = 7
ASTEROID_SPAWN_RATE = 30  

# --- 类定义 ---

class Star:
    """背景星星类"""
    def __init__(self):
        self.x = random.randint(0, SCREEN_WIDTH)
        self.y = random.randint(0, SCREEN_HEIGHT)
        self.size = random.randint(1, 2)
        self.speed = random.uniform(0.2, 0.8)

    def move(self):
        self.y += self.speed
        if self.y > SCREEN_HEIGHT:
            self.y = 0
            self.x = random.randint(0, SCREEN_WIDTH)

    def draw(self):
        pygame.draw.circle(screen, WHITE, (self.x, self.y), self.size)

class Ship:
    """玩家飞船类"""
    def __init__(self):
        self.width = 40
        self.height = 40
        self.x = SCREEN_WIDTH // 2
        self.y = SCREEN_HEIGHT // 2
        self.rect = pygame.Rect(self.x, self.y, self.width, self.height)
        self.flame_timer = 0

    def move(self, dx, dy):
        self.x += dx * PLAYER_SPEED
        self.y += dy * PLAYER_SPEED
        
        # 边界限制
        self.x = max(0, min(self.x, SCREEN_WIDTH - self.width))
        self.y = max(0, min(self.y, SCREEN_HEIGHT - self.height))
        
        self.rect.topleft = (self.x, self.y)

    def draw(self):
        # 绘制飞船主体 (三角形)
        points = [
            (self.x + self.width // 2, self.y),          # 顶点
            (self.x, self.y + self.height),              # 左下
            (self.x + self.width, self.y + self.height)  # 右下
        ]
        pygame.draw.polygon(screen, CYAN, points)
        
        # 绘制推进器火焰
        self.flame_timer += 1
        flame_height = random.randint(10, 20)
        flame_points = [
            (self.x + 10, self.y + self.height - 5),
            (self.x + self.width - 10, self.y + self.height - 5),
            (self.x + self.width // 2, self.y + self.height + flame_height)
        ]
        pygame.draw.polygon(screen, ORANGE, flame_points)

class Asteroid:
    """陨石类"""
    def __init__(self):
        self.radius = random.randint(15, 40)
        self.x, self.y = self.get_spawn_position()
        self.speed = random.uniform(ASTEROID_SPEED_MIN, ASTEROID_SPEED_MAX)
        
        # 计算飞向屏幕中心的方向
        center_x, center_y = SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2
        angle = math.atan2(center_y - self.y, center_x - self.x)
        
        # 增加一点随机偏转
        angle += random.uniform(-0.5, 0.5)
        
        self.dx = math.cos(angle) * self.speed
        self.dy = math.sin(angle) * self.speed
        
        self.rect = pygame.Rect(self.x - self.radius, self.y - self.radius, self.radius * 2, self.radius * 2)

    def get_spawn_position(self):
        """从屏幕四个边缘随机位置生成"""
        side = random.choice(['top', 'bottom', 'left', 'right'])
        if side == 'top':
            return random.randint(0, SCREEN_WIDTH), -50
        elif side == 'bottom':
            return random.randint(0, SCREEN_WIDTH), SCREEN_HEIGHT + 50
        elif side == 'left':
            return -50, random.randint(0, SCREEN_HEIGHT)
        elif side == 'right':
            return SCREEN_WIDTH + 50, random.randint(0, SCREEN_HEIGHT)

    def update(self):
        self.x += self.dx
        self.y += self.dy
        self.rect.centerx = self.x
        self.rect.centery = self.y

    def draw(self):
        pygame.draw.circle(screen, ASTEROID_COLOR, (int(self.x), int(self.y)), self.radius)
        # 画个圈显得更有质感
        pygame.draw.circle(screen, WHITE, (int(self.x), int(self.y)), self.radius, 2)

    def is_off_screen(self):
        # 如果飞出了屏幕很远的地方，就销毁
        margin = 100
        return (self.x < -margin or self.x > SCREEN_WIDTH + margin or 
                self.y < -margin or self.y > SCREEN_HEIGHT + margin)

# --- 主游戏逻辑 ---

def main():
    ship = Ship()
    asteroids = []
    stars = [Star() for _ in range(100)] 
    score = 0
    game_over = False
    
    # --- 字体设置 (已修复中文显示) ---
    # 尝试自动查找 Windows 系统的微软雅黑字体
    font_path = os.path.join(os.environ.get("WINDIR", "C:\\Windows"), "Fonts", "msyh.ttc")
    
    try:
        if os.path.exists(font_path):
            font = pygame.font.Font(font_path, 30)      # 小字号
            big_font = pygame.font.Font(font_path, 60)  # 大字号
        else:
            # 如果找不到字体文件，回退到默认字体（中文可能显示为方框）
            font = pygame.font.SysFont("arial", 30)
            big_font = pygame.font.SysFont("arial", 60)
    except:
        font = pygame.font.SysFont("arial", 30)
        big_font = pygame.font.SysFont("arial", 60)

    running = True
    while running:
        clock.tick(60)
        screen.fill(BLACK)

        # 1. 事件处理
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_r and game_over:
                    main() # 重新开始
                    return

        # 2. 游戏逻辑
        if not game_over:
            # 键盘控制
            keys = pygame.key.get_pressed()
            dx = dy = 0
            if keys[pygame.K_LEFT] or keys[pygame.K_a]: dx = -1
            if keys[pygame.K_RIGHT] or keys[pygame.K_d]: dx = 1
            if keys[pygame.K_UP] or keys[pygame.K_w]: dy = -1
            if keys[pygame.K_DOWN] or keys[pygame.K_s]: dy = 1
            
            ship.move(dx, dy)

            # 生成陨石
            if random.randint(1, ASTEROID_SPAWN_RATE) == 1:
                asteroids.append(Asteroid())

            # 更新陨石
            for asteroid in asteroids:
                asteroid.update()
                if ship.rect.colliderect(asteroid.rect):
                    game_over = True
            
            # 移除超出屏幕的陨石并计分
            if asteroids and asteroids[0].is_off_screen():
                asteroids.pop(0)
                score += 1

        # 3. 绘制画面
        # 绘制背景
        for star in stars:
            star.move()
            star.draw()

        # 绘制陨石
        for asteroid in asteroids:
            asteroid.draw()

        # 绘制飞船
        ship.draw()

        # --- UI 显示 (中文) ---
        score_text = font.render(f"得分：{score}", True, WHITE)
        screen.blit(score_text, (10, 10))

        if game_over:
            # 游戏结束文字
            over_text = big_font.render("游戏结束", True, RED)
            restart_text = font.render("按 'R' 键重新开始", True, WHITE)
            
            # 居中显示
            text_rect = over_text.get_rect(center=(SCREEN_WIDTH/2, SCREEN_HEIGHT/2 - 20))
            restart_rect = restart_text.get_rect(center=(SCREEN_WIDTH/2, SCREEN_HEIGHT/2 + 40))
            
            screen.blit(over_text, text_rect)
            screen.blit(restart_text, restart_rect)

        pygame.display.flip()

    pygame.quit()
    sys.exit()

if __name__ == "__main__":
    main()