import pygame
import sys
import random
import math

pygame.init()
WIDTH, HEIGHT = 900, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("水果切切乐")
clock = pygame.time.Clock()

# 颜色
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (220, 30, 30)
GREEN = (30, 180, 40)
ORANGE = (255, 140, 0)
YELLOW = (255, 220, 0)
PURPLE = (160, 40, 180)
SKY_BLUE = (100, 170, 255)

# 字体
try:
    font = pygame.font.SysFont("simhei", 30)
    font_big = pygame.font.SysFont("simhei", 60)
except:
    font = pygame.font.Font(None, 30)
    font_big = pygame.font.Font(None, 60)

# 水果类型定义
FRUIT_TYPES = [
    {"color": ORANGE, "radius": 32, "is_bomb": False},  #橙子
    {"color": RED, "radius": 30, "is_bomb": False},    #苹果
    {"color": PURPLE, "radius": 34, "is_bomb": False}, #葡萄
    {"color": YELLOW, "radius": 28, "is_bomb": False}, #柠檬
    {"color": BLACK, "radius": 26, "is_bomb": True}    #炸弹
]

# 水果类
class Fruit:
    def __init__(self):
        self.x = random.randint(80, WIDTH - 80)
        self.y = HEIGHT + 30
        self.vx = random.uniform(-3.5, 3.5)
        self.vy = random.uniform(-14, -10)
        self.rotate = 0
        self.rotate_speed = random.uniform(-4, 4)
        self.info = random.choice(FRUIT_TYPES)
        self.r = self.info["radius"]
        self.cut = False

    def update(self):
        self.x += self.vx
        self.y += self.vy
        self.vy += 0.32
        self.rotate += self.rotate_speed

    def draw(self):
        cx, cy = self.x, self.y
        surface = pygame.Surface((self.r*3, self.r*3), pygame.SRCALPHA)
        pygame.draw.circle(surface, self.info["color"], (self.r*1.5, self.r*1.5), self.r)
        if self.info["is_bomb"]:
            pygame.draw.circle(surface, WHITE, (self.r*1.5-8, self.r*1.5-6), 5)
            pygame.draw.circle(surface, BLACK, (self.r*1.5-8, self.r*1.5-6), 2)
        rotated = pygame.transform.rotate(surface, self.rotate)
        rect = rotated.get_rect(center=(cx, cy))
        screen.blit(rotated, rect)

    def check_slice(self, p1, p2):
        x1,y1 = p1
        x2,y2 = p2
        cx, cy = self.x, self.y
        dx = x2 - x1
        dy = y2 - y1
        # 修复：两点重合直接返回False，避免除零
        if dx == 0 and dy == 0:
            return False
        a = y2 - y1
        b = x1 - x2
        c = x2*y1 - x1*y2
        dist = abs(a*cx + b*cy + c) / math.hypot(a,b)
        if dist > self.r:
            return False
        min_x = min(x1,x2) - self.r
        max_x = max(x1,x2) + self.r
        min_y = min(y1,y2) - self.r
        max_y = max(y1,y2) + self.r
        return min_x <= cx <= max_x and min_y <= cy <= max_y

# 游戏变量
fruit_list = []
trace_points = []  #鼠标刀痕轨迹
score = 0
life = 3
combo = 0
combo_timer = 0
game_over = False
spawn_timer = 0

def reset_game():
    global fruit_list, score, life, combo, game_over, spawn_timer, trace_points
    fruit_list.clear()
    trace_points.clear()
    score = 0
    life = 3
    combo = 0
    combo_timer = 0
    game_over = False

reset_game()

running = True
while running:
    clock.tick(60)
    screen.fill(SKY_BLUE)
    mx, my = pygame.mouse.get_pos()

    mouse_down = pygame.mouse.get_pressed()[0]
    #刀痕轨迹
    if mouse_down and not game_over:
        trace_points.append((mx, my))
        if len(trace_points) > 18:
            trace_points.pop(0)
    else:
        trace_points.clear()

    #绘制刀痕
    if len(trace_points) >= 2:
        pygame.draw.lines(screen, WHITE, False, trace_points, 4)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE and game_over:
                reset_game()

    if not game_over:
        #生成水果
        spawn_timer += 1
        if spawn_timer >= 35:
            fruit_list.append(Fruit())
            spawn_timer = 0

        #连击倒计时
        if combo_timer > 0:
            combo_timer -= 1
        else:
            combo = 0

        #更新所有水果
        remove_list = []
        for fruit in fruit_list:
            fruit.update()
            #切割判定
            if len(trace_points)>=2 and not fruit.cut:
                for i in range(len(trace_points)-1):
                    if fruit.check_slice(trace_points[i], trace_points[i+1]):
                        fruit.cut = True
                        if fruit.info["is_bomb"]:
                            game_over = True
                        else:
                            combo += 1
                            combo_timer = 40
                            add_score = 10 + combo*3
                            score += add_score
                        break
            #飞出屏幕底部
            if fruit.y > HEIGHT + 50 and not fruit.cut:
                if not fruit.info["is_bomb"]:
                    life -= 1
                    if life <= 0:
                        game_over = True
                remove_list.append(fruit)
            elif fruit.y < -60:
                remove_list.append(fruit)
        #统一删除，避免遍历中直接删除列表元素引发bug
        for f in remove_list:
            if f in fruit_list:
                fruit_list.remove(f)

        #绘制水果
        for fruit in fruit_list:
            if not fruit.cut:
                fruit.draw()

    #UI信息
    text_score = font.render(f"分数：{score}", True, BLACK)
    text_life = font.render(f"生命：{'❤'*life}", True, RED)
    screen.blit(text_score, (20,15))
    screen.blit(text_life, (20, 50))
    if combo > 1:
        combo_text = font.render(f"连击 x{combo}", True, ORANGE)
        screen.blit(combo_text, (WIDTH - 160, 15))

    if game_over:
        over_text = font_big.render("游戏结束！", True, RED)
        tip_text = font.render("按下空格键重新开始", True, BLACK)
        screen.blit(over_text, (WIDTH//2 - 160, HEIGHT//2 - 60))
        screen.blit(tip_text, (WIDTH//2 - 200, HEIGHT//2 + 10))

    pygame.display.flip()

pygame.quit()
sys.exit()