先介绍下 Pygame 绘制烟花的基本原理,烟花从发射到绽放一共分为三个阶段:

1,发射阶段:在这一阶段烟花的形状是线性向上,通过设定一组大小不同、颜色不同的点来模拟“向上发射” 的运动运动,运动过程中 5个点被赋予不同大小的加速度,随着时间推移,后面的点会赶上前面的点,最终所有点会汇聚在一起,处于 绽放准备阶段;

2,烟花绽放:烟花绽放这个阶段,是由一个点分散多个点向不同方向发散,并且每个点的移动轨迹可需要被记录,目的是为了追踪整个绽放轨迹。

3,烟花凋零,此阶段负责描绘绽放后烟花的效果,绽放后的烟花,而在每一时刻点的下降速度和亮度(代码中也叫透明度)是不一样的,因此在代码里,将烟花绽放后将每个点赋予两个属性:分别为重力向量和生命周期,来模拟烟花在不同时期时不同的展现效果。

程序运行截图:

 完整程序代码:

import pygamefrom random import randint, uniform, choiceimport mathvector = pygame.math.Vector2gravity = vector(0, 0.3)DISPLAY_WIDTH = DISPLAY_HEIGHT = 800trail_colours = [(45, 45, 45), (60, 60, 60), (75, 75, 75), (125, 125, 125), (150, 150, 150)]dynamic_offset = 1static_offset = 3class Firework:def __init__(self):# 随机颜色self.colour = (randint(0, 255), randint(0, 255), randint(0, 255))self.colours = ((randint(0, 255), randint(0, 255), randint(0, 255)),(randint(0, 255), randint(0, 255), randint(0, 255)),(randint(0, 255), randint(0, 255), randint(0, 255)))self.firework = Particle(randint(0, DISPLAY_WIDTH), DISPLAY_HEIGHT, True,self.colour) # Creates the firework particleself.exploded = Falseself.particles = []self.min_max_particles = vector(100, 225)def update(self, win): # called every frameif not self.exploded:self.firework.apply_force(gravity)self.firework.move()for tf in self.firework.trails:tf.show(win)self.show(win)if self.firework.vel.y >= 0:self.exploded = Trueself.explode()else:for particle in self.particles:particle.apply_force(vector(gravity.x + uniform(-1, 1) / 20, gravity.y / 2 + (randint(1, 8) / 100)))particle.move()for t in particle.trails:t.show(win)particle.show(win)def explode(self):# amount 数量amount = randint(self.min_max_particles.x, self.min_max_particles.y)for i in range(amount):self.particles.append(Particle(self.firework.pos.x, self.firework.pos.y, False, self.colours))def show(self, win):pygame.draw.circle(win, self.colour, (int(self.firework.pos.x), int(self.firework.pos.y)), self.firework.size)def remove(self):if self.exploded:for p in self.particles:if p.remove is True:self.particles.remove(p)if len(self.particles) == 0:return Trueelse:return Falseclass Particle:def __init__(self, x, y, firework, colour):self.firework = fireworkself.pos = vector(x, y)self.origin = vector(x, y)self.radius = 20self.remove = Falseself.explosion_radius = randint(5, 18)self.life = 0self.acc = vector(0, 0)# trail variablesself.trails = [] # stores the particles trail objectsself.prev_posx = [-10] * 10 # stores the 10 last positionsself.prev_posy = [-10] * 10 # stores the 10 last positionsif self.firework:self.vel = vector(0, -randint(17, 20))self.size = 5self.colour = colourfor i in range(5):self.trails.append(Trail(i, self.size, True))else:self.vel = vector(uniform(-1, 1), uniform(-1, 1))self.vel.x *= randint(7, self.explosion_radius + 2)self.vel.y *= randint(7, self.explosion_radius + 2)# 向量self.size = randint(2, 4)self.colour = choice(colour)# 5 个 tails总计for i in range(5):self.trails.append(Trail(i, self.size, False))def apply_force(self, force):self.acc += forcedef move(self):if not self.firework:self.vel.x *= 0.8self.vel.y *= 0.8self.vel += self.accself.pos += self.velself.acc *= 0if self.life == 0 and not self.firework: # check if particle is outside explosion radiusdistance = math.sqrt((self.pos.x - self.origin.x) ** 2 + (self.pos.y - self.origin.y) ** 2)if distance > self.explosion_radius:self.remove = Trueself.decay()self.trail_update()self.life += 1def show(self, win):pygame.draw.circle(win, (self.colour[0], self.colour[1], self.colour[2], 0), (int(self.pos.x), int(self.pos.y)),self.size)def decay(self): # random decay of the particlesif 50 > self.life > 10: # early stage their is a small chance of decayran = randint(0, 30)if ran == 0:self.remove = Trueelif self.life > 50:ran = randint(0, 5)if ran == 0:self.remove = Truedef trail_update(self):self.prev_posx.pop()self.prev_posx.insert(0, int(self.pos.x))self.prev_posy.pop()self.prev_posy.insert(0, int(self.pos.y))for n, t in enumerate(self.trails):if t.dynamic:t.get_pos(self.prev_posx[n + dynamic_offset], self.prev_posy[n + dynamic_offset])else:t.get_pos(self.prev_posx[n + static_offset], self.prev_posy[n + static_offset])class Trail:def __init__(self, n, size, dynamic):self.pos_in_line = nself.pos = vector(-10, -10)self.dynamic = dynamicif self.dynamic:self.colour = trail_colours[n]self.size = int(size - n / 2)else:self.colour = (255, 255, 200)self.size = size - 2if self.size < 0:self.size = 0def get_pos(self, x, y):self.pos = vector(x, y)def show(self, win):pygame.draw.circle(win, self.colour, (int(self.pos.x), int(self.pos.y)), self.size)def update(win, fireworks):for fw in fireworks:fw.update(win)if fw.remove():fireworks.remove(fw)pygame.display.update()def main():pygame.init()pygame.font.init()pygame.display.set_caption("Fireworks in Pygame") # 标题background = pygame.image.load("img/1.png") # 背景myfont = pygame.font.Font("img/simkai.ttf",80)myfont1 = pygame.font.Font("img/simkai.ttf", 30)testsurface = myfont.render("新年快乐",False,(251, 59, 85))testsurface1 = myfont1.render("By:Python代码大全", False, (251, 59, 85))# pygame.image.load("")win = pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT))# win.blit(background)clock = pygame.time.Clock()fireworks = [Firework() for i in range(2)] # create the first fireworksrunning = Truewhile running:clock.tick(60)for event in pygame.event.get():if event.type == pygame.QUIT:running = Falseif event.type == pygame.KEYDOWN: # Change game speed with number keysif event.key == pygame.K_1: # 按下 1fireworks.append(Firework())if event.key == pygame.K_2: # 按下 2 加入10个烟花for i in range(10):fireworks.append(Firework())win.fill((20, 20, 30)) # draw backgroundwin.blit(background,(0,0))win.blit(testsurface,(200,30))win.blit(testsurface1, (520,80))if randint(0, 20) == 1: # create new fireworkfireworks.append(Firework())update(win, fireworks)# stats for fun# total_particles = 0# for f in fireworks:# total_particles += len(f.particles)# print(f"Fireworks: {len(fireworks)}\nParticles: {total_particles}\n\n")pygame.quit()quit()main()

