import pygame
import math
import random

# --- 初始化 ---
pygame.init()
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("海岛骑兵 - Island Cavalry")
clock = pygame.time.Clock()

# 配色
SEA_COLOR = (30, 100, 180)
SAND_COLOR = (238, 214, 175)
GRASS_COLOR = (100, 180, 100)
PLAYER_COLOR = (50, 100, 200)  # 蓝色骑兵服
HORSE_COLOR = (139, 69, 19)    # 棕色战马
ENEMY_COLOR = (180, 40, 40)    # 红色海盗
SLASH_COLOR = (255, 255, 255)  # 刀光
UI_COLOR = (255, 255, 255)

FONT = pygame.font.SysFont("arial", 24)
BIG_FONT = pygame.font.SysFont("arial", 60)

# --- 类定义 ---

class Slash:
    def __init__(self, x, y, angle):
        self.x = x
        self.y = y
        self.angle = angle
        self.life = 10
        self.radius = 60
        self.alive = True

    def update(self):
        self.life -= 1
        if self.life <= 0: self.alive = False

    def draw(self, surface):
        # 画扇形刀光
        start_angle = self.angle - math.pi / 4
        end_angle = self.angle + math.pi / 4
        rect = pygame.Rect(self.x - self.radius, self.y - self.radius, self.radius*2, self.radius*2)
        alpha = max(0, min(255, self.life * 25))
        color = (255, 255, 255, alpha)
        # Pygame 原生不支持透明扇形，用线条模拟
        for i in range(5):
            a = start_angle + (end_angle - start_angle) * i / 4
            ex = self.x + math.cos(a) * self.radius
            ey = self.y + math.sin(a) * self.radius
            pygame.draw.line(surface, SLASH_COLOR, (self.x, self.y), (ex, ey), 3)

class Enemy:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.speed = 1.0
        self.rect = pygame.Rect(x-12, y-12, 24, 24)
        self.alive = True
        self.hp = 2

    def update(self, target_x, target_y):
        dx = target_x - self.x
        dy = target_y - self.y
        dist = math.hypot(dx, dy)
        if dist > 0:
            self.x += (dx / dist) * self.speed
            self.y += (dy / dist) * self.speed
        self.rect.center = (self.x, self.y)

    def draw(self, surface):
        pygame.draw.circle(surface, ENEMY_COLOR, (int(self.x), int(self.y)), 12)
        # 画个海盗帽示意
        pygame.draw.rect(surface, (0,0,0), (int(self.x)-8, int(self.y)-15, 16, 6))

class Cavalry:
    def __init__(self):
        self.x = WIDTH // 2
        self.y = HEIGHT // 2
        self.base_speed = 4
        self.speed = self.base_speed
        self.vx = 0
        self.vy = 0
        self.rect = pygame.Rect(self.x-18, self.y-18, 36, 36)
        self.angle = 0
        self.cooldown = 0
        self.sprint_timer = 0
        self.max_sprint = 30
        self.sprint_cd = 0

    def update(self, mouse_pos):
        keys = pygame.key.get_pressed()
        move_x, move_y = 0, 0
        if keys[pygame.K_w]: move_y -= 1
        if keys[pygame.K_s]: move_y += 1
        if keys[pygame.K_a]: move_x -= 1
        if keys[pygame.K_d]: move_x += 1
        
        # 归一化移动
        dist = math.hypot(move_x, move_y)
        if dist > 0:
            move_x /= dist
            move_y /= dist

        # 冲刺逻辑
        if keys[pygame.K_SPACE] and self.sprint_cd <= 0 and dist > 0:
            self.sprint_timer = self.max_sprint
            self.sprint_cd = 60 # 冷却1秒

        current_speed = self.base_speed
        if self.sprint_timer > 0:
            current_speed = self.base_speed * 2.5
            self.sprint_timer -= 1
        if self.sprint_cd > 0: self.sprint_cd -= 1

        self.x += move_x * current_speed
        self.y += move_y * current_speed
        
        # 边界限制（岛屿范围）
        margin = 50
        self.x = max(margin, min(WIDTH-margin, self.x))
        self.y = max(margin, min(HEIGHT-margin, self.y))
        self.rect.center = (self.x, self.y)

        # 朝向鼠标
        dx = mouse_pos[0] - self.x
        dy = mouse_pos[1] - self.y
        self.angle = math.atan2(dy, dx)
        
        if self.cooldown > 0: self.cooldown -= 1

    def attack(self, slashes):
        if self.cooldown <= 0:
            slashes.append(Slash(self.x, self.y, self.angle))
            self.cooldown = 20 # 攻击间隔

    def draw(self, surface):
        # 画战马（椭圆）
        horse_rect = pygame.Rect(self.x-20, self.y-12, 40, 24)
        # 简单旋转效果：根据角度拉伸
        # 这里用固定椭圆，通过位置模拟方向
        pygame.draw.ellipse(surface, HORSE_COLOR, horse_rect)
        
        # 画骑手（圆）
        rider_offset = 5
        rx = self.x + math.cos(self.angle) * rider_offset
        ry = self.y + math.sin(self.angle) * rider_offset
        pygame.draw.circle(surface, PLAYER_COLOR, (int(rx), int(ry)), 10)
        
        # 画武器（线）
        weapon_len = 25
        wx = rx + math.cos(self.angle) * weapon_len
        wy = ry + math.sin(self.angle) * weapon_len
        pygame.draw.line(surface, (200, 200, 200), (rx, ry), (wx, wy), 3)

