直接上程式碼!

# -*- coding: utf-8 -*-

import math, random,time

import threading

import tkinter as tk

import re

#import uuid

Fireworks=[]

maxFireworks=8

height,width=600,600

class firework(object):

def __init__(self,color,speed,width,height):

#uid=uuid。uuid1()

self。radius=random。randint(2,4) #

粒子半徑

為2~4畫素

self。color=color #粒子顏色

self。speed=speed #speed是1。5-3。5秒

self。status=0 #在煙花未爆炸的情況下,status=0;爆炸後,status>=1;當status>100時,煙花的生命期終止

self。nParticle=random。randint(20,30) #粒子數量

self。center=[random。randint(0,width-1),random。randint(0,height-1)] #煙花隨機中心座標

self。oneParticle=[] #

原始粒子

座標(100%狀態時)

self。rotTheta=random。uniform(0,2*math。pi) #橢圓平面旋轉角

#橢圓引數方程:x=a*cos(theta),y=b*sin(theta)

#ellipsePara=[a,b]

self。ellipsePara=[

random。randint

(30,40),random。randint(20,30)]

theta=2*math。pi/self。nParticle

for i in range(self。nParticle):

t=random。uniform(-1。0/16,1。0/16) #產生一個 [-1/16,1/16) 的

隨機數

x,y=self。ellipsePara[0]*math。cos(theta*i+t), self。ellipsePara[1]*math。sin(theta*i+t) #

橢圓引數方程

xx,yy=x*math。cos(self。rotTheta)-y*math。sin(self。rotTheta), y*math。cos(self。rotTheta)+x*math。sin(self。rotTheta) #

平面旋轉方程

self。oneParticle。append([xx,yy])

self。curParticle=self。oneParticle[0:] #當前粒子座標

self。thread=threading。Thread(target=self。extend) #建立執行緒物件

def extend(self): #粒子群狀態變化函式執行緒

for i in range(100):

self。status+=1 #更新狀態標識

self。curParticle=[[one[0]*self。status/100, one[1]*self。status/100] for one in self。oneParticle] #更新粒子群座標

time。sleep(self。speed/50)

def explode(self):

self。thread。setDaemon(True) #把現程設為

守護執行緒

self。thread。start() #

啟動執行緒

def __repr__(self):

return (‘color:{color}\n’

‘speed:{speed}\n’

‘number of particle: {np}\n’

‘center:[{cx} , {cy}]\n’

‘ellipse:a={ea} , b={eb}\n’

‘particle:\n{p}\n’

)。format(color=self。color,speed=self。speed,np=self。nParticle,cx=self。center[0],cy=self。center[1],p=str(self。oneParticle),ea=self。ellipsePara[0],eb=self。ellipsePara[1])

def colorChange(fire):

rgb=re。findall(r‘(。{2})’,fire。color[1:])

cs=fire。status

f=lambda x,c: hex(int(int(x,16)*(100-c)/30))[2:] #當粒子壽命到70%時,顏色開始線性衰減

if cs>70:

ccr,ccg,ccb=f(rgb[0],cs),f(rgb[1],cs),f(rgb[2],cs)

else:

ccr,ccg,ccb=rgb[0],rgb[1],rgb[2]

return ‘#{0:0>2}{1:0>2}{2:0>2}’。format(ccr,ccg,ccb)

def appendFirework(n=1): #遞迴生成煙花物件

if n>maxFireworks or len(Fireworks)>maxFireworks:

pass

elif n==1:

cl=‘#{0:0>6}’。format(hex(int(random。randint(0,16777215)))[2:]) # 產生一個0~16777215(0xFFFFFF)的隨機數,作為隨機顏色

a=firework(cl,random。uniform(1。5,3。5),width,height)

Fireworks。append( {‘particle’:a,‘points’:[]} ) #建立粒子顯示列表,‘particle’為一個煙花物件,‘points’為每一個粒子顯示時的物件變數集

a。explode()

else:

appendFirework()

appendFirework(n-1)

def show(c):

for p in Fireworks: #每次重新整理顯示,先把已有的所以粒子全部刪除

for pp in p[‘points’]:

c。delete(pp)

for p in Fireworks: #根據每個煙花物件,計算其中每個粒子的顯示物件

oneP=p[‘particle’]

if oneP。status==100: #狀態標識為100,說明煙花壽命結束

Fireworks。remove(p) #移出當前煙花

appendFirework() #新增一個煙花

continue

else:

li=[[int(cp[0]*2)+oneP。center[0],int(cp[1]*2)+oneP。center[1]] for cp in oneP。curParticle] #把中心為原點的橢圓平移到隨機圓心

座標

color=colorChange(oneP) #根據煙花當前狀態計算當前顏色

for pp in li:

p[‘points’]。append(c。create_oval(pp[0]-oneP。radius, pp[1]-oneP。radius, pp[0]+oneP。radius, pp[1]+oneP。radius, fill=color)) #繪製煙花每個粒子

root。after(50, show,c) #回撥,每50ms重新整理一次

if __name__==‘__main__’:

appendFirework(maxFireworks)

root = tk。Tk()

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

cv。create_rectangle(0, 0, width, height, fill=“black”)

cv。pack()

root。after(50, show,cv)

root。mainloop()

2:效果圖

Python煙花程式碼!

點選連結加入群聊【Python學習交流群】: