新年快樂! python實作絢爛的煙花綻放效果
來源:中文源碼網 浏覽: 次 日期:2019年11月5日
【下載下傳文檔: 新年快樂! python實作絢爛的煙花綻放效果.txt 】
(友情提示:右鍵點上行txt文檔名->目标另存為)
新年快樂! python實作絢爛的煙花綻放效果做了一個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 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 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.增加文字繪制功能,在背景圖中隐藏有字樣,煙花綻放後落于字樣中的粒子不消失,而是定格在視窗中。以上就是本文的全部内容,希望對大家的學習有所幫助,也希望大家多多支援中文源碼網。
親,試試微信掃碼分享本頁! *^_^*