import pygame
import math
import random

# --- 初始化 ---
pygame.init()
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("捕鱼模拟器 - Pygame街机版")
clock = pygame.time.Clock()

# 颜色
BG_COLOR = (20, 60, 100)
CANNON_COLOR = (180, 120, 60)
BULLET_COLOR = (255, 200, 50)
NET_COLOR = (200, 200, 200, 100)
GOLD_COLOR = (255, 215, 0)
UI_COLOR = (255, 255, 255)

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

# --- 游戏对象 ---

class Cannon:
    def __init__(self):
        self.x = WIDTH // 2
        self.y = HEIGHT - 40
        self.angle = -math.pi / 2  # 初始朝上
        self.cooldown = 0
        self.power = 1  # 炮台等级

    def update(self, mouse_pos):
        # 计算角度
        dx = mouse_pos[0] - self.x
        dy = mouse_pos[1] - self.y
        self.angle = math.atan2(dy, dx)
        
        # 限制角度范围（防止向后打）
        if self.angle > -0.2: self.angle = -0.2
        if self.angle < -math.pi + 0.2: self.angle = -math.pi + 0.2
        
        if self.cooldown > 0: self.cooldown -= 1

    def shoot(self):
        if self.cooldown > 0: return None
        self.cooldown = 15  # 射击间隔
        # 子弹初始位置在炮口
        bx = self.x + math.cos(self.angle) * 40
        by = self.y + math.sin(self.angle) * 40
        return Bullet(bx, by, self.angle, self.power)

    def draw(self, surface):
        # 炮台底座
        pygame.draw.circle(surface, CANNON_COLOR, (self.x, self.y), 30)
        # 炮管
        end_x = self.x + math.cos(self.angle) * 50
        end_y = self.y + math.sin(self.angle) * 50
        pygame.draw.line(surface, (200, 150, 80), (self.x, self.y), (end_x, end_y), 12)
        # 等级标识
        lvl_txt = FONT.render(str(self.power), True, (0,0,0))
        surface.blit(lvl_txt, (self.x - 8, self.y - 12))

class Bullet:
    def __init__(self, x, y, angle, power):
        self.x = x
        self.y = y
        self.angle = angle
        self.speed = 10
        self.power = power
        self.alive = True
        self.rect = pygame.Rect(x-4, y-4, 8, 8)

    def update(self):
        self.x += math.cos(self.angle) * self.speed
        self.y += math.sin(self.angle) * self.speed
        self.rect.center = (self.x, self.y)
        
        # 出界销毁
        if not screen.get_rect().contains(self.rect):
            self.alive = False

    def draw(self, surface):
        pygame.draw.circle(surface, BULLET_COLOR, (int(self.x), int(self.y)), 6)
        # 简单拖尾
        tail_x = self.x - math.cos(self.angle) * 10
        tail_y = self.y - math.sin(self.angle) * 10
        pygame.draw.circle(surface, (255, 150, 0), (int(tail_x), int(tail_y)), 3)

class Net:
    def __init__(self, x, y, power):
        self.x = x
        self.y = y
        self.power = power
        self.radius = 40 + power * 10  # 威力越大网越大
        self.life = 10  # 存在帧数
        self.alive = True

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

    def draw(self, surface):
        # 半透明渔网
        net_surf = pygame.Surface((self.radius*2, self.radius*2), pygame.SRCALPHA)
        pygame.draw.circle(net_surf, NET_COLOR, (self.radius, self.radius), self.radius)
        surface.blit(net_surf, (int(self.x - self.radius), int(self.y - self.radius)))

