本文的文字及圖片來源于網路,僅供學習、交流使用,不具有任何商業用途,著作權歸原作者所有,如有問題請及時聯系我們以作處理
本文來自騰訊云,作者:Python小二
煙花由中國古代人民較早發明,常用于盛大的典禮或表演中,也在除夕夜及元宵節中燃放用來烘托節日氛圍,近年來隨著環境污染的加劇,一些地區已經禁止燃放煙花了,那我們就用 Python 實作一場無污染的煙花秀,
環境
- 作業系統:Windows
- Python 版本:3.6
- 涉及模塊:tkinter、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
煙花顏色
colors = ['red', 'blue', 'yellow', 'white', 'green', 'orange', 'purple', 'seagreen', 'indigo', 'cornflowerblue']
定義煙花類
class fireworks: 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 # 綻放的粒子數 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 + 0.5 * dt) self.vy += 0.5 * dt # 過期移除 elif self.cid is not None: cv.delete(self.cid) self.cid = None # 定義膨脹效果的時間幀 def expand(self): return self.age <= 1.5 # 檢查粒子是否仍在生命周期內 def alive(self): return self.age <= self.lifespan
燃放煙花
def ignite(cv): t = time() # 煙花串列 explode_points = [] wait_time = randint(10, 100) # 爆炸的個數 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) # 爆炸的粒子數半徑 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)) # 添加進粒子串列里 objects.append(r) # 把粒子串列添加到煙花串列 explode_points.append(objects) total_time = .0 # 在 1.8 秒時間幀內保持更新 while total_time < 1.8: # 讓畫面暫停 0.01s 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, ignite, cv)
啟動
if __name__ == "__main__": root = tk.Tk() # 繪制一個畫布 cv = tk.Canvas(root, height=400, width=600) # 背景圖 image = Image.open("bg.jpg") photo = ImageTk.PhotoImage(image) # 在畫板上繪制一張圖片 cv.create_image(0, 0, image=photo, anchor='nw') cv.pack() root.protocol(close) root.after(100, ignite, cv) # 生成視窗 root.mainloop()
最終效果,如圖所示:
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/236927.html
標籤:Python
