fork(1) download
  1.  
Success #stdin #stdout 0.09s 14160KB
stdin
import pygame
import numpy as np
import math

# 初始化Pygame
pygame.init()
width, height = 800, 600
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("粒子爱心汇聚效果")
clock = pygame.time.Clock()
fps = 60

# 粒子类(增加生命周期和发射属性)
class Particle:
    def __init__(self, target_x, target_y, target_z):
        # 初始位置(从底部随机位置发射)
        self.pos = np.array([np.random.uniform(-50, 50), 50, np.random.uniform(-20, 20)], dtype=float)
        self.target_pos = np.array([target_x, target_y, target_z], dtype=float)  # 爱心目标位置
        self.vel = np.array([0, 0, 0], dtype=float)
        self.acc = np.array([0, 0, 0], dtype=float)
        self.life = 100  # 粒子生命周期(帧数)
        self.max_life = 100
        self.size = 2

    def update(self):
        # 向目标位置的吸引力
        dir_to_target = self.target_pos - self.pos
        attract_force = dir_to_target * 0.008  # 吸引力强度
        self.apply_force(attract_force)

        # 重力(让粒子下落消散)
        gravity = np.array([0, 0.05, 0]) if self.life < 20 else np.array([0, 0, 0])
        self.apply_force(gravity)

        # 物理更新
        self.vel += self.acc
        self.pos += self.vel
        self.acc *= 0

        # 生命周期递减
        self.life -= 1

    def apply_force(self, force):
        self.acc += force

    def get_color(self):
        # 粒子颜色随生命周期变化(蓝青色渐变)
        alpha = self.life / self.max_life
        blue = int(100 + alpha * 155)
        cyan = int(200 + alpha * 55)
        return (0, blue, cyan)

    def is_alive(self):
        return self.life > 0

# 生成爱心目标位置
def create_heart_targets(num_particles):
    targets = []
    for _ in range(num_particles):
        theta = np.random.uniform(0, 2 * math.pi)
        r = 16 * math.sin(theta) ** 3
        x = r * math.cos(theta)
        y = 13 * math.cos(theta) - 5 * math.cos(2*theta) - 2 * math.cos(3*theta) - math.cos(4*theta)
        z = np.random.uniform(-5, 5)
        targets.append((x * 8, y * 8, z * 8))  # 缩放爱心大小
    return targets

# 初始化目标位置和粒子池
targets = create_heart_targets(800)  # 800个粒子更细腻
particles = []
particle_index = 0

# 3D视角参数
camera_z = 120
rotation = 0

running = True
while running:
    # 事件处理
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    screen.fill((0, 0, 0))  # 黑色背景

    # 逐步生成粒子(循环复用目标位置)
    if particle_index < len(targets) and len(particles) < 600:
        tx, ty, tz = targets[particle_index]
        particles.append(Particle(tx, ty, tz))
        particle_index = (particle_index + 1) % len(targets)

    # 旋转参数更新
    rotation += 0.005
    cos_rot = math.cos(rotation)
    sin_rot = math.sin(rotation)

    # 更新并绘制粒子
    alive_particles = []
    for p in particles:
        if p.is_alive():
            p.update()

            # 3D旋转(绕y轴)
            x, y, z = p.pos
            x_rot = x * cos_rot - z * sin_rot
            z_rot = x * sin_rot + z * cos_rot

            # 透视投影
            factor = camera_z / (camera_z + z_rot)
            x_screen = width // 2 + x_rot * factor
            y_screen = height // 2 + y * factor
            size = p.size * factor

            # 绘制粒子
            if 0 < x_screen < width and 0 < y_screen < height and factor > 0:
                color = p.get_color()
                pygame.draw.circle(screen, color, (int(x_screen), int(y_screen)), max(1, int(size)))
            alive_particles.append(p)
    particles = alive_particles  # 移除死亡粒子

    pygame.display.flip()
    clock.tick(fps)

pygame.quit()
stdout
Standard output is empty