程序所需的素材包:

更多源码持续更新....

知道你对源码感兴趣,所以你可以通过下方v信二维码获取【100%免费】

2023年2.14情人节最浪漫的表白烟花,送给自己的脑婆(源码)相关推荐

  1. 2023微信社区小程序+APP+后台,附带超详细完整搭建教程【源码+教程】

    2023微信社区小程序+APP+后台,附带超详细完整搭建教程[源码+教程] 微信授权登陆正常,小程序和APP带后台 手机号登陆正常,发帖,建圈子.发活动. 微信小程序是一种轻量级的应用程序,可以在微信 ...

  2. 在Ubuntu 14.04 64bit上编译并研究State Threads网络线程库源码

    State Threads是一个广受关注的高性能网络线程库,winlin在SRS中做了比较充分的应用,我很遗憾直到现在才精心研究它.下面是我的研究实录,以作备忘. 一.源码编译 下面是在Ubuntu ...

  3. 浪漫婚礼表白PPT送给幸福的你

    随着时代的发展,互联网科技的发展,就连表白方式也得到提升呢.比如可以有时尚浪漫的表白PPT,里面可以融入双方相识.相恋.相知.相守和难忘的点滴故事情节--这个表白相对于那些老套的情书,不失为一种新颖别 ...

  4. 程序员的硬核浪漫 — 女友专属语聊房(内附源码)

    人人都说找个程序猿做男朋友就是好,钱多话少 over 早. 额...估计小编把文章发布出去后就要被公司的程序猿同胞们疯狂逮捕挨打了. 虽然日常生活中大家对程序猿的标签大多是呆板.木讷.不懂浪漫,格子衫 ...

  5. 【转】Ubuntu 14.04.3上配置并成功编译Android 6.0 r1源码

    http://www.linuxidc.com/Linux/2016-01/127292.htm 终于成功把Android 6.0 r1源码的源码编译.先上图,这是在Ubuntu中运行的Android ...

  6. 2023最新微官网美食订餐HTML5触屏响应式手机Wap模板源码

    正文: 一款微官网美食订餐模板,html5触屏响应式手机端,欧美风格,共有9个页面,分别为:首页.新闻列表.图标按钮UI.美食列表.图片列表.留言板,联系等等. 程序: wwxsyd.lanzout. ...

  7. 2023最新透明UI素颜个人导航网官网永久发布页HTML源码+支持WAP响应式

    正文: 一款单页的网址发布页单页HTML模板,支持响应式显示,可用于网址发布页使用,本模板简约商务,页面精美没有花里胡哨的效果,喜欢的可以自己拿去安装体验吧. 程序: wwxskw.lanzoul.c ...

  8. 2023自适应网址导航网站发布页单页网页模板HTML静态无后台源码

    正文: 超级好看自适应清新网址导航网站发布页单页网页模板html源码!无论电脑还是手机,可以看看演示!这是一个网页单页源码!! 模板无后台模板,无需数据库,上传服务器直接能用, 程序: wweoeg. ...

  9. 2.14情人节,程序员该如何绝地反击?

    导读:掐指一算,距离2.14情人节已经只剩下几小时.还没来得及准备的人,要么被打断腿,要么注孤生. 目测已经有一大批直男,死在了口嗨撩妹的路上-- 作者:丁彦军 来源:恋习Python(ID:slda ...

最新文章

  1. 古城钟楼微博:葡萄城程序员演练技术的产物
  2. ASP.NET面试题目大全(非常经典、吐血推荐)
  3. python -- join()
  4. python设置label的位置_Python3 tkinter基础 Label pack 设置控件在窗体中的位置
  5. 以数据库思维理解区块链
  6. 使用svn进行本地代码管理
  7. 算法导论 思考题6-3(Young氏矩阵)
  8. fprom预测结果内容_生物标志物联合OCT预测ACS患者再发冠脉事件|博“冠”精点...
  9. 浏览器市场 Chrome 仍占主导地位,IE 继续下降
  10. 33.4. Gearman
  11. android计算汇率代码,android studio 开发实例 连接网络获取汇率
  12. 《Netty实战》总结
  13. 变焦和对焦_在Randonautica内部,该应用程序可带领变焦器发现彩虹,尸体和隐藏的宝藏
  14. 2018年已经过了一半,你还记得年初时候定的小目标么——致已经逝去的2018上半年
  15. Bitbucket安装配置
  16. 宽带,猫,路由器的关系是什么?
  17. SparkMLlib简介
  18. 人大金仓数据库:睡在甲骨文卧榻之侧
  19. 国庆七连测(一)BREAD
  20. JAVA17安装体验JFX17抢先体验

热门文章

  1. 让logo设计更有设计感的几个方法
  2. 商业综合体电气综合管理平台技术方案
  3. PLC抑制干扰电路的设计
  4. 计算机二级Python选择题真题第一套,计算机二级Python考试题库
  5. Go + Redis 实现分布式锁
  6. 故宫元宵灯会黄牛票最高要5千 律师:小心被拒
  7. 光学设计ZEMAX——什么是MF、RMS均方根点半径
  8. Mac上绘制流程图的软件
  9. jira是干什么_Jira 概述 | 产品、项目和托管 | Atlassian
  10. 稀疏数组练习demo 数据结构和算法