import pygame
import random
import sys
import os

# 初始化pygame
pygame.init()
# 窗口设置
WIDTH, HEIGHT = 900, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("2D移动射击游戏")
clock = pygame.time.Clock()
FPS = 60

# 颜色常量
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (220, 30, 30)
GREEN = (40, 180, 40)
BLUE = (30, 100, 220)
YELLOW = (255, 220, 0)
GRAY = (80, 80, 80)

# ========== 修复字体部分 ==========
try:
    # 直接调用系统已安装的微软雅黑字体名称，不用读取文件
    font_big = pygame.font.SysFont("Microsoft YaHei", 48)
    font_mid = pygame.font.SysFont("Microsoft YaHei", 28)
    font_small = pygame.font.SysFont("Microsoft YaHei", 20)
except:
    # 终极兜底：pygame自带默认字体，百分百不会报错
    font_big = pygame.font.Font(None, 48)
    font_mid = pygame.font.Font(None, 28)
    font_small = pygame.font.Font(None, 20)

# 玩家类
class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.radius = 20
        self.image = pygame.Surface((self.radius*2, self.radius*2), pygame.SRCALPHA)
        pygame.draw.circle(self.image, BLUE, (self.radius, self.radius), self.radius)
        self.rect = self.image.get_rect(center=(WIDTH//2, HEIGHT//2))
        self.speed = 5
        self.hp = 100
        self.max_hp = 100
        self.invincible = False
        self.inv_time = 0
        self.damage = 10

    def update(self, keys):
        # 移动控制 WASD
        if keys[pygame.K_w] and self.rect.top > 0:
            self.rect.y -= self.speed
        if keys[pygame.K_s] and self.rect.bottom < HEIGHT:
            self.rect.y += self.speed
        if keys[pygame.K_a] and self.rect.left > 0:
            self.rect.x -= self.speed
        if keys[pygame.K_d] and self.rect.right < WIDTH:
            self.rect.x += self.speed

        # 无敌帧计时
        if self.invincible:
            self.inv_time -= 1
            if self.inv_time <= 0:
                self.invincible = False

# 子弹类
class Bullet(pygame.sprite.Sprite):
    def __init__(self, x, y, target_x, target_y):
        super().__init__()
        self.radius = 6
        self.image = pygame.Surface((self.radius*2, self.radius*2), pygame.SRCALPHA)
        pygame.draw.circle(self.image, YELLOW, (self.radius, self.radius), self.radius)
        self.rect = self.image.get_rect(center=(x, y))
        self.speed = 12
        dx = target_x - x
        dy = target_y - y
        dist = (dx**2 + dy**2)**0.5
        self.vx = dx / dist * self.speed
        self.vy = dy / dist * self.speed

    def update(self):
        self.rect.x += self.vx
        self.rect.y += self.vy
        if self.rect.right < 0 or self.rect.left > WIDTH or self.rect.bottom < 0 or self.rect.top > HEIGHT:
            self.kill()

# 敌人类
class Enemy(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.radius = 16
        self.image = pygame.Surface((self.radius*2, self.radius*2), pygame.SRCALPHA)
        pygame.draw.circle(self.image, RED, (self.radius, self.radius), self.radius)
        side = random.randint(0, 3)
        if side == 0:
            pos = (random.randint(0, WIDTH), -30)
        elif side == 1:
            pos = (random.randint(0, WIDTH), HEIGHT+30)
        elif side == 2:
            pos = (-30, random.randint(0, HEIGHT))
        else:
            pos = (WIDTH+30, random.randint(0, HEIGHT))
        self.rect = self.image.get_rect(center=pos)
        self.speed = random.uniform(2, 3.5)

    def update(self, player):
        dx = player.rect.centerx - self.rect.centerx
        dy = player.rect.centery - self.rect.centery
        dist = (dx**2 + dy**2)**0.5
        if dist > 0:
            self.rect.x += dx / dist * self.speed
            self.rect.y += dy / dist * self.speed

# 绘制血条、分数UI
def draw_ui(hp, score):
    pygame.draw.rect(screen, GRAY, (20, 20, 200, 22))
    hp_width = (hp / 100) * 200
    color = GREEN if hp > 50 else RED
    pygame.draw.rect(screen, color, (20, 20, hp_width, 22))
    hp_text = font_small.render(f"生命值: {hp}/100", True, WHITE)
    screen.blit(hp_text, (25, 22))
    score_text = font_mid.render(f"分数: {score}", True, WHITE)
    screen.blit(score_text, (WIDTH - 150, 15))

# 游戏结束界面
def game_over_screen(score):
    screen.fill(BLACK)
    over_text = font_big.render("游戏结束", True, RED)
    score_text = font_mid.render(f"最终分数：{score}", True, WHITE)
    tip_text = font_mid.render("按 R 重新开始 | ESC 退出", True, WHITE)
    screen.blit(over_text, (WIDTH//2 - over_text.get_width()//2, HEIGHT//2 - 80))
    screen.blit(score_text, (WIDTH//2 - score_text.get_width()//2, HEIGHT//2))
    screen.blit(tip_text, (WIDTH//2 - tip_text.get_width()//2, HEIGHT//2 + 60))
    pygame.display.update()
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_r:
                    return True
                if event.key == pygame.K_ESCAPE:
                    pygame.quit()
                    sys.exit()

# 主游戏循环
def main():
    while True:
        all_sprites = pygame.sprite.Group()
        bullet_group = pygame.sprite.Group()
        enemy_group = pygame.sprite.Group()
        player = Player()
        all_sprites.add(player)
        score = 0
        enemy_spawn_timer = 0
        game_running = True

        while game_running:
            clock.tick(FPS)
            screen.fill((20, 20, 25))
            mouse_pos = pygame.mouse.get_pos()
            keys = pygame.key.get_pressed()

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()
                if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                    bullet = Bullet(player.rect.centerx, player.rect.centery, *mouse_pos)
                    bullet_group.add(bullet)
                    all_sprites.add(bullet)

            # 生成敌人
            enemy_spawn_timer += 1
            if enemy_spawn_timer >= 90:
                enemy = Enemy()
                enemy_group.add(enemy)
                all_sprites.add(enemy)
                enemy_spawn_timer = 0

            # 更新精灵
            player.update(keys)
            for enemy in enemy_group:
                enemy.update(player)
            bullet_group.update()

            # 子弹击杀敌人加分
            hit_enemies = pygame.sprite.groupcollide(enemy_group, bullet_group, True, True)
            for _ in hit_enemies:
                score += 10

            # 玩家受伤
            hit_player = pygame.sprite.spritecollide(player, enemy_group, True)
            if hit_player and not player.invincible:
                player.hp -= player.damage
                player.invincible = True
                player.inv_time = 45

            if player.hp <= 0:
                game_running = False

            all_sprites.draw(screen)
            draw_ui(player.hp, score)
            pygame.draw.line(screen, (100,100,100), player.rect.center, mouse_pos, 1)
            pygame.display.flip()

        restart = game_over_screen(score)
        if not restart:
            break

if __name__ == "__main__":
    main()