import pygame
import sys
import random
import math

# 初始化pygame
pygame.init()

# 游戏常量
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
FPS = 60

# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 255, 0)
GRAY = (128, 128, 128)


class Player:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = 40
        self.height = 40
        self.speed = 5
        self.health = 100
        self.max_health = 100
        self.rect = pygame.Rect(x, y, self.width, self.height)
        self.shoot_cooldown = 0
        self.shoot_delay = 10  # 射击冷却时间

    def update(self, keys):
        # 移动控制
        if keys[pygame.K_w] and self.y > 0:
            self.y -= self.speed
        if keys[pygame.K_s] and self.y < SCREEN_HEIGHT - self.height:
            self.y += self.speed
        if keys[pygame.K_a] and self.x > 0:
            self.x -= self.speed
        if keys[pygame.K_d] and self.x < SCREEN_WIDTH - self.width:
            self.x += self.speed

        # 更新矩形位置
        self.rect.x = self.x
        self.rect.y = self.y

        # 更新射击冷却
        if self.shoot_cooldown > 0:
            self.shoot_cooldown -= 1

    def shoot(self, mouse_x, mouse_y):
        if self.shoot_cooldown <= 0:
            self.shoot_cooldown = self.shoot_delay
            # 计算子弹方向
            dx = mouse_x - self.x
            dy = mouse_y - self.y
            distance = max(1, math.sqrt(dx*dx + dy*dy))
            dx, dy = dx/distance, dy/distance
            return Bullet(self.x + self.width//2, self.y + self.height//2, dx, dy, True)
        return None

    def draw(self, screen):
        # 绘制玩家
        pygame.draw.rect(screen, BLUE, self.rect)
        pygame.draw.rect(screen, WHITE, self.rect, 2)

        # 绘制血条
        bar_width = self.width
        bar_height = 5
        health_ratio = self.health / self.max_health
        pygame.draw.rect(
            screen, RED, (self.x, self.y - 10, bar_width, bar_height))
        pygame.draw.rect(screen, GREEN, (self.x, self.y - 10,
                         bar_width * health_ratio, bar_height))


class Enemy:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.width = 30
        self.height = 30
        self.speed = random.uniform(1.0, 2.5)
        self.health = 30
        self.max_health = 30
        self.rect = pygame.Rect(x, y, self.width, self.height)
        self.shoot_cooldown = 0
        self.shoot_delay = random.randint(60, 120)  # 敌人射击间隔

    def update(self, player_x, player_y):
        # 向玩家移动
        dx = player_x - self.x
        dy = player_y - self.y
        distance = max(1, math.sqrt(dx*dx + dy*dy))
        dx, dy = dx/distance, dy/distance

        self.x += dx * self.speed
        self.y += dy * self.speed

        # 更新矩形位置
        self.rect.x = self.x
        self.rect.y = self.y

        # 更新射击冷却
        if self.shoot_cooldown > 0:
            self.shoot_cooldown -= 1

    def shoot(self, player_x, player_y):
        if self.shoot_cooldown <= 0:
            self.shoot_cooldown = self.shoot_delay
            # 计算子弹方向（向玩家）
            dx = player_x - self.x
            dy = player_y - self.y
            distance = max(1, math.sqrt(dx*dx + dy*dy))
            dx, dy = dx/distance, dy/distance
            return Bullet(self.x + self.width//2, self.y + self.height//2, dx, dy, False)
        return None

    def draw(self, screen):
        # 绘制敌人
        pygame.draw.rect(screen, RED, self.rect)
        pygame.draw.rect(screen, WHITE, self.rect, 2)

        # 绘制血条
        bar_width = self.width
        bar_height = 3
        health_ratio = self.health / self.max_health
        pygame.draw.rect(
            screen, RED, (self.x, self.y - 8, bar_width, bar_height))
        pygame.draw.rect(screen, GREEN, (self.x, self.y - 8,
                         bar_width * health_ratio, bar_height))


class Bullet:
    def __init__(self, x, y, dx, dy, is_player_bullet):
        self.x = x
        self.y = y
        self.dx = dx * 8  # 子弹速度
        self.dy = dy * 8
        self.radius = 3
        self.is_player_bullet = is_player_bullet
        self.rect = pygame.Rect(x - self.radius, y -
                                self.radius, self.radius*2, self.radius*2)

    def update(self):
        self.x += self.dx
        self.y += self.dy
        self.rect.x = self.x - self.radius
        self.rect.y = self.y - self.radius

    def is_off_screen(self):
        return (self.x < 0 or self.x > SCREEN_WIDTH or
                self.y < 0 or self.y > SCREEN_HEIGHT)

    def draw(self, screen):
        color = YELLOW if self.is_player_bullet else RED
        pygame.draw.circle(
            screen, color, (int(self.x), int(self.y)), self.radius)


class Game:
    def __init__(self):
        self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
        pygame.display.set_caption("枪战游戏")
        self.clock = pygame.time.Clock()
        self.font = pygame.font.Font(None, 36)

        # 游戏对象
        self.player = Player(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2)
        self.enemies = []
        self.bullets = []
        self.score = 0
        self.game_over = False
        self.enemy_spawn_timer = 0
        self.enemy_spawn_delay = 60  # 每60帧生成一个敌人

    def spawn_enemy(self):
        # 在屏幕边缘随机位置生成敌人
        side = random.randint(0, 3)
        if side == 0:  # 上边
            x = random.randint(0, SCREEN_WIDTH)
            y = -30
        elif side == 1:  # 右边
            x = SCREEN_WIDTH + 30
            y = random.randint(0, SCREEN_HEIGHT)
        elif side == 2:  # 下边
            x = random.randint(0, SCREEN_WIDTH)
            y = SCREEN_HEIGHT + 30
        else:  # 左边
            x = -30
            y = random.randint(0, SCREEN_HEIGHT)

        self.enemies.append(Enemy(x, y))

    def handle_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                return False
            elif event.type == pygame.MOUSEBUTTONDOWN:
                if event.button == 1 and not self.game_over:  # 左键点击
                    mouse_x, mouse_y = pygame.mouse.get_pos()
                    bullet = self.player.shoot(mouse_x, mouse_y)
                    if bullet:
                        self.bullets.append(bullet)
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_r and self.game_over:
                    self.restart_game()
        return True

    def restart_game(self):
        self.player = Player(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2)
        self.enemies = []
        self.bullets = []
        self.score = 0
        self.game_over = False
        self.enemy_spawn_timer = 0

    def update(self):
        if self.game_over:
            return

        keys = pygame.key.get_pressed()
        self.player.update(keys)

        # 生成敌人
        self.enemy_spawn_timer += 1
        if self.enemy_spawn_timer >= self.enemy_spawn_delay:
            self.spawn_enemy()
            self.enemy_spawn_timer = 0
            # 随着分数增加，敌人生成速度加快
            self.enemy_spawn_delay = max(20, 60 - self.score // 10)

        # 更新敌人
        for enemy in self.enemies[:]:
            enemy.update(self.player.x, self.player.y)

            # 敌人射击
            if random.random() < 0.02:  # 2%概率每帧射击
                bullet = enemy.shoot(self.player.x, self.player.y)
                if bullet:
                    self.bullets.append(bullet)

            # 检查碰撞：玩家与敌人
            if self.player.rect.colliderect(enemy.rect):
                self.player.health -= 1
                if self.player.health <= 0:
                    self.game_over = True

        # 更新子弹
        for bullet in self.bullets[:]:
            bullet.update()

            # 移除屏幕外的子弹
            if bullet.is_off_screen():
                self.bullets.remove(bullet)
                continue

            # 检查碰撞
            if bullet.is_player_bullet:
                # 玩家子弹击中敌人
                for enemy in self.enemies[:]:
                    if bullet.rect.colliderect(enemy.rect):
                        enemy.health -= 25
                        if enemy.health <= 0:
                            self.enemies.remove(enemy)
                            self.score += 10
                        if bullet in self.bullets:
                            self.bullets.remove(bullet)
                        break
            else:
                # 敌人子弹击中玩家
                if bullet.rect.colliderect(self.player.rect):
                    self.player.health -= 10
                    if self.player.health <= 0:
                        self.game_over = True
                    if bullet in self.bullets:
                        self.bullets.remove(bullet)

    def draw(self):
        self.screen.fill(BLACK)

        # 绘制所有对象
        self.player.draw(self.screen)
        for enemy in self.enemies:
            enemy.draw(self.screen)
        for bullet in self.bullets:
            bullet.draw(self.screen)

        # 绘制UI
        score_text = self.font.render(f"分数: {self.score}", True, WHITE)
        self.screen.blit(score_text, (10, 10))

        health_text = self.font.render(
            f"生命: {self.player.health}", True, WHITE)
        self.screen.blit(health_text, (10, 50))

        # 绘制游戏结束界面
        if self.game_over:
            game_over_text = self.font.render("游戏结束! 按R键重新开始", True, RED)
            text_rect = game_over_text.get_rect(
                center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2))
            self.screen.blit(game_over_text, text_rect)

            final_score_text = self.font.render(
                f"最终分数: {self.score}", True, WHITE)
            score_rect = final_score_text.get_rect(
                center=(SCREEN_WIDTH//2, SCREEN_HEIGHT//2 + 40))
            self.screen.blit(final_score_text, score_rect)

        pygame.display.flip()

    def run(self):
        running = True
        while running:
            running = self.handle_events()
            self.update()
            self.draw()
            self.clock.tick(FPS)

        pygame.quit()
        sys.exit()


if __name__ == "__main__":
    game = Game()
    game.run()


class Player:
    # ... (之前的 __init__ 代码) ...
    def __init__(self, x, y):
        # ... (原有属性) ...
        self.melee_cooldown = 0
        self.melee_range = 60  # 攻击距离
        self.melee_damage = 50  # 攻击伤害

    def update(self, keys):
        # ... (原有的移动代码) ...

        # 更新近战冷却
        if self.melee_cooldown > 0:
            self.melee_cooldown -= 1

    def melee_attack(self, enemies):
        if self.melee_cooldown <= 0:
            self.melee_cooldown = 30  # 0.5秒冷却
            hit_connected = False

            # 创建一个临时的攻击范围矩形（以玩家为中心）
            attack_rect = pygame.Rect(
                self.x - self.melee_range//2,
                self.y - self.melee_range//2,
                self.width + self.melee_range,
                self.height + self.melee_range
            )

            # 检查是否打中敌人
            for enemy in enemies[:]:
                if attack_rect.colliderect(enemy.rect):
                    enemy.health -= self.melee_damage
                    hit_connected = True
                    if enemy.health <= 0:
                        enemies.remove(enemy)
                        return 10  # 返回分数

            return 0  # 没打死敌人或没打中
        return 0
