Эта статья была впервые опубликована сколонна Джижи
Код тоже романтичен: устройте фейерверк на Python
Использованная литература:towardsdatascience.com
Друзья, которые каждый день пишут код, вы когда-нибудь думали, что код тоже может стать крутым и романтичным? Сегодня я научу вас, как использовать Python для имитации цветущего фейерверка, чтобы отпраздновать вчерашнюю победу французской команды.Вы также можете позволить программе устроить для себя фейерверк в любое время после работы.
Этот интересный небольшой проект не сложен, всего лишь немного навыков визуализации, более 100 строк кода Python и библиотека Tkinter, и наконец мы можем добиться следующего эффекта:
После прохождения этого урока вы тоже сможете сделать такое шоу фейерверков.
Общая концепция кардочесания
Вся наша философия относительно проста.
Как показано выше, мы моделируем эффект взрыва, разделяя частицу на экране на X частиц. Частицы «набухают», то есть они движутся с постоянной скоростью и под одинаковыми углами друг к другу. Это позволяет имитировать изображение цветущего фейерверка в виде расширяющегося круга. Через определенное время частицы переходят в фазу «свободного падения», когда они начинают падать на землю под действием силы тяжести, подобно фейерверкам, которые гаснут после того, как распустятся.
Проектирование Fireworks с помощью Python и Tkinter: основы
Здесь мы уже не выбрасываем все математические знания, мы пишем код и говорим о теории. Во-первых, убедитесь, что вы установили и импортировали Tkinter, который является стандартной библиотекой графического интерфейса Python и широко используется в различных проектах и разработке программ.Использование Tkinter в 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
Помимо Tkinter, чтобы у интерфейса был красивый фон, мы также импортируем PIL для обработки изображений, и импортируем некоторые другие пакеты, такие как time, random и math. Они позволяют нам более легко контролировать траекторию частиц фейерверка.
Базовая настройка приложения Tkinter выглядит следующим образом:
root = tk.Tk()
Чтобы иметь возможность инициализировать Tkinter, мы должны создать корневой виджет Tk(), который представляет собой окно с заголовком и другими украшениями, предоставляемыми оконным менеджером. Этот корневой виджет должен быть создан до того, как мы создадим другие виджеты, и может быть только один корневой виджет.
w = tk.Label(root, text="Hello Tkinter!")
Эта строка кода содержит виджет Label. Первый параметр в вызове Label — это имя родительского окна, которое мы используем здесь как «корень». Аргумент ключевого слова «текст» указывает отображаемое текстовое содержимое. Вы также можете вызывать другие виджеты: Button, Canvas и т.д.
w.pack()
root.mainloop()
Следующие две строки кода важны. Метод упаковки здесь заключается в том, чтобы указать Tkinter изменить размер окна, чтобы он соответствовал используемому виджету. Окно не появится, пока мы не войдем в цикл событий Tkinter, который вызывается root.mainloop(). Скрипт остается в цикле событий, пока мы не закроем окно.
Перевести фейерверки в код
Теперь мы создаем объект, который представляет каждую частицу в событии фейерверка. Каждая частица будет иметь некоторые важные свойства, определяющие ее внешний вид и движение: размер, цвет, положение, скорость и т. д.
'''
Generic class for particles
particles are emitted almost randomly on the sky, forming a round of circle (a star) before falling and getting removed
from canvas
Attributes:
- id: identifier of a particular particle in a star
- x, y: x,y-coordinate of a star (point of explosion)
- vx, vy: speed of particle in x, y coordinate
- total: total number of particle in a star
- age: how long has the particle last on canvas
- color: self-explantory
- cv: canvas
- lifespan: how long a particle will last on canvas
- intial_speed: speed of particle at explosion
'''
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 = 0
self.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
Теперь нам просто нужно объединить две последние сущности в одну функцию, которую может вызывать Tkinter, назовем ее симуляцией(). Эта функция будет отображать все элементы данных и обновлять свойства каждого элемента данных в соответствии с установленным нами временем. В нашем основном коде мы будем вызывать эту функцию с модулем обработки сигналов тревоги after(), который будет ждать определенное время перед вызовом функции. Мы установили здесь, чтобы позволить Tkinter ждать 100 единиц (1 секунду) перед вызовом симуляции.
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:
Эта статья является лишь базовой версией.После того, как вы лучше познакомитесь с Tkinter, вы можете добавить больше фоновых фотографий с более красивыми цветами, и пусть код расцветет для вас более красивым фейерверком!
Вся эта статьякодовый адрес
0806 «Искусственный интеллект — от нуля до мастера» со скидкой, ограниченной по времени!
Нажмите здесь, чтобы узнать подробности
Болтать и смеяться Онлайн-программирование Узнать об этом?
(Первые 25 студентов также могут получить купон на 200 иен)