快到春節(jié)了,用Python來一場(chǎng)煙花秀
作者:野客
來源:Python 技術(shù)(pythonall)

實(shí)現(xiàn)
功能實(shí)現(xiàn)用到的 Python 庫(kù)包括:tkinter、PIL、time、random、math,如果之前沒有裝過第三庫(kù)的話,使用 pip install pillow 裝一下即可。
首先,我們使用 tkinter 來創(chuàng)建一個(gè)畫布,可以根據(jù)自己的喜好選一張應(yīng)景的圖片作為背景,代碼實(shí)現(xiàn)如下:
root?=?tk.Tk()
#?繪制一個(gè)畫布
cv?=?tk.Canvas(root,?height=457,?width=690)
#?背景圖
image?=?Image.open("bg.jpeg")
photo?=?ImageTk.PhotoImage(image)
#?在畫板上繪制一張圖片
cv.create_image(0,?0,?image=photo,?anchor='nw')
cv.pack()
運(yùn)行后顯示:

初始化方法主要參數(shù)包括:煙花綻放坐標(biāo)軸、速度、顏色、粒子數(shù)和時(shí)間等,代碼實(shí)現(xiàn)如下:
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
?#?煙花綻放?x?軸
?self.x?=?x
?#?煙花綻放?x?軸
?self.y?=?y
?self.initial_speed?=?explosion_speed
?#?外放?x?軸速度
?self.vx?=?vx
?#?外放?y?軸速度
?self.vy?=?vy
?#?綻放的粒子數(shù)
?self.total?=?total
?#?已停留時(shí)間
?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)
?self.lifespan =?lifespan
當(dāng)煙花燃放過后需要進(jìn)行刷新。
看一下更新方法,代碼實(shí)現(xiàn)如下:
def?update(self,?dt):
?self.age?+=?dt
?#?粒子膨脹
?if?self.alive()?and?self.expand():
??move_x?=?cos(radians(self.id?*?360?/?self.total))?*?self.initial_speed
??move_y?=?sin(radians(self.id?*?360?/?self.total))?*?self.initial_speed
??self.cv.move(self.cid,?move_x,?move_y)
??self.vx?=?move_x?/?(float(dt)?*?1000)
?#?膨脹到最大下落
?elif?self.alive():
??move_x?=?cos(radians(self.id?*?360?/?self.total))
??self.cv.move(self.cid,?self.vx?+?move_x,?self.vy?+?0.5?*?dt)
??self.vy?+=?0.5?*?dt
?#?過期移除
?elif?self.cid?is?not?None:
??cv.delete(self.cid)
??self.cid?=?None
再接著來看煙花燃放的實(shí)現(xiàn),主要元素包括:煙花的個(gè)數(shù)、爆炸的范圍和速度、停留時(shí)間和刷新時(shí)間等,代碼實(shí)現(xiàn)如下:
def?ignite(cv):
????t?=?time()
????#?煙花列表
????explode_points?=?[]
????wait_time?=?randint(10,?100)
????#?爆炸的個(gè)數(shù)
????numb_explode?=?randint(6,?10)
????for?point?in?range(numb_explode):
????????#?爆炸粒子列表
????????objects?=?[]
????????#?爆炸?x?軸
????????x_cordi?=?randint(50,?550)
????????#?爆炸?y?軸
????????y_cordi?=?randint(50,?150)
????????speed?=?uniform(0.5,?1.5)
????????size?=?uniform(0.5,?3)
????????color?=?choice(colors)
????????#?爆炸的綻放速度
????????explosion_speed?=?uniform(0.2,?1)
????????#?爆炸的粒子數(shù)半徑
????????total_particles?=?randint(10,?50)
????????for?i?in?range(1,?total_particles):
????????????r?=?fireworks(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))
????????????#?添加進(jìn)粒子列表里
????????????objects.append(r)
????????#?把粒子列表添加到煙花列表
????????explode_points.append(objects)
????total_time?=?.0
????#?在?1.8?秒時(shí)間幀內(nèi)保持更新
????while?total_time?1.8:
????????#?讓畫面暫停?0.01s
????????sleep(0.01)
????????#?刷新時(shí)間
????????tnew?=?time()
????????t,?dt?=?tnew,?tnew?-?t
????????#?遍歷煙花列表
????????for?point?in?explode_points:
????????????#?遍歷煙花里的粒子列表
????????????for?item?in?point:
????????????????#?更新時(shí)間
????????????????item.update(dt)
????????#?刷新頁(yè)面
????????cv.update()
????????total_time?+=?dt
????root.after(wait_time,?ignite,?cv)
最后,我們來看一下效果:

總結(jié)
本文我們使用 Python 實(shí)現(xiàn)了煙花燃放的特效,如果感興趣的話,可以自動(dòng)動(dòng)手試試。
代碼地址:
https://github.com/JustDoPython/python-examples/tree/master/yeke/py-firework
_往期文章推薦_
評(píng)論
圖片
表情
