Найти в Дзене
IT Start | Python

Фейерверки на Python

В ходе данной статьи напишем код для красивой анимации запуска и взрыва фейерверков на Python с использованием библиотеки Tkinter. Для начала импортируем tkinter, random и math: import tkinter as tk
import random
import math Создадим окно приложения с размерами 800×600 и чёрным фоном, которое будет служить нашим «ночным небом»: import tkinter as tk
import random
import math # Настройка окна
root = tk.Tk()
root.title("Фейерверки!")
root.geometry("800x600")
root.configure(bg="black")
root.resizable(False, False) # Запуск основного цикла приложения
root.mainloop() Создадим холст для рисования: import tkinter as tk
import random
import math root = tk.Tk()
root.title("Фейерверки!")
root.geometry("800x600")
root.configure(bg="black")
root.resizable(False, False) # Холст для рисования
canvas = tk.Canvas(root, width=800, height=600, bg="black", highlightthickness=0)
canvas.pack() root.mainloop() Добавим функцию для запуска ракеты, которую назовём create_rocket(). Внутри неё п
Оглавление

Введение

В ходе данной статьи напишем код для красивой анимации запуска и взрыва фейерверков на Python с использованием библиотеки Tkinter.

Настройка окна приложения

Для начала импортируем tkinter, random и math:

import tkinter as tk
import random
import math

Создадим окно приложения с размерами 800×600 и чёрным фоном, которое будет служить нашим «ночным небом»:

import tkinter as tk
import random
import math

# Настройка окна
root = tk.Tk()
root.title("Фейерверки!")
root.geometry("800x600")
root.configure(bg="black")
root.resizable(False, False)

# Запуск основного цикла приложения
root.mainloop()

Создадим холст для рисования:

import tkinter as tk
import random
import math

root = tk.Tk()
root.title("Фейерверки!")
root.geometry("800x600")
root.configure(bg="black")
root.resizable(False, False)

# Холст для рисования
canvas = tk.Canvas(root, width=800, height=600, bg="black", highlightthickness=0)
canvas.pack()

root.mainloop()

Создание ракеты

Добавим функцию для запуска ракеты, которую назовём create_rocket(). Внутри неё первым делом определим случайную горизонтальную позицию, нижнюю стартовую позицию, конечную позицию и отрисуем овал:

import tkinter as tk
import random
import math

def create_rocket():
x = random.randint(100, 700) # Случайная горизонтальная позиция
y_start = 600 # Стартовая позиция снизу
y_target = random.randint(100, 300) # Конечная позиция (высота взрыва)
rocket = canvas.create_oval(x - 2, y_start - 10, x + 2, y_start + 10, fill="white", outline="white")

root = tk.Tk()
root.title("Фейерверки!")
root.geometry("800x600")
root.configure(bg="black")
root.resizable(False, False)

canvas = tk.Canvas(root, width=800, height=600, bg="black", highlightthickness=0)
canvas.pack()

root.mainloop()

Далее создадим вложенную функцию animate_rocket() для анимации взлёта. Внутри неё используем ключевое слово nonlocal для доступа к переменной y_start из внешней функции:

import tkinter as tk
import random
import math

def create_rocket():
x = random.randint(100, 700)
y_start = 600
y_target = random.randint(100, 300)
rocket = canvas.create_oval(x - 2, y_start - 10, x + 2, y_start + 10, fill="white", outline="white")
# Анимация взлёта
def animate_rocket():
nonlocal y_start

root = tk.Tk()
root.title("Фейерверки!")
root.geometry("800x600")
root.configure(bg="black")
root.resizable(False, False)

canvas = tk.Canvas(root, width=800, height=600, bg="black", highlightthickness=0)
canvas.pack()

root.mainloop()

Следом будет идти условие, что если текущая позиция y_start больше конечной позиции y_target, ракета продолжает двигаться вверх:

import tkinter as tk
import random
import math

