天天看點

python寫新年快樂程式_新年快樂! python實作絢爛的煙花綻放效果

新年快樂! 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.增加文字繪制功能,在背景圖中隐藏有字樣,煙花綻放後落于字樣中的粒子不消失,而是定格在視窗中。以上就是本文的全部内容,希望對大家的學習有所幫助,也希望大家多多支援中文源碼網。

親,試試微信掃碼分享本頁! *^_^*