首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >升级版动态跳动爱心代码

升级版动态跳动爱心代码

作者头像
用户11944278
发布2025-12-23 10:19:44
发布2025-12-23 10:19:44
2640
举报

高级粒子特效跳动爱心代码

代码语言:javascript
复制
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. 多粒子系统设计

代码语言:javascript
复制
class ParticleSystem:
    def __init__(self, num_particles):
        self.num_particles = num_particles
        self.reset()

· 创建了三个独立的粒子系统:主爱心粒子、背景氛围粒子和闪烁粒子 · 每个系统有不同类型的粒子,具有不同的行为和视觉效果

2. 粒子类型分类

代码语言:javascript
复制
# 根据粒子类型设置不同属性
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. 复杂跳动效果

代码语言:javascript
复制
# 计算当前帧的跳动效果
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. 粒子生命周期管理

代码语言:javascript
复制
# 粒子生命周期
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. 颜色和透明度动画

代码语言:javascript
复制
# 粒子颜色脉动
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色彩空间使用

代码语言:javascript
复制
# 颜色变化
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. 闪烁粒子特效

代码语言:javascript
复制
# 闪烁效果
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. 文字动画

代码语言:javascript
复制
# 文字效果
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)))

· 文字透明度和位置都有动画效果 · 增加整体动态感和氛围感

特效亮点

  1. 多层粒子系统:三个独立的粒子系统创造丰富的视觉效果
  2. 复杂跳动:多频率正弦波叠加模拟真实心跳
  3. 色彩渐变:使用HSV色彩空间实现平滑的颜色过渡
  4. 独立相位:每个粒子有独立相位,创造错落有致的动画
  5. 粒子生命周期:完整的粒子重生系统保持效果持续
  6. 闪烁特效:使用绝对值正弦函数创造星光闪烁
  7. 文字动画:增强整体氛围感
  8. 边界处理:粒子在边界处反弹或重生,保持场景活跃

这个代码创造了非常复杂且氛围感十足的跳动爱心效果,适合用于浪漫场景或艺术展示。你可以通过调整粒子数量、颜色参数和动画频率来定制不同的视觉效果。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-12-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档