def create_rocket():
x = random.randint(100, 700)
y_start = 600
y_target = random.randint(100, 300)
rocket = canvas.create_oval(x - 2, y_start - 10, x + 2, y_start + 10, fill="white", outline="white")
# Анимация взлета
def animate_rocket():
nonlocal y_start
if y_start > y_target:
canvas.move(rocket, 0, -10) # Двигаем ракету вверх
y_start -= 10
root.after(30, animate_rocket) # Запускаем следующий кадр
else:
canvas.delete(rocket) # Удаляем ракету после достижения цели

animate_rocket()

root = tk.Tk()
root.title("Фейерверки!")
root.geometry("800x600")
root.configure(bg="black")
root.resizable(False, False)

canvas = tk.Canvas(root, width=800, height=600, bg="black", highlightthickness=0)
canvas.pack()

root.mainloop()

Реализация взрыва

Теперь добавим эффект взрыва. Для этого у нас будет служить функция explode().

У функции будет присутствовать два параметра, а именно:

  • x — координата по X центра взрыва, которая определяет, где по горизонтали начнется анимация (центр, откуда разлетаются частицы).
  • y_target — координата по Y центра взрыва, которая определяет, где по вертикали начнется анимация (центр, откуда разлетаются частицы).

import tkinter as tk
import random
import math

def create_rocket():
x = random.randint(100, 700)
y_start = 600
y_target = random.randint(100, 300)
rocket = canvas.create_oval(x - 2, y_start - 10, x + 2, y_start + 10, fill="white", outline="white")

def animate_rocket():
nonlocal y_start
if y_start > y_target:
canvas.move(rocket, 0, -10)
y_start -= 10
root.after(30, animate_rocket)
else:
canvas.delete(rocket)

animate_rocket()

# Реализация взрыва
def explode(x, y_target):

root = tk.Tk()
root.title("Фейерверки!")
root.geometry("800x600")
root.configure(bg="black")
root.resizable(False, False)

canvas = tk.Canvas(root, width=800, height=600, bg="black", highlightthickness=0)
canvas.pack()

root.mainloop()

Внутри функции сначала будет идти список colors с цветами и пустой список particles, предназначенный для хранения данных о частицах взрыва. Далее будет идти цикл, в котором будет создаваться 30 частиц со случайными углами направления, дистанцией разлёта, смещением по оси X и Y и со случайными цветами:

import tkinter as tk
import random
import math

def create_rocket():
x = random.randint(100, 700)
y_start = 600
y_target = random.randint(100, 300)
rocket = canvas.create_oval(x - 2, y_start - 10, x + 2, y_start + 10, fill="white", outline="white")

def animate_rocket():
nonlocal y_start
if y_start > y_target:
canvas.move(rocket, 0, -10)
y_start -= 10
root.after(30, animate_rocket)
else:
canvas.delete(rocket)

animate_rocket()

def explode(x, y_target):
# Функция создает взрыв в виде разноцветных частиц
colors = ["red", "orange", "yellow", "green", "blue", "purple", "white"]
# Список цветов для частиц взрыва
particles = [] # Список для хранения данных о частицах

for _ in range(30): # Создаем 30 частиц взрыва
angle = random.uniform(0, 360) # Случайный угол (в градусах) для направления
distance = random.uniform(20, 100) # Случайная дистанция разлета
dx = distance * math.cos(angle) # Расчет смещения по оси X
dy = distance * math.sin(angle) # Расчет смещения по оси Y
color = random.choice(colors) # Случайный выбор цвета из списка
particle = canvas.create_oval(
x, y_target, x + 5, y_target + 5, fill=color, outline=color
) # Создаем частицу как цветной круг на холсте
particles.append((particle, dx, dy)) # Добавляем частицу в список

root = tk.Tk()
root.title("Фейерверки!")
root.geometry("800x600")
root.configure(bg="black")
root.resizable(False, False)

canvas = tk.Canvas(root, width=800, height=600, bg="black", highlightthickness=0)
canvas.pack()

root.mainloop()

Теперь добавим вложенную функцию animate_explosion() для анимации взрыва. Внутри неё будет находиться цикл, который пройдётся по всем данным из списка particles и реализует анимацию движения частиц взрыва:

import tkinter as tk
import random
import math

