作者:xiaoyu

微信公眾號:

Python資料科學

知乎:python資料分析師

七夕禮物

一年一度的七夕節又到了,每年重複的過,花樣各種有,很多男同胞又開始發愁了,該準備點什麼呢?前一段時間非常火的電影

“西紅市首富”

突然給了我點靈感,男主全城放煙花俘獲了女主的芳心。

沒錯!就是放煙花,而且要全城放。

可除了土豪,不是所有人都能在整個城市放煙花的。對於一個普通的不能再普通的我也只能想想了。雖然夢想很遙遠,不過我還沒放棄,我決定用Python來幫我實現一下這個願望,

畢竟Python是萬能的

下面是Python實現的禮花動態效果。

如何用Python過一個完美的七夕節?

Tkinter和程式碼實現

這個動態效果是由

Tkinter

庫來完成的,屬於Python的GUI程式設計部分。Python提供了多個圖形開發介面的庫,常用的有Tkinter,xwPython,Jython。

Tkinter是Python的標準GUI庫,內建在Python中,不需要額外安裝

,對於一些簡單的圖形介面可以輕鬆實現。

下面是七夕節煙花效果的程式碼實現,首先匯入所有需要的庫:

Tkinter:

最終的GUI實現;

PIL:

處理影象,在最後畫布背景中使用;

time:

處理時間,完成時間生命週期的更新迭代;

random:

隨機產生數字,定義燃放過程中的隨機變數;

math:

數學函式方法,計算燃放移動使用;

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

然後定義一個通用的煙花顆粒的類(part),

煙花顆粒的屬性如下:

id:

每個煙花中顆粒的標識;

x, y:

煙花的x,y軸;

vx, vy:

在x,y軸中顆粒的速度;

total:

每個煙花的顆粒數量;

age:

顆粒已經在背景度過的時間;

color:

顏色;

cv:

背景;

lifespan:

顆粒將在背景持續多久;

然後在這個類中定義了煙花顆粒的一些類方法:

update:

透過判斷顆粒狀態更新顆粒的生命時間;

expand:

定義爆炸的時間;

alive:

檢查顆粒在生命週期內是否還存在;

# 設定重力引數

GRAVITY = 0。05

# 設定隨機的顏色列表

colors = [‘red’, ‘blue’, ‘yellow’, ‘white’, ‘green’, ‘orange’, ‘purple’, ‘seagreen’, ‘indigo’, ‘cornflowerblue’]

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

self。y = y

self。initial_speed = explosion_speed

self。vx = vx

self。vy = vy

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)

self。lifespan = lifespan

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 + GRAVITY * dt)

self。vy += GRAVITY * dt

# 如果顆超過最長持續時間,顆粒消失

elif self。cid is not None:

cv。delete(self。cid)

self。cid = None

# 定義爆炸的時間

def expand(self):

return self。age <= 1。2

# 檢查顆粒在生命周內是否還存在

def alive(self):

return self。age <= self。lifespan

上面完成了一個通用的煙花顆粒類的實現,下面就開始煙花燃放的模擬迴圈過程:

透過遞迴不斷循地在背景中產生新的煙花。

首先定義一個

simulate

模擬的函式,在函式中定了一些引數:

t:

時間戳;

explode_points:

煙花爆炸點列表,供後續更新使用;

num_explore:

隨機的煙花數量;

然後在所有的煙花數量中迴圈建立所有的煙花顆粒類,當然在每次迴圈中顆粒類都需要設定一定的屬性引數,引數多是隨機產生:

objects:

存放所有的顆粒物件;

x_cordi,y_cordi:

隨機產生煙花在背景中的x,y座標位置(50,550);

speed:

隨機產生顆粒移動速度(0。5,1。5);

size:

隨機產生顆粒大小(0。5,3);

color:

選擇顏色隨機列表中的顏色;

total_particles:

隨機產生每個煙花中所有顆粒的數量;

有了這些引數,我們就可以定義迴圈產生每個顆粒物件了,並將每個煙花的所有顆粒物件儲存在objects中。

也就是說explore_points是列表中套列表,內層列表是每個煙花的所有顆粒物件,外層列表是所有煙花。

所有的顆粒物件完成後,就開始對每個顆粒的生命時間進行更新,且總時間設定在1。8秒以內。最後透過root

遞迴

使煙花可以一直在背景中燃放。

def simulate(cv):

t = time()

explode_points = []

wait_time = randint(10, 100)

numb_explode = randint(6, 10)

# 迴圈建立所有的煙花顆粒

for point in range(numb_explode):

objects = []

x_cordi = randint(50, 550)

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)

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

# 保持在1。8秒內進行更新

while total_time < 1。8:

sleep(0。01)

tnew = time()

t, dt = tnew, tnew - t

for point in explode_points:

for item in point:

item。update(dt)

cv。update()

total_time += dt

# 透過遞迴持續不斷的在背景中新增新煙花

root。after(wait_time, simulate, cv)

def close(*ignore):

“”“停止模擬迴圈,關閉視窗”“”

global root

root。quit()

以上程式碼部分均與Tkinter無關,只是定義了顆粒物件以及模擬顆粒生命週期的全過程,下面將使用Tkinter完成最終的效果。

root:

Tkinter類的物件;

cv:

定義了Tkinter中背景畫布物件,其中height和width引數可根據實際進行調整;

image:

開啟的影象物件,影象將被作為畫布中的背景,

影象可根據自己喜好自行選擇

photo:

使用ImageTk定義了Tkinter中的影象物件;

然後將在畫布物件上建立一個影象(使用定義的photo物件作為引數),最後呼叫Tkinter物件root進行持續不斷地simulate模擬過程。

if __name__ == ‘__main__’:

root = tk。Tk()

cv = tk。Canvas(root, height=600, width=600)

# 自己選擇一個好的影象背景填充畫布

image = Image。open(“image。jpg”)

photo = ImageTk。PhotoImage(image)

cv。create_image(0, 0, image=photo, anchor=‘nw’)

cv。pack()

root。protocol(“WM_DELETE_WINDOW”, close)

root。after(100, simulate, cv)

root。mainloop()

注意:背景圖片可根據自己的喜好進行更換,還不趕緊定製一個屬於自己的煙花秀?

七夕總結

以上便是博主給大家的七夕節禮物了,程式碼不到100行,但卻完成了一個超炫的GUI效果。

完整程式碼

可在公眾號後臺回覆

“七夕”

獲取,最後祝大家七夕節快樂。

https://

github。com/tuangauss/Va

rious-projects/blob/master/Python/fireworks。py

如何用Python過一個完美的七夕節?

關注微信公眾號:

Python資料科學

,檢視更多精彩內容。