使用python实现跨年烟花代码
创始人
2024-05-04 00:13:42
0

朋友们,有多久没放烟花了?今年你所在的地方允许放烟花么?既然我们不能线下放,那么我们就在线上放个够吧(还是那句话:你~有~对~象~了~嘛~)

一下是动态图(图片我使用的我上几次的背景图,大家也可以换成别的哦~但是呢阿玥还是建议用暗色的背景图,会更好看的哟~~~)

目录

基本知识:用Python和Tkinter设计烟花

将烟花绽放转译成代码

使用Tkinter模拟

现在我们将粒子的移动概念化,不过很明显,一个烟花不能只有一个粒子,一场烟花秀也不能只有一个烟花。我们下一步就是让Python和Tkinter以我们可控的方式向天上连续“发射”粒子。



1.Pygame 绘制烟花的基本原理

1、发射阶段:在这一阶段烟花的形状是线性向上,通过设定一组大小不同、颜色不同的点来模拟“向上发射” 的运动运动,运动过程中 5个点被赋予不同大小的加速度,随着时间推移,后面的点会赶上前面的点,最终所有点会汇聚在一起,处于绽放准备阶段。

2、烟花绽放:烟花绽放这个阶段,是由一个点分散多个点向不同方向发散,并且每个点的移动轨迹可需要被记录,目的是为了追踪整个绽放轨迹。

3、烟花凋零,此阶段负责描绘绽放后烟花的效果,绽放后的烟花,而在每一时刻点的下降速度和亮度(代码中也叫透明度)是不一样的,因此在代码里,将烟花绽放后将每个点赋予两个属性:分别为重力向量和生命周期,来模拟烟花在不同时期时不同的展现效果。

首先设置全局变量,例如重力向量,窗口大小,Trail 的颜色列表(多为灰色或白色)以及不同状态下 Trail 之间间隔,gravity设置重力变量,DISPLAY_width和heigh控制窗口的长和宽

基本知识:用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之外,为了能让界面有漂亮的背景,

w = tk.Label(root, text="Hello 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 = idxself.x = xself.y = yself.initial_speed = explosion_speedself.vx = vxself.vy = vyself.total = totalself.age = 0self.color = colorself.cv = cvself.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_speedmove_y = sin(radians(self.id*360/self.total))*self.initial_speedself.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 jobself.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 - tfor 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代码放了一场烟花秀:

 可以换个背景哦

以下是全部代码:

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 = idxself.x = xself.y = yself.initial_speed = explosion_speedself.vx = vxself.vy = vyself.total = totalself.age = 0self.color = colorself.cv = cvself.cid = self.cv.create_oval(x - size, y - size, x + size,y + size, fill=self.color)self.lifespan = lifespandef update(self, dt):self.age += dt# 粒子范围扩大if self.alive() and self.expand():move_x = cos(radians(self.id * 360 / self.total)) * self.initial_speedmove_y = sin(radians(self.id * 360 / self.total)) * self.initial_speedself.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 jobself.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 - tfor 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 rootroot.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()

创作不易哦~

求大家给个三连,点个关注~感谢大家哦

 今天就是以上这些内容,下面有个投票,大家可以来看看哦

相关内容

热门资讯

微信安卓系统转苹果系统,轻松实... 你有没有想过,从微信安卓系统转到苹果系统,这中间的转换过程,就像是一场说走就走的旅行,充满了未知和惊...
如何刷安卓8.0系统,安卓8.... 你有没有想过,让你的安卓手机升级到最新的8.0系统,让它焕发出全新的活力呢?别急,今天我就来给你详细...
安卓系统里查看路由,安卓系统下... 你是不是也和我一样,对家里的无线网络充满了好奇?想知道安卓手机里怎么查看路由器信息?那就跟着我一起探...
手机出现安卓系统信号,手机信号... 你有没有发现,最近你的安卓手机信号好像变得特别不稳定呢?是不是觉得有时候信号满格,却还是接不到电话,...
创维安卓系统怎么安装,享受智能... 你家的创维电视是不是最近有点儿不给力,想要给它来个升级,让它焕发新生呢?那就得给它装个安卓系统啦!别...
中兴刷原生安卓系统,原生安卓系... 亲爱的读者们,你是否厌倦了那些千篇一律的安卓系统,想要给你的手机来点新鲜感?今天,就让我带你一起探索...
云系统与安卓系统软件,构建智能... 你有没有想过,你的手机里那些神奇的软件,其实都是靠云系统和安卓系统软件的默契配合才变得如此强大呢?想...
如何禁止安卓系统联网,全方位操... 你有没有想过,你的安卓手机其实是个小宇宙,里面藏着无数的秘密和信息?但是,你知道吗?有时候,这些信息...
a安卓系统不兼容,揭秘a设备的... 最近是不是发现你的安卓手机有些不对劲?比如,某个APP突然罢工了,再比如,你下载了一个新游戏,结果发...
安卓系统刷固件教程,解锁设备潜... 你有没有想过,你的安卓手机其实就像一个隐藏着无限可能的宝藏呢?没错,就是那个你每天不离手的宝贝。今天...
电脑系统安卓界面,功能与美学的... 你有没有发现,现在手机和电脑的界面越来越像了呢?没错,就是那个我们每天都要打交道的好伙伴——安卓界面...
吃鸡王座安卓系统,登顶吃鸡巅峰 你有没有想过,在手机游戏中,谁才是真正的“吃鸡王座”呢?今天,就让我带你一探究竟,看看安卓系统上的那...
安卓点名系统下载,安卓点名系统... 你有没有想过,在繁忙的学习生活中,有没有一种神奇的工具,能让你轻松管理课堂纪律,还能让点名变得如此有...
手机安装通用安卓系统,引领智能... 你有没有想过,为什么你的手机可以安装那么多好玩的应用?秘密就在于它搭载了通用安卓系统!想象一个系统就...
安卓系统仿真器,功能与操作指南 你有没有想过,在电脑上也能玩安卓游戏?没错,这就是安卓系统仿真器的神奇之处!想象你坐在电脑前,手握鼠...
安卓系统可以刷街机,畅享虚拟游... 你知道吗?现在用安卓系统刷街机,简直就像变魔术一样神奇!没错,就是那种让你仿佛穿越回童年,手握游戏杆...
安卓系统画画软件画笔,绘制无限... 你有没有发现,手机里的画画软件越来越丰富啦?尤其是安卓系统上的那些,简直让人眼花缭乱。今天,就让我带...
安卓系统垃圾和缓存,提升使用体... 手机里的安卓系统是不是越来越慢了?是不是觉得打开一个应用都要等半天?别急,今天就来跟你聊聊安卓系统里...
安卓系统图片转入苹果,轻松实现... 你是不是也有过这样的烦恼?手机里存了好多珍贵的照片,突然想换手机,却发现安卓系统的照片怎么也弄不到苹...
华为matebooke装安卓系... 你有没有想过,你的华为MateBook也能装上安卓系统呢?没错,就是那个我们平时手机上用的安卓系统!...