import pygame
import random
import sys
import os

# 初始化pygame
pygame.init()

# 窗口设置
SCREEN_WIDTH = 1000
SCREEN_HEIGHT = 700
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("2D移动射击游戏")

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)

# 时钟
clock = pygame.time.Clock()
FPS = 60

# ==========修复字体报错============
try:
    # 选用微软雅黑，规避None参数引起的sysfont异常
    font = pygame.font.SysFont("msyh", 36)
except Exception:
    # 失败就创建默认字体对象
    font = pygame.font.Font(pygame.font.get_default_font(), 36)


# 玩家类
class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.Surface((40, 40))
        self.image.fill(BLUE)
        self.rect = self.image.get_rect()
        self.rect.center = (SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2)
        self.speed = 5
        self.health = 100

    def update(self):
        # 方向键移动
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT] and self.rect.left > 0:
            self.rect.x -= self.speed
        if keys[pygame.K_RIGHT] and self.rect.right < SCREEN_WIDTH:
            self.rect.x += self.speed
        if keys[pygame.K_UP] and self.rect.top > 0:
            self.rect.y -= self.speed
        if keys[pygame.K_DOWN] and self.rect.bottom < SCREEN_HEIGHT:
            self.rect.y += self.speed


# 子弹类
class Bullet(pygame.sprite.Sprite):
    def __init__(self, x, y, mx, my):
        super().__init__()
        self.image = pygame.Surface((8, 16))
        self.image.fill(YELLOW)
        self.rect = self.image.get_rect(center=(x, y))
        # 计算子弹朝向鼠标
        dx = mx - x
        dy = my - y
        dist = (dx ** 2 + dy ** 2) ** 0.5
        self.vx = dx / dist * 10
        self.vy = dy / dist * 10

    def update(self):
        self.rect.x += self.vx
        self.rect.y += self.vy
        # 超出屏幕销毁
        if (self.rect.right < 0 or self.rect.left > SCREEN_WIDTH or
                self.rect.bottom < 0 or self.rect.top > SCREEN_HEIGHT):
            self.kill()


# 敌人类
class Enemy(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.Surface((35, 35))
        self.image.fill(RED)
        self.rect = self.image.get_rect()
        # 四边随机出生
        side = random.choice(["top", "bottom", "left", "right"])
        if side == "top":
            self.rect.centerx = random.randint(0, SCREEN_WIDTH)
            self.rect.y = -40
        elif side == "bottom":
            self.rect.centerx = random.randint(0, SCREEN_WIDTH)
            self.rect.y = SCREEN_HEIGHT + 40
        elif side == "left":
            self.rect.x = -40
            self.rect.centery = random.randint(0, SCREEN_HEIGHT)
        else:
            self.rect.x = SCREEN_WIDTH + 40
            self.rect.centery = random.randint(0, SCREEN_HEIGHT)
        self.speed = random.uniform(2, 4)

    def update(self):
        # 朝向玩家追击
        dx = player.rect.centerx - self.rect.centerx
        dy = player.rect.centery - self.rect.centery
        dist = (dx ** 2 + dy ** 2) ** 0.5
        self.rect.x += dx / dist * self.speed
        self.rect.y += dy / dist * self.speed


# 创建精灵分组
all_sprites = pygame.sprite.Group()
bullets = pygame.sprite.Group()
enemies = pygame.sprite.Group()

player = Player()
all_sprites.add(player)

score = 0
enemy_spawn_timer = 0

running = True
while running:
    clock.tick(FPS)
    mx, my = pygame.mouse.get_pos()

    # 事件监听
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        # 鼠标左键发射子弹
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                bullet = Bullet(player.rect.centerx, player.rect.centery, mx, my)
                all_sprites.add(bullet)
                bullets.add(bullet)

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

    all_sprites.update()

    # 子弹击中敌人
    hit_enemies = pygame.sprite.groupcollide(enemies, bullets, True, True)
    for hit in hit_enemies:
        score += 10

    # 敌人撞击玩家
    hurt = pygame.sprite.spritecollide(player, enemies, True)
    for h in hurt:
        player.health -= 20
        if player.health <= 0:
            print(f"游戏结束！最终得分:{score}")
            running = False

    # 渲染
    screen.fill(BLACK)
    all_sprites.draw(screen)

    # UI文字
    score_text = font.render(f"分数：{score}", True, WHITE)
    hp_text = font.render(f"生命值：{player.health}", True, GREEN)
    screen.blit(score_text, (10, 10))
    screen.blit(hp_text, (10, 50))

    pygame.display.flip()

pygame.quit()
sys.exit()
