import pygame
import numpy as np
from math import sin, cos, radians
# 初始化引擎
pygame.init()
W, H = 1920, 1080 # 支持4K分辨率
screen = pygame.display.set_mode((W, H))
clock = pygame.time.Clock()
# 高级参数配置
PARTICLES = 500 # 粒子数量
HEART_SCALE = 18 # 爱心大小系数
GRAVITY = 0.25 # 引力参数
COLOR_SPEED = 3 # 颜色渐变速度
TRAIL_LENGTH = 15 # 粒子拖尾长度
class Particle:
def __init__(self):
self.angle = np.random.uniform(0, 2*np.pi) # 初始角度
self.radius = np.random.uniform(80, 150) # 3D深度模拟
self.pos = np.array([W//2, H//2], dtype=float)
self.history = [] # 轨迹坐标存储
# HSL颜色初始化
self.hue = np.random.randint(0, 360)
self.color = pygame.Color(0)
self.color.hsla = (self.hue, 100, 50, 0)
def update(self, time):
# 心跳函数控制缩放
beat = 1 + 0.3 * sin(time * 5) # 5Hz心跳频率
# 心形参数方程(3D投影)
theta = self.angle + time * 0.5 # 动态旋转
x = HEART_SCALE * beat * (16 * sin(theta)**3)
y = HEART_SCALE * (13*cos(theta) - 5*cos(2*theta)
- 2*cos(3*theta) - cos(4*theta))
# 3D透视变换
target = np.array([W//2 + x * (1 + self.radius/200),
H//2 - y * (1 + self.radius/200)])
# 物理运动模拟
self.pos += (target - self.pos) * 0.1 + np.array([0, GRAVITY])
self.history.append(self.pos.copy())
if len(self.history) > TRAIL_LENGTH:
self.history.pop(0)
# 动态颜色渐变
self.hue = (self.hue + COLOR_SPEED) % 360
self.color.hsla = (self.hue, 100, 50, 0)
def draw(self):
# 绘制粒子拖尾
for i, pos in enumerate(self.history):
alpha = 255 * (i+1)/len(self.history)
radius = 3 * (i+1)/len(self.history)
pygame.draw.circle(screen, (*self.color[:3], alpha),
pos.astype(int), int(radius))
# 创建粒子系统
particles = [Particle() for _ in range(PARTICLES)]
# 主循环
running = True
time = 0
while running:
screen.fill((0, 0, 0)) # 星空背景
# 添加动态星空特效
if np.random.rand() < 0.02:
pygame.draw.circle(screen, (255,255,255),
(np.random.randint(W), np.random.randint(H)), 1)
# 更新粒子状态
for p in particles:
p.update(time)
p.draw()
# 事件处理
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.display.flip()
time += 0.01
clock.tick(60) # 60FPS锁定
pygame.quit()