import pygame
import random
import sys

# ===================== 初始化基础配置 =====================
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 = (30, 200, 30)
BLUE = (30, 100, 220)
YELLOW = (255, 220, 0)
BG_COLOR = (28, 28, 35)

# ========== 修复后的字体代码 ==========
try:
    msyh_path = "C:/Windows/Fonts/msyh.ttc"
    font_big = pygame.font.Font(msyh_path, 48)
    font_mid = pygame.font.Font(msyh_path, 28)
    font_small = pygame.font.Font(msyh_path, 20)
except:
    font_big = pygame.font.SysFont(["Microsoft YaHei", "SimHei", "Arial"], 48)
    font_mid = pygame.font.SysFont(["Microsoft YaHei", "SimHei", "Arial"], 28)
    font_small = pygame.font.SysFont(["Microsoft YaHei", "SimHei", "Arial"], 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

    def update(self):
        # WASD移动
        keys = pygame.key.get_pressed()
        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

# ===================== 子弹类 =====================
class Bullet(pygame.sprite.Sprite):
    def __init__(self, pos, target_pos):
        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=pos)
        self.speed = 12
        # 计算子弹方向向量
        dx = target_pos[0] - pos[0]
        dy = target_pos[1] - pos[1]
        dist = (dx**2 + dy**2)**0.5
        if dist != 0:
            self.vx = dx / dist * self.speed
            self.vy = dy / dist * self.speed
        else:
            self.vx, self.vy = 0, -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:
            x = random.randint(0, WIDTH)
            y = -20
        elif side == 1:
            x = WIDTH + 20
            y = random.randint(0, HEIGHT)
        elif side == 2:
            x = random.randint(0, WIDTH)
            y = HEIGHT + 20
        else:
            x = -20
            y = random.randint(0, HEIGHT)
        self.rect = self.image.get_rect(center=(x, y))
        self.speed = random.uniform(1.5, 3)

    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

# ===================== 游戏初始化数据 =====================
def reset_game():
    global player, all_sprites, bullet_group, enemy_group, score, game_over
    player = Player()
    all_sprites = pygame.sprite.Group(player)
    bullet_group = pygame.sprite.Group()
    enemy_group = pygame.sprite.Group()
    score = 0
    game_over = False

reset_game()
spawn_enemy_timer = 0

# ===================== 主游戏循环 =====================
running = True
while running:
    dt = clock.tick(FPS) / 1000
    screen.fill(BG_COLOR)

    # 事件监听
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        # 鼠标左键发射子弹
        if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1 and not game_over:
            mouse_pos = pygame.mouse.get_pos()
            bullet = Bullet(player.rect.center, mouse_pos)
            bullet_group.add(bullet)
            all_sprites.add(bullet)
        # 游戏结束按R重新开始
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_r and game_over:
                reset_game()

    if not game_over:
        # 定时生成敌人
        spawn_enemy_timer += dt
        if spawn_enemy_timer > 1.2:
            enemy = Enemy()
            enemy_group.add(enemy)
            all_sprites.add(enemy)
            spawn_enemy_timer = 0

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

        # 子弹击中敌人
        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)
        for _ in hit_player:
            player.hp -= 20
            if player.hp <= 0:
                game_over = True

    # 绘制所有物体
    all_sprites.draw(screen)

    # 绘制UI信息
    hp_text = font_small.render(f"血量: {max(player.hp, 0)}", True, GREEN if player.hp>30 else RED)
    screen.blit(hp_text, (10, 10))
    score_text = font_small.render(f"分数: {score}", True, WHITE)
    screen.blit(score_text, (10, 35))

    # 游戏结束画面
    if game_over:
        over_text = font_big.render("游戏结束", True, RED)
        tip_text = font_mid.render("按 R 重新开始", True, WHITE)
        screen.blit(over_text, (WIDTH//2 - over_text.get_width()//2, HEIGHT//2 - 60))
        screen.blit(tip_text, (WIDTH//2 - tip_text.get_width()//2, HEIGHT//2 + 10))

    pygame.display.flip()

pygame.quit()
sys.exit()