Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3657214
  • 博文数量: 365
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2522
  • 用 户 组: 普通用户
  • 注册时间: 2019-10-28 13:40
文章分类

全部博文(365)

文章存档

2023年(8)

2022年(130)

2021年(155)

2020年(50)

2019年(22)

我的朋友

分类: 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把画布上的粒子移动xy个距离

            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)

    #等待时间为10100之间整数

    numb_explode = randint(8,20)

    #爆炸烟花个数时610之间的随机整数

    # 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()

阅读(938) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~