# --- 主程序 ---

def main():
    player = Cavalry()
    slashes = []
    enemies = []
    score = 0
    spawn_timer = 0
    game_over = False

    running = True
    while running:
        clock.tick(60)
        mouse_pos = pygame.mouse.get_pos()

        for event in pygame.event.get():
            if event.type == pygame.QUIT: running = False
            if event.type == pygame.MOUSEBUTTONDOWN and not game_over:
                if event.button == 1: player.attack(slashes)
            if event.type == pygame.KEYDOWN and game_over:
                if event.key == pygame.K_r:
                    main(); return

        if not game_over:
            player.update(mouse_pos)

            # 生成海盗
            spawn_timer += 1
            difficulty = max(30, 80 - score // 50)
            if spawn_timer > difficulty:
                spawn_timer = 0
                side = random.choice(['top', 'bottom', 'left', 'right'])
                if side == 'top': ex, ey = random.randint(0, WIDTH), -30
                elif side == 'bottom': ex, ey = random.randint(0, WIDTH), HEIGHT+30
                elif side == 'left': ex, ey = -30, random.randint(0, HEIGHT)
                else: ex, ey = WIDTH+30, random.randint(0, HEIGHT)
                enemies.append(Enemy(ex, ey))

            # 更新刀光
            for s in slashes[:]:
                s.update()
                if not s.alive: slashes.remove(s)
                else:
                    # 刀光击中敌人
                    for e in enemies[:]:
                        if e.alive:
                            dx = e.x - s.x
                            dy = e.y - s.y
                            dist = math.hypot(dx, dy)
                            if dist < 60: # 攻击半径
                                angle_to_enemy = math.atan2(dy, dx)
                                diff = abs((angle_to_enemy - s.angle + math.pi) % (2*math.pi) - math.pi)
                                if diff < math.pi / 4: # 扇形角度
                                    e.hp -= 1
                                    if e.hp <= 0:
                                        e.alive = False
                                        score += 10
                                    # 击退效果
                                    e.x += math.cos(s.angle) * 20
                                    e.y += math.sin(s.angle) * 20
                                    s.alive = False # 一刀只打一个（或穿透，看需求）
                                    break
            enemies = [e for e in enemies if e.alive]

            # 更新敌人
            for e in enemies:
                e.update(player.x, player.y)
                # 撞击伤害
                if e.rect.colliderect(player.rect):
                    # 简单处理：碰到就扣血或重置位置
                    # 这里设为碰到即死，增加难度
                    game_over = True

        # --- 绘图 ---
        screen.fill(SEA_COLOR)
        pygame.draw.rect(screen, SAND_COLOR, (40, 40, WIDTH-80, HEIGHT-80))
        pygame.draw.rect(screen, GRASS_COLOR, (100, 100, WIDTH-200, HEIGHT-200))

        for s in slashes: s.draw(screen)
        player.draw(screen)
        for e in enemies: e.draw(screen)

        # UI
        score_txt = FONT.render(f"Bounties: {score}", True, UI_COLOR)
        screen.blit(score_txt, (10, 10))
        
        # 冲刺条
        sprint_pct = 1 - (player.sprint_cd / 60) if player.sprint_cd > 0 else 1
        bar_w = 100
        pygame.draw.rect(screen, (100,100,100), (10, 40, bar_w, 10))
        pygame.draw.rect(screen, (255, 200, 0), (10, 40, int(bar_w * sprint_pct), 10))
        hint_txt = FONT.render("SPACE: Sprint", True, UI_COLOR)
        screen.blit(hint_txt, (120, 35))

        if game_over:
            over_txt = BIG_FONT.render("HORSE FALLEN", True, (255, 50, 50))
            rect = over_txt.get_rect(center=(WIDTH//2, HEIGHT//2 - 30))
            screen.blit(over_txt, rect)
            restart_txt = FONT.render("Press R to Remount", True, UI_COLOR)
            r_rect = restart_txt.get_rect(center=(WIDTH//2, HEIGHT//2 + 30))
            screen.blit(restart_txt, r_rect)

        pygame.display.flip()

    pygame.quit()

if __name__ == "__main__":
    main()