def create_rocket():
x = random.randint(100, 700)
y_start = 600
y_target = random.randint(100, 300)
rocket = canvas.create_oval(x - 2, y_start - 10, x + 2, y_start + 10, fill="white", outline="white")

def animate_rocket():
nonlocal y_start
if y_start > y_target:
canvas.move(rocket, 0, -10)
y_start -= 10
root.after(30, animate_rocket)
else:
canvas.delete(rocket)

animate_rocket()

def explode(x, y_target):
colors = ["red", "orange", "yellow", "green", "blue", "purple", "white"]
particles = []

for _ in range(30):
angle = random.uniform(0, 360)
distance = random.uniform(20, 100)
dx = distance * math.cos(angle)
dy = distance * math.sin(angle)
color = random.choice(colors)
particle = canvas.create_oval(
x, y_target, x + 5, y_target + 5, fill=color, outline=color
)
particles.append((particle, dx, dy))

# Анимация движения частиц взрыва
def animate_explosion():
for particle, dx, dy in particles:
# Перемещаем частицу в соответствии с расчетными смещениями
canvas.move(particle, dx * 0.1, dy * 0.1)
pos = canvas.coords(particle) # Получаем текущие координаты частицы
# Если частица вышла за пределы окна, удаляем её
if pos[0] < 0 or pos[1] < 0 or pos[2] > 800 or pos[3] > 600:
canvas.delete(particle)
particles.remove((particle, dx, dy))
# Если остались частицы, продолжаем анимацию
if particles:
root.after(50, animate_explosion)

animate_explosion() # Запускаем анимацию

root = tk.Tk()
root.title("Фейерверки!")
root.geometry("800x600")
root.configure(bg="black")
root.resizable(False, False)

canvas = tk.Canvas(root, width=800, height=600, bg="black", highlightthickness=0)
canvas.pack()

root.mainloop()

Объединение взлета ракеты и взрыва

Обновим функцию create_rocket(), чтобы вызывать explode() после завершения взлета:

import tkinter as tk
import random
import math

def create_rocket():
x = random.randint(100, 700)
y_start = 600
y_target = random.randint(100, 300)
rocket = canvas.create_oval(x - 2, y_start - 10, x + 2, y_start + 10, fill="white", outline="white")

def animate_rocket():
nonlocal y_start
if y_start > y_target:
canvas.move(rocket, 0, -10)
y_start -= 10
root.after(30, animate_rocket)
else:
canvas.delete(rocket)
explode(x, y_target)

animate_rocket()

def explode(x, y_target):
colors = ["red", "orange", "yellow", "green", "blue", "purple", "white"]
particles = []

for _ in range(30):
angle = random.uniform(0, 360)
distance = random.uniform(20, 100)
dx = distance * math.cos(angle)
dy = distance * math.sin(angle)
color = random.choice(colors)
particle = canvas.create_oval(
x, y_target, x + 5, y_target + 5, fill=color, outline=color
)
particles.append((particle, dx, dy))

def animate_explosion():
for particle, dx, dy in particles:
canvas.move(particle, dx * 0.1, dy * 0.1)
pos = canvas.coords(particle)
if pos[0] < 0 or pos[1] < 0 or pos[2] > 800 or pos[3] > 600:
canvas.delete(particle)
particles.remove((particle, dx, dy))
if particles:
root.after(50, animate_explosion)

animate_explosion()

root = tk.Tk()
root.title("Фейерверки!")
root.geometry("800x600")
root.configure(bg="black")
root.resizable(False, False)

canvas = tk.Canvas(root, width=800, height=600, bg="black", highlightthickness=0)
canvas.pack()

root.mainloop()

Запуск нескольких фейерверков

Для автоматического запуска новых ракет добавим функцию start_fireworks(), которая будет вызывать create_rocket() каждые 1000 мс:

import tkinter as tk
import random
import math

def create_rocket():
x = random.randint(100, 700)
y_start = 600
y_target = random.randint(100, 300)
rocket = canvas.create_oval(x - 2, y_start - 10, x + 2, y_start + 10, fill="white", outline="white")

