当前位置:首页>python>用 Python 写一场浪漫烟花爱心, 直接刷屏朋友圈!

用 Python 写一场浪漫烟花爱心, 直接刷屏朋友圈!

  • 2026-09-02 18:50:58
用 Python 写一场浪漫烟花爱心, 直接刷屏朋友圈!

💘 谁能拒绝一场用代码写的浪漫?

520、情人节、纪念日,想给 TA 一个不一样的惊喜?送花太俗、转账太硬,不如用一行行代码,为 TA 绽放一场专属的粉色烟花爱心。

当屏幕上无数粉色粒子从底部腾空而起,像烟花一样划过轨迹,最终在屏幕中央汇聚成一颗饱满立体的爱心,中间缓缓亮起闪烁的「LOVE」字样 —— 这是程序员独有的浪漫,也是最戳人的告白。

今天就手把手教你,用 Python 实现这个超炫酷的烟花爱心特效,零基础也能直接上手!


✨ 效果先睹为快

  • ✅ 真实烟花升空:粒子从底部发射,带抛物线轨迹 + 超长拖尾,氛围感拉满
  • ✅ 饱满立体爱心:双层粒子结构,轮廓完整无缺口,内部实心填满,一眼就是爱心
  • ✅ 动态呼吸特效:爱心 + 文字同步闪烁,自带柔光光晕,梦幻感拉满
  • ✅ 自定义文字:中间可替换成「我爱你」「520」等专属告白语
  • ✅ 无限循环播放:自动循环,可直接做成视频、壁纸,氛围感直接拉满

🧠 实现原理拆解(小白也能懂)

这个特效的核心,其实是三个超简单的知识点,组合起来就是满满的浪漫:

1. 爱心的数学密码:笛卡尔心形线

这颗爱心不是画出来的,是算出来的!用经典的笛卡尔心形曲线参数方程,就能生成一个标准的爱心轮廓:

x=16sin3(t)

y=−(13cos(t)−5cos(2t)−2cos(3t)−cos(4t))

我们只需要让所有粒子,最终精准飞到这个方程对应的坐标上,就能完美汇聚成爱心。

2. 烟花的物理模拟:抛物线升空

粒子从屏幕底部出发,模拟真实烟花的运动轨迹:

  • 给粒子一个向上的初速度,模拟发射
  • 施加重力加速度,让粒子做抛物线运动,更有真实感
  • 当粒子飞到爱心坐标附近时,停止运动,固定成爱心形状

3. 粒子系统:分层渲染,饱满不空洞

为了让爱心不空心、不松散,我们用双层粒子结构:

  • 填充层
    :1500 + 粒子直接铺满爱心内部,保证实心饱满
  • 轮廓层
    :800 + 粒子精准勾勒爱心边缘,保证形状完整无缺口
  • 再加上拖尾、光晕、呼吸闪烁特效,直接把氛围感拉满

🚀 完整可运行代码(直接复制)

只需要 3 步,就能拥有属于你的浪漫:

  1. 安装依赖:pip install pygame
  2. 复制下面的代码,保存为heart_firework.py
  3. 直接运行,就能看到超炫酷的烟花爱心!
