高级粒子特效跳动爱心代码
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from matplotlib.collections import PathCollection
import matplotlib.cm as cm
from math import pi, sin, cos, exp, sqrt
import random
from colorsys import hsv_to_rgb
# 设置画布
fig = plt.figure(figsize=(12, 10), facecolor='black')
ax = fig.add_subplot(111, facecolor='black')
ax.set_xlim(-25, 25)
ax.set_ylim(-25, 25)
ax.axis('off') # 关闭坐标轴
# 创建多个粒子系统
class ParticleSystem:
def __init__(self, num_particles):
self.num_particles = num_particles
self.reset()
def reset(self):
# 初始化粒子数据
self.particles = np.zeros(self.num_particles, dtype=[
('position', float, 2),
('size', float, 1),
('color', float, 4),
('velocity', float, 2),
('life', float, 1),
('type', int, 1),
('phase', float, 1)
])
# 随机初始化粒子
self.particles['position'][:, 0] = np.random.uniform(-25, 25, self.num_particles)
self.particles['position'][:, 1] = np.random.uniform(-25, 25, self.num_particles)
self.particles['size'] = np.random.uniform(2, 25, self.num_particles)
self.particles['life'] = np.random.uniform(0.0, 1.0, self.num_particles)
self.particles['phase'] = np.random.uniform(0, 2*pi, self.num_particles)
self.particles['type'] = np.random.randint(0, 3, self.num_particles)
# 根据粒子类型设置不同属性
for i in range(self.num_particles):
ptype = self.particles['type'][i]
if ptype == 0: # 主爱心粒子
self.particles['color'][i] = [1.0, 0.2, 0.2, 0.8] # 红色
self.particles['velocity'][i] = [0, 0]
elif ptype == 1: # 氛围粒子
r, g, b = hsv_to_rgb(random.uniform(0.9, 1.0), 1.0, 1.0)
self.particles['color'][i] = [r, g, b, random.uniform(0.3, 0.7)]
self.particles['velocity'][i] = [random.uniform(-0.3, 0.3), random.uniform(-0.3, 0.3)]
else: # 闪烁粒子
self.particles['color'][i] = [1.0, 1.0, 1.0, random.uniform(0.5, 1.0)]
self.particles['velocity'][i] = [random.uniform(-0.1, 0.1), random.uniform(-0.1, 0.1)]
# 创建多个粒子系统
main_particles = ParticleSystem(2000)
background_particles = ParticleSystem(1000)
sparkle_particles = ParticleSystem(500)
# 创建散点图对象
main_scat = ax.scatter(main_particles.particles['position'][:, 0],
main_particles.particles['position'][:, 1],
s=main_particles.particles['size'],
c=main_particles.particles['color'],
alpha=0.8)
bg_scat = ax.scatter(background_particles.particles['position'][:, 0],
background_particles.particles['position'][:, 1],
s=background_particles.particles['size'],
c=background_particles.particles['color'],
alpha=0.6)
sparkle_scat = ax.scatter(sparkle_particles.particles['position'][:, 0],
sparkle_particles.particles['position'][:, 1],
s=sparkle_particles.particles['size'],
c=sparkle_particles.particles['color'],
alpha=0.9)
# 添加文字效果
text = ax.text(0, -20, "LOVE",
fontsize=32, color='white',
ha='center', va='center',
fontfamily='serif', fontweight='bold',
alpha=0.8)
subtext = ax.text(0, -22, "永恒的心跳",
fontsize=16, color='pink',
ha='center', va='center',
fontfamily='serif',
alpha=0.7)
# 计算爱心形状上的点
def heart_shape(t, scale=1.0):
x = 16 * np.sin(t) ** 3
y = 13 * np.cos(t) - 5 * np.cos(2*t) - 2 * np.cos(3*t) - np.cos(4*t)
return x * scale, y * scale
# 动画更新函数
def update(frame):
# 计算当前帧的跳动效果
beat1 = 1.0 + 0.15 * sin(frame * 6)
beat2 = 1.0 + 0.08 * sin(frame * 12 + pi/4)
beat3 = 1.0 + 0.05 * sin(frame * 24 + pi/2)
overall_beat = (beat1 + beat2 + beat3) / 3
# 更新主爱心粒子
for i in range(main_particles.num_particles):
ptype = main_particles.particles['type'][i]
if ptype == 0: # 主爱心粒子
# 粒子生命周期
main_particles.particles['life'][i] -= 0.005
if main_particles.particles['life'][i] <= 0:
# 在爱心形状上重生
angle = random.uniform(0, 2*pi)
x, y = heart_shape(angle, overall_beat)
main_particles.particles['position'][i, 0] = x + random.uniform(-0.5, 0.5)
main_particles.particles['position'][i, 1] = y + random.uniform(-0.5, 0.5)
main_particles.particles['life'][i] = random.uniform(0.5, 1.0)
main_particles.particles['size'][i] = random.uniform(5, 15)
# 粒子颜色脉动
pulse = 0.7 + 0.3 * sin(frame * 10 + main_particles.particles['phase'][i])
main_particles.particles['color'][i, 0] = 1.0 # R
main_particles.particles['color'][i, 1] = 0.1 + 0.1 * pulse # G
main_particles.particles['color'][i, 2] = 0.1 + 0.1 * pulse # B
main_particles.particles['color'][i, 3] = 0.6 + 0.2 * pulse # A
elif ptype == 1: # 氛围粒子
# 更新位置
main_particles.particles['position'][i, 0] += main_particles.particles['velocity'][i, 0]
main_particles.particles['position'][i, 1] += main_particles.particles['velocity'][i, 1]
# 边界检查
if abs(main_particles.particles['position'][i, 0]) > 25:
main_particles.particles['velocity'][i, 0] *= -1
if abs(main_particles.particles['position'][i, 1]) > 25:
main_particles.particles['velocity'][i, 1] *= -1
# 颜色变化
hue = (frame * 0.05 + main_particles.particles['phase'][i]) % 1.0
r, g, b = hsv_to_rgb(hue, 0.8, 1.0)
main_particles.particles['color'][i, 0] = r
main_particles.particles['color'][i, 1] = g
main_particles.particles['color'][i, 2] = b
main_particles.particles['color'][i, 3] = 0.5 + 0.3 * sin(frame * 3 + main_particles.particles['phase'][i])
else: # 闪烁粒子
# 更新位置
main_particles.particles['position'][i, 0] += main_particles.particles['velocity'][i, 0]
main_particles.particles['position'][i, 1] += main_particles.particles['velocity'][i, 1]
# 闪烁效果
sparkle = 0.3 + 0.7 * abs(sin(frame * 20 + main_particles.particles['phase'][i]))
main_particles.particles['color'][i, 3] = sparkle
main_particles.particles['size'][i] = 2 + 8 * sparkle
# 更新背景粒子
for i in range(background_particles.num_particles):
# 更新位置
background_particles.particles['position'][i, 0] += background_particles.particles['velocity'][i, 0]
background_particles.particles['position'][i, 1] += background_particles.particles['velocity'][i, 1]
# 边界检查
if abs(background_particles.particles['position'][i, 0]) > 25:
background_particles.particles['position'][i, 0] = np.sign(background_particles.particles['position'][i, 0]) * -25
if abs(background_particles.particles['position'][i, 1]) > 25:
background_particles.particles['position'][i, 1] = np.sign(background_particles.particles['position'][i, 1]) * -25
# 颜色变化
hue = (frame * 0.02 + background_particles.particles['phase'][i]) % 1.0
r, g, b = hsv_to_rgb(hue, 0.6, 0.8)
background_particles.particles['color'][i, 0] = r
background_particles.particles['color'][i, 1] = g
background_particles.particles['color'][i, 2] = b
# 更新闪烁粒子
for i in range(sparkle_particles.num_particles):
# 粒子生命周期
sparkle_particles.particles['life'][i] -= 0.01
if sparkle_particles.particles['life'][i] <= 0:
# 在爱心附近重生
angle = random.uniform(0, 2*pi)
radius = random.uniform(5, 20)
sparkle_particles.particles['position'][i, 0] = radius * cos(angle)
sparkle_particles.particles['position'][i, 1] = radius * sin(angle)
sparkle_particles.particles['life'][i] = random.uniform(0.5, 1.5)
sparkle_particles.particles['size'][i] = random.uniform(1, 5)
# 闪烁效果
sparkle = 0.2 + 0.8 * abs(sin(frame * 15 + sparkle_particles.particles['phase'][i]))
sparkle_particles.particles['color'][i, 3] = sparkle
sparkle_particles.particles['size'][i] = 1 + 4 * sparkle
# 向中心移动
dist = sqrt(sparkle_particles.particles['position'][i, 0]**2 + sparkle_particles.particles['position'][i, 1]**2)
if dist > 0.1:
sparkle_particles.particles['position'][i, 0] -= 0.1 * sparkle_particles.particles['position'][i, 0] / dist
sparkle_particles.particles['position'][i, 1] -= 0.1 * sparkle_particles.particles['position'][i, 1] / dist
# 更新散点图数据
main_scat.set_offsets(main_particles.particles['position'])
main_scat.set_sizes(main_particles.particles['size'])
main_scat.set_color(main_particles.particles['color'])
bg_scat.set_offsets(background_particles.particles['position'])
bg_scat.set_sizes(background_particles.particles['size'])
bg_scat.set_color(background_particles.particles['color'])
sparkle_scat.set_offsets(sparkle_particles.particles['position'])
sparkle_scat.set_sizes(sparkle_particles.particles['size'])
sparkle_scat.set_color(sparkle_particles.particles['color'])
# 文字效果
text_pulse = 0.7 + 0.3 * sin(frame * 4)
text.set_color((1.0, 1.0, 1.0, text_pulse))
text.set_position((0, -20 + 0.5 * sin(frame * 2)))
subtext_pulse = 0.6 + 0.4 * sin(frame * 3 + pi/3)
subtext.set_color((1.0, 0.7, 0.9, subtext_pulse))
return main_scat, bg_scat, sparkle_scat, text, subtext
# 创建动画
ani = FuncAnimation(fig, update, frames=np.linspace(0, 4*pi, 200),
interval=40, blit=True)
plt.tight_layout()
plt.show()代码详细解析
1. 多粒子系统设计
class ParticleSystem:
def __init__(self, num_particles):
self.num_particles = num_particles
self.reset()· 创建了三个独立的粒子系统:主爱心粒子、背景氛围粒子和闪烁粒子 · 每个系统有不同类型的粒子,具有不同的行为和视觉效果
2. 粒子类型分类
# 根据粒子类型设置不同属性
ptype = self.particles['type'][i]
if ptype == 0: # 主爱心粒子
self.particles['color'][i] = [1.0, 0.2, 0.2, 0.8] # 红色
self.particles['velocity'][i] = [0, 0]
elif ptype == 1: # 氛围粒子
r, g, b = hsv_to_rgb(random.uniform(0.9, 1.0), 1.0, 1.0)
self.particles['color'][i] = [r, g, b, random.uniform(0.3, 0.7)]
self.particles['velocity'][i] = [random.uniform(-0.3, 0.3), random.uniform(-0.3, 0.3)]
else: # 闪烁粒子
self.particles['color'][i] = [1.0, 1.0, 1.0, random.uniform(0.5, 1.0)]
self.particles['velocity'][i] = [random.uniform(-0.1, 0.1), random.uniform(-0.1, 0.1)]· 主爱心粒子:形成爱心形状,颜色为红色,位置相对固定 · 氛围粒子:在背景中漂浮,颜色渐变,创造浪漫氛围 · 闪烁粒子:白色粒子,大小和透明度变化,创造星光效果
3. 复杂跳动效果
# 计算当前帧的跳动效果
beat1 = 1.0 + 0.15 * sin(frame * 6)
beat2 = 1.0 + 0.08 * sin(frame * 12 + pi/4)
beat3 = 1.0 + 0.05 * sin(frame * 24 + pi/2)
overall_beat = (beat1 + beat2 + beat3) / 3· 使用三个不同频率的正弦波叠加,创造更自然的跳动效果 · 每个波有不同的振幅和相位,模拟真实心跳的复杂性
4. 粒子生命周期管理
# 粒子生命周期
main_particles.particles['life'][i] -= 0.005
if main_particles.particles['life'][i] <= 0:
# 在爱心形状上重生
angle = random.uniform(0, 2*pi)
x, y = heart_shape(angle, overall_beat)
main_particles.particles['position'][i, 0] = x + random.uniform(-0.5, 0.5)
main_particles.particles['position'][i, 1] = y + random.uniform(-0.5, 0.5)
main_particles.particles['life'][i] = random.uniform(0.5, 1.0)· 每个粒子有生命周期,结束后在爱心形状上重生 · 重生位置基于爱心参数方程,确保粒子始终形成爱心形状
5. 颜色和透明度动画
# 粒子颜色脉动
pulse = 0.7 + 0.3 * sin(frame * 10 + main_particles.particles['phase'][i])
main_particles.particles['color'][i, 0] = 1.0 # R
main_particles.particles['color'][i, 1] = 0.1 + 0.1 * pulse # G
main_particles.particles['color'][i, 2] = 0.1 + 0.1 * pulse # B
main_particles.particles['color'][i, 3] = 0.6 + 0.2 * pulse # A· 使用正弦函数创造颜色脉动效果 · 每个粒子有独立的相位,创造错落有致的视觉效果
6. HSV色彩空间使用
# 颜色变化
hue = (frame * 0.05 + main_particles.particles['phase'][i]) % 1.0
r, g, b = hsv_to_rgb(hue, 0.8, 1.0)
main_particles.particles['color'][i, 0] = r
main_particles.particles['color'][i, 1] = g
main_particles.particles['color'][i, 2] = b· 使用HSV色彩空间实现平滑的颜色渐变 · 色调随时间变化,创造彩虹般的效果
7. 闪烁粒子特效
# 闪烁效果
sparkle = 0.2 + 0.8 * abs(sin(frame * 15 + sparkle_particles.particles['phase'][i]))
sparkle_particles.particles['color'][i, 3] = sparkle
sparkle_particles.particles['size'][i] = 1 + 4 * sparkle· 使用绝对值正弦函数创造尖锐的闪烁效果 · 大小和透明度同步变化,增强闪烁感
8. 文字动画
# 文字效果
text_pulse = 0.7 + 0.3 * sin(frame * 4)
text.set_color((1.0, 1.0, 1.0, text_pulse))
text.set_position((0, -20 + 0.5 * sin(frame * 2)))· 文字透明度和位置都有动画效果 · 增加整体动态感和氛围感
特效亮点
这个代码创造了非常复杂且氛围感十足的跳动爱心效果,适合用于浪漫场景或艺术展示。你可以通过调整粒子数量、颜色参数和动画频率来定制不同的视觉效果。