侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

新年快乐! python实现绚烂的烟花绽放效果

Python  /  管理员 发布于 7年前   204

做了一个Python的小项目。利用了一点python的可视化技巧,做出烟花绽放的效果,文章的灵感来自网络上一位大神。

一.编译环境

Pycharm

二.模块

1.tkinter:这个小项目的主角,是一个python图形模块。且Python3已经自带了该模块,不用另外安装。它有点像java中的swing图形模块(由众多组件集成,组件通过创建实例添加,组件通过坐标定位在窗口上)。

2.PIL:Python Imaging Library,是Python平台的图像处理标准模块。在Python3也是自带的,在这个项目中用于背景图片的导入。

3.time:相信这个模块大家都不会陌生,导入它用来控制烟花的绽放,坠落及消失时间。

4.random:随机数模块,用于生成烟花随机坐标点,随机绽放速度,随机消失时间。

5.math:这个模块大家应该也很熟悉了,导入它的目的是使烟花绽放的粒子以一定角度散开。

三.效果

项目最终实现的效果就跟上面一样了。

四.代码

以下是我学习(copy)了那位大神的代码,再添加了一些浅显的注解。

import tkinter as tkfrom PIL import Image,ImageTkfrom time import time,sleepfrom random import choice,uniform,randintfrom math import sin,cos,radians#重力变量GRAVITY=0.5#listof colors,can choose randomly or use as queue(FIFOcolors=['red','blue','yellow','white','green','orange','purple','seagreen','indigo','cornflowerblue']'''create a class for particles粒子particles are emitted almost randomly on the sky,forming around(组成一个圈) of circle(a star)before falling and getting removed from canvasAttributes(属性):id:每个特定烟花的标识符x,y:烟花的绽放坐标vx,vy:烟花的绽放速度total:一颗烟花里的星星总数age:一颗星星会在画布上停留多久color:自我移植cv:画布lifespan:星星在画布上停留的最后时间'''class part:#为每一个烟花绽放出来的粒子单独构建一个类的对象 def __init__(self,cv,idx,total,explosion_speed,x=0.,y=0.,vx=0.,vy=0.,size=2.,color='red',lifespan=2,**kwargs):  self.id=idx#每个烟花的特定标识符  self.x=x#烟花的绽放x轴  self.y=y#烟花的绽放x轴  self.initial_speed=explosion_speed#初速度  self.vx=vx#外放x轴速度  self.vy=vy#外放y轴速度  self.total=total#绽放的粒子数  self.age=0#已停留时间  self.color=color#颜色  self.cv=cv#画布  self.cid=self.cv.create_oval(x-size,y-size,x+size,y+size,fill=self.color)#create_oval()创建一个椭圆,参数为左上x,左上y,右下x,右下y,填满的颜色,该函数返回一个id  self.lifespan=lifespan#应该停留时间 def update(self,dt):#更新数据,已停留时间增加  self.age+=dt  #粒子膨胀  if self.alive() and self.expand():#如果停留时间(2s)足够&&膨胀时间(1.2s)足够   move_x=cos(radians(self.id*360/self.total))*self.initial_speed#粒子的x轴继续膨胀   move_y=sin(radians(self.id*360/self.total))*self.initial_speed#粒子的y轴继续膨胀   self.cv.move(self.cid, move_x, move_y)#根据id把画布上的粒子移动x和y个距离   self.vx=move_x/(float(dt)*1000)  #以自由落体坠落  elif self.alive():#如果只是停留时间足够,说明膨胀到最大了,应该准备下坠   move_x=cos(radians(self.id*360/self.total))#x轴继续膨胀   self.cv.move(self.cid,self.vx+move_x,self.vy+GRAVITY*dt)#而y轴按照重力因素做落体运动,但实际上这个重力是v而不是a   self.vy+=GRAVITY*dt#更新一下y轴  elif self.cid is not None:#如果粒子的生命周期已过,就将其移除   cv.delete(self.cid)#删除该粒子对象   self.cid=None #定义膨胀效果的时间帧 def expand(self):  return self.age<=1.2#膨胀时间小于1.2s #检查粒子是否仍在生命周期内 def alive(self):#已停留时间是不是比应该停留时间短  return self.age<=self.lifespan'''烟花模拟回路:递归调用来在画布上重复发出新的烟火通过每个“部件”对象内部的更新协议,每次调用时都要在画布上创建并绘制列表(星列表,每个星列表成员都是粒子列表)来重复地在画布上发出新的焰火'''#生成新的一轮爆炸def simulate(cv): t=time()#time()函数返回自1970年后经过的浮点秒数,精确到小数点后6位 explode_points=[]#爆炸点列表--烟花列表 wait_time=randint(10,100)#随机生成一个int n,10<=n<=100 numb_explode=randint(6,10)#爆炸的个数是6~10 #为所有模拟烟花绽放的全部例子创建一列列表 for point in range(numb_explode):#遍历爆炸的个数  objects=[]#这是每个点的爆炸粒子列表  x_cordi=randint(50,550)#每个点的爆炸x轴  y_cordi=randint(50,150)#爆炸y轴  speed=uniform(0.5,1.5)#随机生成一个float speed,0.5<=speed<1.5  size=uniform(0.5,3)#随机生成一个float size,0.5<=size<3  color=choice(colors)#choice()是python内置函数,随机返回元组,列表,或字符串的一个成员  explosion_speed=uniform(0.2,1)#爆炸的绽放速度也要随机出来  total_particles=randint(10,50)#爆炸出来的粒子数半径也随机  for i in range(1,total_particles):#同一个烟花爆炸出来的粒子的大小,速度,坐标都是相同的   r = part(cv, idx=i, total=total_particles, explosion_speed=explosion_speed, x=x_cordi, y=y_cordi,    vx=speed, vy=speed, color=color, size=size, lifespan=uniform(0.6, 1.75))#把上述参数带入,但他们每个粒子的生存时间是自己独立的   objects.append(r)#添加进粒子列表里  explode_points.append(objects)#把该粒子列表添加进烟花列表里 total_time=.0#先把时间置0 #在1.8秒时间帧内保持更新 while total_time<1.8:  sleep(0.01)#让画面暂停0.01s  tnew=time()#刷新时间  t,dt=tnew,tnew-t#时间等于新时间,与上次时间间隔为tnew-t  for point in explode_points:#遍历烟花列表   for item in point:#遍历烟花里的粒子列表    item.update(dt)#更新时间  cv.update()#刷新页面  total_time+=dt#为上面的while循环增加时间 root.after(wait_time,simulate,cv)#将组件置于其他组件之后,就是放在最顶层,覆盖下面的,这里递归第哦啊用了自己,形成新的一轮爆炸def close(*ignore): #打开模拟循环并关闭窗口 global root root.quit()if __name__=="__main__": root=tk.Tk() cv=tk.Canvas(root,height=600,width=700)#绘制一个画布 #绘制一个黑色背景 #cv.create_rectangle(0,0,600,600,fill="black") #use a nice background image image=Image.open("L:\PyCharm Community Edition 2018.2.2\Python_program\image.jpg") photo=ImageTk.PhotoImage(image) cv.create_image(0,0,image=photo,anchor='nw')#在画板上绘制一张图片 cv.pack()#把cv添加进去 root.protocol("WM_DELETE_WINDOW",close) #在0.1s后才开始调用stimulate() root.after(100,simulate,cv)#调用stimulate生成一轮烟花绽放效果 root.mainloop()#执行root,生成窗口#让我更加明白了python的一切皆对象

五.结尾

这篇博客暂时就这样,如果有机会会重新做一遍,不过最大的可能就是遥遥无期了。先打算对项目做如下修改:

1.增加鼠标交互功能,用户鼠标点击位置额外生成烟花绽放;

2.增加文字绘制功能,在背景图中隐藏有字样,烟花绽放后落于字样中的粒子不消失,而是定格在窗口中。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


  • 上一条:
    python实现浪漫的烟花秀
    下一条:
    python+selenium 定位到元素,无法点击的解决方法
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客