import pygameimport mathimport randomimport sys# ================= 基础配置 =================pygame.init()WIDTH = 1000HEIGHT = 750screen = pygame.display.set_mode((WIDTH, HEIGHT))pygame.display.set_caption("🎆 浪漫烟花爱心 🎆")clock = pygame.time.Clock()FPS = 60# 颜色系统BLACK = (0, 0, 0)HEART_MAIN = (255, 0, 100)HEART_GLOW = (255, 120, 200)TRAIL_COLOR = (255, 150, 210)# ================= 文字配置(可自定义) =================TEXT_CONTENT = "LOVE"  # 可替换为「我爱你」「520」等FONT_SIZE = 72# 兼容全系统字体加载try:    FONT = pygame.font.SysFont("SimHei", FONT_SIZE)except:    FONT = pygame.font.Font(None, FONT_SIZE)# 预渲染文字,保证居中TEXT_SURFACE = FONT.render(TEXT_CONTENT, True, (255, 255, 255))TEXT_RECT = TEXT_SURFACE.get_rect(center=(WIDTH//2, HEIGHT//2 + 60))# ================= 爱心数学工具(预生成完整轮廓) =================HEART_POINTS = []HEART_SCALE = 22HEART_CENTER = (WIDTH//2, HEIGHT//2 - 30)# 预生成1000个均匀分布的爱心轮廓点,保证形状完整无缺口for t in range(0, 1000):    t = t / 1000 * 2 * math.pi    x = 16 * math.sin(t) ** 3    y = -(13 * math.cos(t) - 5 * math.cos(2*t) - 2 * math.cos(3*t) - math.cos(4*t))    HEART_POINTS.append((        HEART_CENTER[0] + x * HEART_SCALE,        HEART_CENTER[1] + y * HEART_SCALE    ))# 生成爱心内部填充点(保证实心饱满)FILL_POINTS = []for _ in range(1500):    t = random.uniform(0, 2 * math.pi)    scale = random.uniform(0, HEART_SCALE * 0.9)    x = 16 * math.sin(t) ** 3    y = -(13 * math.cos(t) - 5 * math.cos(2*t) - 2 * math.cos(3*t) - math.cos(4*t))    FILL_POINTS.append((        HEART_CENTER[0] + x * scale,        HEART_CENTER[1] + y * scale    ))# ================= 粒子类(核心逻辑) =================class Particle:    def __init__(self, is_fill=False):        self.is_fill = is_fill        self.reset()    def reset(self):        if not self.is_fill:            # 轮廓粒子:从底部发射,精准飞向爱心轮廓            self.x = random.uniform(WIDTH * 0.2, WIDTH * 0.8)            self.y = HEIGHT + random.uniform(20, 80)            self.vx = random.uniform(-0.8, 0.8)            self.vy = random.uniform(-16, -12)            self.gravity = 0.13            self.target_idx = random.randint(0, len(HEART_POINTS)-1)            self.tx, self.ty = HEART_POINTS[self.target_idx]            self.size = random.uniform(3, 5.5)            self.alpha = 255            self.state = 0  # 0=升空 1=凝聚            self.timer = 0            self.phase = random.uniform(0, 2 * math.pi)            self.trail = []        else:            # 填充粒子:直接生成在爱心内部,保证实心饱满            idx = random.randint(0, len(FILL_POINTS)-1)            self.x, self.y = FILL_POINTS[idx]            self.size = random.uniform(1.5, 3.5)            self.alpha = random.randint(180, 255)            self.phase = random.uniform(0, 2 * math.pi)            self.state = 1    def update(self):        if self.is_fill:            # 填充粒子:仅做轻微呼吸,保持爱心实心            self.phase += 0.05            self.alpha = int(180 + 75 * math.sin(self.phase))            self.x += math.sin(self.phase) * 0.2            self.y += math.cos(self.phase) * 0.2            return        # 轮廓粒子状态机        if self.state == 0:            # 阶段1:升空(精准飞向目标点)            self.vy += self.gravity            self.x += self.vx            self.y += self.vy            self.trail.append((self.x, self.y))            if len(self.trail) > 15:                self.trail.pop(0)            dist = math.hypot(self.x - self.tx, self.y - self.ty)            if dist < 25:                self.state = 1                self.vx = 0                self.vy = 0                self.trail.clear()        else:            # 阶段2:凝聚(轻微浮动,保持轮廓完整)            self.timer += 1            self.phase += 0.06            swing = math.sin(self.phase) * 1.2            self.x = self.tx + swing            self.y = self.ty + swing * 0.6            self.alpha = int(200 + 55 * math.sin(self.phase))            if self.timer > 180:                self.reset()    def draw(self, surface):        if self.is_fill:            # 绘制填充粒子            color = (*HEART_MAIN, self.alpha)            pygame.draw.circle(surface, color, (int(self.x), int(self.y)), int(self.size))            return        # 绘制轮廓粒子拖尾        if len(self.trail) > 0:            for i, (px, py) in enumerate(self.trail):                a = int(120 * (i / len(self.trail)))                color = (*TRAIL_COLOR, a)                pygame.draw.circle(surface, color, (int(px), int(py)), int(self.size * 0.4))        # 绘制轮廓粒子本体        color = (*HEART_MAIN, self.alpha)        s = pygame.Surface((int(self.size*2), int(self.size*2)), pygame.SRCALPHA)        pygame.draw.circle(s, color, (int(self.size), int(self.size)), int(self.size))        surface.blit(s, (int(self.x - self.size), int(self.y - self.size)))        # 绘制光晕(仅凝聚状态显示)        if self.state == 1:            glow_a = int(60 + 30 * math.sin(self.phase))            glow = pygame.Surface((int(self.size*6), int(self.size*6)), pygame.SRCALPHA)            glow_color = (*HEART_GLOW, glow_a)            pygame.draw.circle(glow, glow_color, (int(self.size*3), int(self.size*3)), int(self.size*3))            surface.blit(glow, (int(self.x - self.size*3), int(self.y - self.size*3)))# ================= 主程序 =================outline_particles = [Particle(is_fill=False) for _ in range(800)]fill_particles = [Particle(is_fill=True) for _ in range(1500)]running = Truewhile running:    clock.tick(FPS)    screen.fill(BLACK)    for event in pygame.event.get():        if event.type == pygame.QUIT:            running = False        if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:            running = False    # 分层渲染:填充层 → 轮廓层 → 文字层    for p in fill_particles:        p.update()        p.draw(screen)    for p in outline_particles:        p.update()        p.draw(screen)    # 绘制文字(最上层,不被遮挡)    time = pygame.time.get_ticks() * 0.001    text_alpha = int(200 + 55 * math.sin(time))    text_surf = TEXT_SURFACE.copy()    text_surf.set_alpha(text_alpha)    screen.blit(text_surf, TEXT_RECT)    pygame.display.flip()pygame.quit()sys.exit()