class Fish:
    def __init__(self, speed_mult=1.0):
        # 随机从左侧或右侧生成
        self.side = random.choice(['left', 'right'])
        self.y = random.randint(50, HEIGHT - 100)
        self.x = -50 if self.side == 'left' else WIDTH + 50
        
        # 鱼的大小和血量
        self.size = random.choice([15, 25, 35])
        self.hp = self.size // 5 + 1
        self.max_hp = self.hp
        self.speed = random.uniform(1.5, 3.0) * speed_mult
        if self.side == 'right': self.speed *= -1
        
        self.alive = True
        self.flash_timer = 0  # 受击闪烁

    def update(self):
        self.x += self.speed
        # 简单上下浮动
        self.y += math.sin(pygame.time.get_ticks() / 200 + self.x / 50) * 0.5
        
        # 出界重置
        if (self.side == 'left' and self.x > WIDTH + 60) or \
           (self.side == 'right' and self.x < -60):
            self.reset()
            
        if self.flash_timer > 0: self.flash_timer -= 1

    def reset(self):
        self.side = random.choice(['left', 'right'])
        self.x = -50 if self.side == 'left' else WIDTH + 50
        self.y = random.randint(50, HEIGHT - 100)
        self.hp = self.max_hp
        self.alive = True

    def take_damage(self, dmg):
        self.hp -= dmg
        self.flash_timer = 5
        if self.hp <= 0:
            self.alive = False
            return True  # 击杀
        return False

    def draw(self, surface):
        if not self.alive: return
        color = (255, 100, 100) if self.flash_timer > 0 else (100, 200, 255)
        if self.size > 30: color = (255, 200, 50)  # 大鱼金色
        
        pygame.draw.ellipse(surface, color, (int(self.x - self.size), int(self.y - self.size//2), 
                                             self.size*2, self.size))
        # 眼睛
        eye_x = self.x + (self.size//2 if self.speed > 0 else -self.size//2)
        pygame.draw.circle(surface, (0,0,0), (int(eye_x), int(self.y - 3)), 3)

class Gold:
    def __init__(self, x, y, value):
        self.x = x
        self.y = y
        self.value = value
        self.target_x = WIDTH - 50
        self.target_y = 30
        self.alive = True
        self.speed = 8

    def update(self):
        # 飞向右上角
        dx = self.target_x - self.x
        dy = self.target_y - self.y
        dist = math.hypot(dx, dy)
        if dist < 10:
            self.alive = False
            return self.value  # 返回得分
        else:
            self.x += dx / dist * self.speed
            self.y += dy / dist * self.speed
            return 0

    def draw(self, surface):
        pygame.draw.circle(surface, GOLD_COLOR, (int(self.x), int(self.y)), 8)
        pygame.draw.circle(surface, (200, 150, 0), (int(self.x), int(self.y)), 5)

# --- 主程序 ---

def main():
    cannon = Cannon()
    bullets = []
    nets = []
    fishes = []
    golds = []
    
    score = 0
    frame_count = 0
    speed_mult = 1.0
    
    # 初始化鱼群
    for _ in range(12):
        fishes.append(Fish(speed_mult))

    running = True
    while running:
        clock.tick(60)
        frame_count += 1
        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 event.button == 1:
                b = cannon.shoot()
                if b: bullets.append(b)

        # 难度递增：每30秒加速
        if frame_count % 1800 == 0:
            speed_mult += 0.1
            for f in fishes: f.speed *= 1.1

        # 更新炮台
        cannon.update(mouse_pos)

        # 更新子弹
        for b in bullets[:]:
            b.update()
            if not b.alive:
                bullets.remove(b)
                continue
            # 子弹碰鱼 -> 生成渔网
            for f in fishes:
                if f.alive and abs(b.x - f.x) < f.size and abs(b.y - f.y) < f.size:
                    nets.append(Net(b.x, b.y, cannon.power))
                    b.alive = False
                    break

        # 更新渔网
        for n in nets[:]:
            n.update()
            if not n.alive:
                nets.remove(n)
                continue
            # 渔网伤害判定
            for f in fishes:
                if f.alive and math.hypot(n.x - f.x, n.y - f.y) < n.radius:
                    if f.take_damage(n.power):
                        # 击杀 -> 掉金币
                        val = f.size * 10
                        golds.append(Gold(f.x, f.y, val))
                        f.reset()  # 鱼重生

        # 更新金币
        for g in golds[:]:
            val = g.update()
            if val > 0:
                score += val
                # 升级炮台
                if score > cannon.power * 1000 and cannon.power < 5:
                    cannon.power += 1
            if not g.alive:
                golds.remove(g)

        # 更新鱼
        for f in fishes: f.update()

        # --- 绘图 ---
        screen.fill(BG_COLOR)
        
        # 水波纹背景（简单正弦线）
        for i in range(0, WIDTH, 40):
            y_off = math.sin((frame_count + i) / 30) * 5
            pygame.draw.line(screen, (30, 80, 120), (i, 0), (i, HEIGHT + y_off), 2)

        for f in fishes: f.draw(screen)
        for n in nets: n.draw(screen)
        for b in bullets: b.draw(screen)
        for g in golds: g.draw(screen)
        cannon.draw(screen)

        # UI
        score_txt = FONT.render(f"Score: {score}", True, UI_COLOR)
        screen.blit(score_txt, (WIDTH - 180, 20))
        
        power_txt = FONT.render(f"Power: {cannon.power}", True, GOLD_COLOR)
        screen.blit(power_txt, (20, 20))

        pygame.display.flip()

    pygame.quit()

if __name__ == "__main__":
    main()