做者:xiaoyupython
微信公衆號:Python數據科學git
知乎:python數據分析師github
一年一度的七夕節又到了,每一年重複的過,花樣各類有,不少男同胞又開始發愁了,該準備點什麼呢?前一段時間很是火的電影 「西紅市首富」
忽然給了我點靈感,男主全城放煙花俘獲了女主的芳心。沒錯!就是放煙花,並且要全城放。編程
可除了土豪,不是全部人都能在整個城市放煙花的。對於一個普通的不能再普通的我也只能想一想了。雖然夢想很遙遠,不過我還沒放棄,我決定用Python來幫我實現一下這個願望,畢竟Python是萬能的。微信
下面是Python實現的禮花動態效果。app
這個動態效果是由 Tkinter
庫來完成的,屬於Python的GUI編程部分。Python提供了多個圖形開發界面的庫,經常使用的有Tkinter
,xwPython
,Jython
。Tkinter是Python的標準GUI庫,內置在Python中,不須要額外安裝,對於一些簡單的圖形界面能夠輕鬆實現。dom
下面是七夕節煙花效果的代碼實現,首先導入全部須要的庫:函數
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),煙花顆粒的屬性以下:oop
而後在這個類中定義了煙花顆粒的一些類方法:ui
# 設置重力參數 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
模擬的函數,在函數中定了一些參數:
而後在全部的煙花數量中循環建立全部的煙花顆粒類,固然在每次循環中顆粒類都須要設置必定的屬性參數,參數可能是隨機產生:
有了這些參數,咱們就能夠定義循環產生每一個顆粒對象了,並將每一個煙花的全部顆粒對象儲存在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
完成最終的效果。
而後將在畫布對象上建立一個圖像(使用定義的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/...
關注微信公衆號:Python數據科學,發現更多精彩內容。