🎨 自定义小技巧(一键改出专属浪漫)

拿到代码不用慌,几个参数就能改成你的专属告白:

1. 改中间的告白文字

找到这行代码,直接替换成你想说的话:

TEXT_CONTENT = "LOVE"  # 改成「我爱你」「520」「XX我喜欢你」

2. 改爱心大小

调整爱心缩放系数,爱心想多大就多大:

HEART_SCALE = 22  # 数字越大,爱心越大

3. 改文字大小

调整字体大小,让文字更醒目:

FONT_SIZE = 72  # 数字越大,文字越大

4. 改爱心颜色

把粉色换成你喜欢的颜色,比如紫色、红色:

HEART_MAIN = (255, 0, 100)  # 主色,改成(200, 0, 200)就是紫色

🎬 玩法升级:把代码变成告白神器

代码跑起来只是第一步,这些玩法直接让浪漫拉满:

  1. 录屏做成告白视频
    :用 OBS 录下运行过程,配上浪漫 BGM,直接发朋友圈 / 发给 TA
  2. 做成电脑壁纸
    :用 Wallpaper Engine 加载,把浪漫设为电脑桌面
  3. 嵌入表白网页
    :把代码转成 HTML5 版本,做一个专属告白网页
  4. 定制化修改
    :可以在爱心中间加上对方的名字、纪念日,专属感拉满

💡 写在最后

最好的浪漫,从来不是昂贵的礼物,而是用心的创造。一行行代码,不仅是技术的体现,更是藏在细节里的温柔。这个 520,用一场代码写的烟花爱心,给 TA 一个永远不会褪色的浪漫吧。


📢 互动福利

评论区留下你想在爱心中间显示的文字,一起交流学习!!!

最新文章

随机文章