您的位置:首页 > 脚本大全 > > 正文

python樱花绽放代码(新年快乐! python实现绚烂的烟花绽放效果)

更多 时间:2022-04-02 16:32:01 类别:脚本大全 浏览量:2959

python樱花绽放代码

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

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

一.编译环境

pycharm

二.模块

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

2.pil:python imaging library,是python平台的图像处理标准模块。在python3也是自带的,在这个项目中用于背景图片的导入。

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

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

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

三.效果

python樱花绽放代码(新年快乐! python实现绚烂的烟花绽放效果)

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

四.代码

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

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • import tkinter as tk
  • from pil import image,imagetk
  • from time import time,sleep
  • from random import choice,uniform,randint
  • from math import sin,cos,radians
  • #重力变量
  • gravity=0.5
  • #listof colors,can choose randomly or use as queue(fifo
  • colors=['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 canvas
  •  
  • attributes(属性):
  • 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" alt="python樱花绽放代码(新年快乐! python实现绚烂的烟花绽放效果)" border="0" />)
  •   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.增加文字绘制功能,在背景图中隐藏有字样,烟花绽放后落于字样中的粒子不消失,而是定格在窗口中。

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

    原文链接:https://blog.csdn.net/Mou_Yang/article/details/85091181

    标签:Python 烟花
    您可能感兴趣