def animate_rocket():
nonlocal y_start
if y_start > y_target:
canvas.move(rocket, 0, -10)
y_start -= 10
root.after(30, animate_rocket)
else:
canvas.delete(rocket)
explode(x, y_target)

animate_rocket()

def explode(x, y_target):
colors = ["red", "orange", "yellow", "green", "blue", "purple", "white"]
particles = []

for _ in range(30):
angle = random.uniform(0, 360)
distance = random.uniform(20, 100)
dx = distance * math.cos(angle)
dy = distance * math.sin(angle)
color = random.choice(colors)
particle = canvas.create_oval(
x, y_target, x + 5, y_target + 5, fill=color, outline=color
)
particles.append((particle, dx, dy))

def animate_explosion():
for particle, dx, dy in particles:
canvas.move(particle, dx * 0.1, dy * 0.1)
pos = canvas.coords(particle)
if pos[0] < 0 or pos[1] < 0 or pos[2] > 800 or pos[3] > 600:
canvas.delete(particle)
particles.remove((particle, dx, dy))
if particles:
root.after(50, animate_explosion)

animate_explosion()

def start_fireworks():
create_rocket()
root.after(1000, start_fireworks)

root = tk.Tk()
root.title("Фейерверки!")
root.geometry("800x600")
root.configure(bg="black")
root.resizable(False, False)

canvas = tk.Canvas(root, width=800, height=600, bg="black", highlightthickness=0)
canvas.pack()

start_fireworks()

root.mainloop()

Итог. Фейерверки на Python

-2

ООП версия. Фейерверки на Python

Тот же результат, но с использованием ООП:

import tkinter as tk
import random
import math

class FireworksApp:
def __init__(self, width=800, height=600):
self.width = width
self.height = height

# Настройка окна
self.root = tk.Tk()
self.root.title("Фейерверки!")
self.root.geometry(f"{width}x{height}")
self.root.configure(bg="black")
self.root.resizable(False, False)

# Холст для рисования
self.canvas = tk.Canvas(self.root, width=width, height=height, bg="black", highlightthickness=0)
self.canvas.pack()

def create_rocket(self):
x = random.randint(100, self.width - 100)
y_start = self.height
y_target = random.randint(100, 300)

rocket = self.canvas.create_oval(
x - 2, y_start - 10, x + 2, y_start + 10, fill="white", outline="white"
)

def explode():
self.canvas.delete(rocket)
colors = ["red", "orange", "yellow", "green", "blue", "purple", "white"]
particles = []

for _ in range(30):
angle = random.uniform(0, 2 * math.pi)
distance = random.uniform(20, 100)
dx = distance * math.cos(angle)
dy = distance * math.sin(angle)
color = random.choice(colors)
particle = self.canvas.create_oval(
x, y_target, x + 5, y_target + 5, fill=color, outline=color
)
particles.append((particle, dx, dy))

def animate_explosion():
for particle, dx, dy in particles:
self.canvas.move(particle, dx * 0.1, dy * 0.1)
pos = self.canvas.coords(particle)
if pos[0] < 0 or pos[1] < 0 or pos[2] > self.width or pos[3] > self.height:
self.canvas.delete(particle)
particles.remove((particle, dx, dy))
if particles:
self.root.after(50, animate_explosion)

animate_explosion()

def animate_rocket():
nonlocal y_start
if y_start > y_target:
self.canvas.move(rocket, 0, -10)
y_start -= 10
self.root.after(30, animate_rocket)
else:
explode()

animate_rocket()

def start_fireworks(self):
self.create_rocket()
self.root.after(1000, self.start_fireworks)

def run(self):
self.start_fireworks()
self.root.mainloop()

if __name__ == "__main__":
app = FireworksApp()
app.run()

Заключение

В ходе статьи мы с Вами написали код для анимации запуска фейерверков на Python. Надеюсь Вам понравилась статья, желаю удачи и успехов! 🙂

Мой Telegram канал

Мой YouTube канал

Мой курс по Python (50 видоуроков + дополнительные уроки)

Курс по созданию телеграм-ботов на Python с фреймворком Aiogram

Курс по созданию GUI на Python