当前位置:首页>python>用Python写一场浪漫奔赴|5000个粒子,汇聚成藏在屏幕里的爱心

用Python写一场浪漫奔赴|5000个粒子,汇聚成藏在屏幕里的爱心

  • 2026-09-08 22:56:45
用Python写一场浪漫奔赴|5000个粒子,汇聚成藏在屏幕里的爱心

谁懂啊!用代码表达浪漫,真的太戳人了✨

没有复杂的道具,没有华丽的辞藻,一行行代码、5000个彩色粒子,从四面八方奔赴而来,慢慢汇聚成一颗跳动的爱心,带着呼吸感、光晕和温柔的拖尾,把藏在心底的温柔,都藏进了屏幕里。

今天就带大家手把手实现「粒子汇聚爱心」效果,用Pygame+Numpy,零基础也能get的浪漫代码,不管是自己玩、做桌面壁纸,还是发给喜欢的人,都足够惊艳~


先看效果!心动预警💖

粒子从屏幕底部随机出现,带着淡淡的粉紫色光晕,缓缓向上移动,一点点靠近、汇聚,最终组成一颗完整的爱心;爱心会跟着呼吸轻轻缩放,每个粒子到达目标后,还会有细微的抖动,像在诉说温柔,移动过程中留下的拖尾,更添几分朦胧感。

小贴士:效果可直接作为桌面动态壁纸,也能导出成视频,发给在意的人,解锁专属浪漫~


核心工具&依赖

实现这个效果,只需要两个常用Python库,安装简单,新手也能快速上手:

  • Pygame:负责图形渲染、动画播放和交互控制,是实现粒子动效的核心;

  • Numpy:处理数学计算(比如爱心参数方程、粒子运动轨迹),让动画更流畅。

安装命令(复制到终端执行即可):

pip install pygame numpy

完整代码|直接复制可运行

代码已全部优化、注释,关键步骤都标清了,不需要修改任何参数,复制粘贴到Python编辑器(PyCharm、VS Code都可以),运行就能看到效果👇

import pygameimport numpy as npimport random# 初始化 pygamepygame.init()# 屏幕设置(高清分辨率,效果更细腻)WIDTH, HEIGHT = 1200, 800screen = pygame.display.set_mode((WIDTH, HEIGHT))pygame.display.set_caption("粒子汇聚爱心")clock = pygame.time.Clock()# 颜色定义(接近截图的粉紫色系)BLACK = (0, 0, 0)PINK = (255, 105, 180)  # 亮粉LIGHT_PINK = (255, 182, 193)  # 淡粉PURPLE = (186, 85, 211)  # 淡紫PALE_PURPLE = (220, 180, 220)  # 淡粉紫# 爱心参数方程(经典数学公式)def heart_shape(t, scale=1, offset_x=0, offset_y=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 + offset_x, -y * scale + offset_y# 粒子类(集成呼吸、拖尾、光晕逻辑)class Particle:    def __init__(self, target_x, target_y, global_scale):        self.target_x = target_x        self.target_y = target_y        self.global_scale = global_scale  # 引用全局呼吸缩放值        # 初始位置:屏幕底部随机(模拟从下方汇聚)        self.x = random.randint(0, WIDTH)        self.y = HEIGHT + random.randint(100, 300)        # 物理属性        self.speed = random.uniform(0.8, 2.2)        self.acceleration = 0.12        self.vx, self.vy = 0.0, 0.0        self.arrived = False        # 视觉属性        self.base_color = random.choice([PINK, LIGHT_PINK, PURPLE, PALE_PURPLE])        self.size = random.randint(1, 4)        self.alpha = random.uniform(0.7, 1.0)  # 透明度        self.wobble_phase = random.uniform(0, np.pi * 2)  # 粒子独立抖动相位    def update(self, current_scale):        # 更新全局缩放引用(实现呼吸效果)        self.global_scale = current_scale        # 目标位置随爱心缩放同步变化        scaled_target_x = self.target_x * (self.global_scale / 12)  # 基准scale=12        scaled_target_y = self.target_y * (self.global_scale / 12)        if not self.arrived:            # 计算方向向量            dx = scaled_target_x - self.x            dy = scaled_target_y - self.y            dist = np.sqrt(dx ** 2 + dy ** 2)            if dist < 3:  # 到达阈值(更宽松,汇聚更丝滑)                self.arrived = True                self.x = scaled_target_x                self.y = scaled_target_y                return            # 归一化方向 + 加速度            dx /= dist            dy /= dist            self.vx += dx * self.acceleration            self.vy += dy * self.acceleration            # 限制最大速度            vel_mag = np.sqrt(self.vx ** 2 + self.vy ** 2)            if vel_mag > self.speed:                self.vx = (self.vx / vel_mag) * self.speed                self.vy = (self.vy / vel_mag) * self.speed            # 更新位置            self.x += self.vx            self.y += self.vy        else:            # 到达后:独立呼吸抖动(不影响整体缩放)            wobble_amt = 0.8 * np.sin(pygame.time.get_ticks() * 0.01 + self.wobble_phase)            self.x = scaled_target_x + wobble_amt            self.y = scaled_target_y + wobble_amt    def draw(self, screen):        # 绘制粒子本体(带透明度)        surf = pygame.Surface((self.size * 2, self.size * 2), pygame.SRCALPHA)        color = (*self.base_color, int(self.alpha * 255))        pygame.draw.circle(surf, color, (self.size, self.size), self.size)        screen.blit(surf, (int(self.x) - self.size, int(self.y) - self.size))        # 绘制外围光晕(仅到达目标的粒子)        if self.arrived:            glow_surf = pygame.Surface((self.size * 4, self.size * 4), pygame.SRCALPHA)            glow_color = (*LIGHT_PINK, int(self.alpha * 80))  # 低透明度光晕            pygame.draw.circle(glow_surf, glow_color, (self.size * 2, self.size * 2), self.size * 2)            screen.blit(glow_surf, (int(self.x) - self.size * 2, int(self.y) - self.size * 2))# 生成爱心所有目标点def generate_heart_points(num_points=5000):    t = np.linspace(0, 2 * np.pi, num_points)    # 初始基准缩放(居中显示)    return list(zip(*heart_shape(t, scale=12, offset_x=WIDTH // 2, offset_y=HEIGHT // 3)))# 主程序核心逻辑def main():    # 生成基础目标点    heart_points = generate_heart_points(num_points=5000)    # 创建粒子列表(每个点对应一个粒子)    particles = [Particle(x, y, 12.0) for x, y in heart_points]    # 拖尾效果:创建专用缓存表面(黑色半透明,实现残留轨迹)    trail_surface = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)    trail_surface.fill((*BLACK, 20))  # 透明度20:拖尾残留长度适中    # 呼吸动画参数    breath_phase = 0.0    breath_speed = 0.08  # 呼吸节奏    base_scale = 12.0  # 基础缩放    breath_range = 0.8  # 缩放幅度    running = True    while running:        # 控制帧率(60FPS,保证流畅)        clock.tick(60)        # 1. 事件处理(关闭窗口可退出)        for event in pygame.event.get():            if event.type == pygame.QUIT:                running = False        # 2. 呼吸缩放计算(正弦函数实现平滑呼吸)        current_scale = base_scale + breath_range * np.sin(breath_phase)        breath_phase += breath_speed        # 3. 绘制拖尾(底层绘制,实现轨迹残留)        screen.blit(trail_surface, (0, 0))        # 4. 更新并绘制所有粒子        for p in particles:            p.update(current_scale)            p.draw(screen)        # 5. 刷新屏幕        pygame.display.flip()    # 退出程序    pygame.quit()# 修正这行!!!前后都要有空格if __name__ == "__main__":    main()  # 这行必须缩进

