python炫酷烟花表白源代码-Python教程

资源魔 21 0
每天敲代码的冤家,有无想过代码也能够变患上很酷炫又浪漫?明天就教各人用Python模仿出绽开的烟花,工作之余也能够随时让顺序为本人放一场烟花秀。

python炫酷烟花表达源代码

这个风趣的小名目其实不复杂,只要一点可视化技术,100余行Python代码以及顺序库Tkinter,最初咱们就能达到上面这个成果:

0.gif

学完本教程后,你也能做出这样的烟花秀。

全体概念梳理

咱们的整个理念比拟简略。

1.jpg

如上图示,咱们这里经过让画面上一个粒子割裂为X数目的粒子来模仿爆炸成果。粒子会发作“收缩”,意义是它们会以恒速挪动且互相之间的角度相等。这样就能让咱们以一个向外收缩的圆圈方式模仿出烟花绽开的画面。通过肯定工夫后,粒子会进入“自在落体”阶段,也就是因为重力要素它们开端坠落到高空,仿若绽开后燃烧的烟花。

(保举学习:编程学习课程)

根本常识:用Python以及Tkinter设计烟花

这里再也不一股脑把数学常识全丢进去,咱们边写代码边说实践。起首,确保你装置以及导入了Tkinter,它是Python的规范 GUI 库,宽泛使用于各类百般的名目以及顺序开发,正在Python中应用 Tkinter 能够疾速的创立 GUI 使用顺序。

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

除了了Tkinter以外,为了能让界面有美丽的布景,咱们也导入PIL用于图象解决,和导入其它一些包,比方time,random以及math。它们能让咱们更易的管制烟花粒子的静止轨迹。

Tkinter使用的根本设置以下:

root = tk.Tk()

为了能初始化Tkinter,咱们必需创立一个Tk()根部件(root widget),它是一个窗口,带有题目栏以及由窗口治理器提供的其它装璜物。该根部件必需正在咱们创立其它小部件以前就创立终了,并且只能有一个根部件。

w = tk.Label(root, text="Hello Tkinter!")

这一行代码蕴含了Label部件。该Label挪用中的第一个参数就是父窗口的名字,即咱们这里用的“根”。要害字参数“text”指显著示的文字内容。你也能够挪用其它小部件:Button,Canvas等等。

w.pack()
root.mainloop()

接上去的这两行代码很首要。这里的打包办法是通知Tkinter调整窗口巨细以顺应所用的小部件。窗口直到咱们进入Tkinter事情轮回,被root.mainloop()挪用时才会呈现。正在咱们封闭窗口前,剧本会不断正在停留正在事情轮回。

将烟花绽开转译成代码

如今咱们设计一个工具,示意烟花事情中的每一个粒子。每一个粒子城市有一些首要的属性,摆布了它的外观以及挪动情况:巨细,颜色,地位,速率等等。

'''
particles 类
粒子正在空中随机天生随机,变为一个圈、下坠、隐没
属性:
    - id: 粒子的id
    - x, y: 粒子的坐标
    - vx, vy: 在座标的变动速率
    - total: 总数
    - age: 粒子存正在的时长
    - color: 颜色
    - cv: 画布
    - lifespan: 最高存正在时长
'''
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 = 0self.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

假如咱们回过甚想一想最开端的设法主意,就会心识到必需确保每一个烟花绽开的一切粒子必需通过3个没有同的阶段,即“收缩”“坠落”以及“隐没”。 以是咱们向粒子类中再增加一些静止函数,以下所示:

def update(self, 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.vx = move_x/(float(dt)*1000)
        self.vy = move_y/(float(dt)*1000)
        self.cv.move(self.cid, move_x, move_y)
    # 以自在落体坠落
    elif self.alive():
        move_x = cos(radians(self.id*360/self.total))
        # 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
    # 假如粒子的生命周期已过,就将其移除了
    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

应用Tkinter模仿

如今咱们将粒子的挪动概念化,不外很显著,一个烟花不克不及只有一个粒子,一场烟花秀也不克不及只有一个烟花。咱们下一步就是让Python以及Tkinter以咱们可控的形式向天上延续“发射”粒子。

到了这里,咱们需求从操作一个粒子晋级为正在屏幕上展示多个烟花及每一个烟花中的多个粒子。

咱们的处理思绪以下:创立一列列表,每一个子列表是一个烟花,其蕴含一列粒子。每一个列表中的例子有相反的x,y坐标、巨细、颜色、初始速率。

numb_explode = randint(6,10)
# 为一切模仿烟花绽开的全副粒子创立一列列表
for point in range(numb_explode):
    objects = []
    x_cordi = randint(50,550)
    y_cordi = randint(50, 150)       
    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, 
        color=color, size = size, lifespan = uniform(0.6,1.75))
        objects.append(r)
explode_points.append(objects)

咱们下一步就是确保活期更新粒子的属性。这里咱们设置让粒子每一0.01秒更新它们的状态,正在1.8秒之后中止更新(这象征着每一个粒子的存正在工夫为1.6秒,此中1.2秒为“绽开”状态,0.4秒为“坠落”状态,0.2秒处于Tkinter将其齐全移除了前的边缘状态)。

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 part in point:
            part.update(dt)
    cv.update()
    total_time += dt

如今,咱们只要将最初两个gist兼并为一个能被Tkinter挪用的函数,就叫它simulate()吧。该函数会展现一切的数据项,并依据咱们设置的工夫更新每一个数据项的属性。正在咱们的主代码中,咱们会用一个alarm解决模块after()挪用此函数,after()会期待肯定的工夫,而后再挪用函数。

咱们这里设置让Tkinter期待100个单元(1秒钟)再调取simulate。

if __name__ == '__main__':
    root = tk.Tk()
    cv = tk.Canvas(root, height=600, width=600)
    # 绘制一个玄色布景
    cv.create_rectangle(0, 0, 600, 600, fill="black")
    cv.pack()
    root.protocol("WM_DELETE_WINDOW", close)
    # 正在1秒后才开端挪用stimulate()
    root.after(100, simulate, cv)
    root.mainloop()

好了,这样咱们就用Python代码放了一场烟花秀:

1.gif

本文只一个简略版本,等进一步相熟Tkinter后,还能够增加更多颜色更美丽的布景照片,让代码为你绽开更美的烟花!

如下是全副代码:

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
# 模仿重力
GRAVITY = 0.05
# 颜色选项(随机或许按程序)
colors = ['red', 'blue', 'yellow', 'white', 'green', 'orange', 'purple', 'seagreen', 'indigo', 'cornflowerblue']
'''
particles 类
粒子正在空中随机天生随机,变为一个圈、下坠、隐没
属性:
    - id: 粒子的id
    - x, y: 粒子的坐标
    - vx, vy: 在座标的变动速率
    - total: 总数
    - age: 粒子存正在的时长
    - color: 颜色
    - cv: 画布
    - lifespan: 最高存正在时长
'''
class Particle:
    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 = 0self.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))
            # 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
        # 移除了超越最高时长的粒子
        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
'''
轮回挪用放弃不绝
'''
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 = Particle(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.8s内不断扩展
    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()
if __name__ == '__main__':
    root = tk.Tk()
    cv = tk.Canvas(root, height=400, 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()

泛滥python培训视频,尽正在python学习网,欢送正在线学习!

以上就是python炫酷烟花表达源代码的具体内容,更多请存眷资源魔其它相干文章!

标签: Python 源码 python教程 python编程 python使用问题 烟花 表白

抱歉,评论功能暂时关闭!