分类: Python/Ruby
2022-03-11 17:19:09
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
#烟花绽放y轴
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, outline='white',width=0.01)
#指定一个限定矩形(Tkinter 会自动在这个矩形内绘制一个椭圆)
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
#粒子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)
#粒子x轴的速度
elif self.alive():
columnFont = ('华文行楷',14)
#如果粒子仅存活不扩张(只是停留时间足够,说明膨胀到最大了),则自由坠落
self.cv.create_text(250, 100, text='喜',tag="write_tag", fill=choice(colors),font = columnFont) #字体
self.cv.create_text(300, 100, text='欢',tag="write_tag", fill=choice(colors),font = columnFont)
self.cv.create_text(350, 100, text='你',tag="write_tag", fill=choice(colors),font = columnFont)
self.cv.create_text(400, 100, text='吖',tag="write_tag", fill=choice(colors),font = columnFont)
#删除文字标签
move_x = cos(radians(self.id*360/self.total))
#x轴的移动位移
# we technically don't need to update x, y because move will do the job
self.cv.move(self.cid, self.vx + move_x, self.vy+GRAVITY*dt)
self.vy += GRAVITY*dt
#更新y轴
elif self.cid is not None:
#如果粒子生命周期已过,则将其移除
cv.delete(self.cid)
#在画布上移除该粒子对象
self.cv.delete("write_tag")
#同时移除字体
self.cid = None
def expand (self):
#定义膨胀效果时间帧
return self.age <= 1.2
#判断膨胀时间是否小于1.2秒
def alive(self):
#判断粒子是否仍在生命周期内
return self.age <= self.lifespan
#判断已停留时间是否小于应该停留时间
'''
Firework simulation loop:
Recursively call to repeatedly emit new fireworks on canvas
a list of list (list of stars, each of which is a list of particles)
is created and drawn on canvas at every call,
via update protocol inside each 'part' object
'''
def simulate(cv):
t = time()
#返回自1970年后经过的浮点秒数,精确到小数点后7位
explode_points = []
#爆炸点列表,烟花列表
wait_time = randint(10,100)
#等待时间为10到100之间整数
numb_explode = randint(8,20)
#爆炸烟花个数时6到10之间的随机整数
# create list of list of all particles in all simultaneous explosion
for point in range(numb_explode):
#为所有模拟烟花绽放的全部粒子创建一列列表
if point<=4:
objects = []
#每个点的爆炸粒子列表粒子列表
x_cordi = 250 + point*50
#每个爆炸点的x轴
y_cordi = 100
#每个爆炸点的y轴
speed = uniform (0.5, 1.5)
#每个爆炸点的速度
size = uniform (0.5,3)
#每个爆炸点的大小
color = choice(colors)
#每个爆炸点的颜色
explosion_speed = uniform(0.6, 3)
#爆炸的绽放速度
total_particles = randint(10,60)
#烟花的总粒子数
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))
#把上述参数代入part函数,但是每个粒子的生存时间是自己独立的
objects.append(r)
#把r添加进粒子列表
explode_points.append(objects)
#把粒子列表添加进烟花列表
else:
objects = []
#每个点的爆炸粒子列表粒子列表
x_cordi = randint(50,550)
#每个爆炸点的x轴
y_cordi = randint(50, 150)
#每个爆炸点的y轴
speed = uniform (0.5, 1.5)
#每个爆炸点的速度
size = uniform (0.5,3)
#每个爆炸点的大小
color = choice(colors)
#每个爆炸点的颜色
explosion_speed = uniform(0.3, 2)
#爆炸的绽放速度
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 外汇跟单gendan5.com= speed, color=color, size = size, lifespan = uniform(0.6,1.75))
#把上述参数代入part函数,但是每个粒子的生存时间是自己独立的
objects.append(r)
#把r添加进粒子列表
explode_points.append(objects)
#把粒子列表添加进烟花列表
total_time = .0
#初始化总时间
# keeps undate within a timeframe of 1.8 second
while total_time < 2:
#当总时间小于1.8秒时运行该循环
sleep(0.03)
#让画面暂停0.01秒
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):
#打开模拟循环并关闭窗口
"""Stops simulation loop and closes the window."""
global root
root.quit()