关键效果拆解|新手也能看懂

不想深究代码?没关系!重点看这3个核心效果,知道它们的作用,就能轻松调整出自己喜欢的样子:

1. 爱心形状:数学公式的浪漫

用经典的爱心参数方程,通过Numpy计算出5000个目标点,这些点组成了爱心的轮廓;通过缩放和偏移,让爱心居中显示在屏幕上,还能通过调整scale参数,控制爱心的大小。

2. 粒子动效:奔赴的仪式感

每个粒子都有自己的初始位置(屏幕底部随机)、速度和颜色,它们会朝着自己对应的爱心目标点移动,到达后会轻微抖动;粒子的大小、速度、颜色都是随机的,让效果更自然、有层次感。

3. 呼吸+拖尾+光晕:氛围感神器

  • 呼吸效果:通过正弦函数控制爱心的缩放,模拟呼吸的节奏,温柔又灵动;

  • 拖尾效果:用半透明的黑色表面,让粒子移动后留下淡淡的轨迹,增加朦胧感;

  • 光晕效果:粒子到达目标后,会有一圈淡粉色的光晕,让爱心更有光泽,氛围感拉满。

小技巧|自定义你的专属爱心

想让爱心更有个性?修改这几个参数就可以,新手也能轻松操作:

  1. 调整爱心大小:找到base_scale = 12.0,数值越大,爱心越大;

  2. 改变呼吸节奏:调整breath_speed = 0.08,数值越小,呼吸越慢;

  3. 更换颜色:修改颜色定义部分的RGB值,比如换成蓝色、红色,打造不同风格;

  4. 调整粒子数量:找到generate_heart_points(num_points=5000),数值越多,爱心越饱满(建议5000-10000)。

常见问题|避坑指南

运行中遇到问题?看看这两个最常见的情况,快速解决:

  • 报错“no module named pygame/numpy”:没有安装依赖,执行前面的安装命令即可;

  • 动画卡顿:降低粒子数量(比如改成3000),或调整clock.tick(60)为clock.tick(30)。

其实代码从来都不是冰冷的,它可以是浪漫的载体,是藏在细节里的温柔。

5000个粒子的奔赴,就像我们对生活、对在意的人的热爱,一点点靠近,一点点圆满。

赶紧复制代码,运行起来,把这份专属浪漫,留给自己,或者送给那个特别的人吧~

文末福利:关注公众号,回复「爱心粒子」,获取完整代码+效果动图+壁纸导出教程,轻松解锁更多玩法~,私信我也可以哦!

💬 评论区聊聊:你想用这段代码,送给谁?

最新文章

随机文章