Python新年烟花代码

Pygame 绘制烟花的基本原理

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

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

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

python 复制代码
# @Author : 小红牛
# 微信公众号:WdPython
import math
from random import randint, uniform, choice
import pygame

vector = pygame.math.Vector2
gravity = vector(0, 0.3)
DISPLAY_WIDTH = 1100
DISPLAY_HEIGHT = 700

trail_colours = [(45, 45, 45), (60, 60, 60), (75, 75, 75),
                 (125, 125, 125), (150, 150, 150)]
dynamic_offset = 1
static_offset = 5


class Firework:

    def __init__(self):
        self.colour = (randint(0, 255), randint(0, 255), randint(0, 255))
        self.colours = (
            (randint(0, 255), randint(0, 255), randint(0, 255)
             ), (randint(0, 255), randint(0, 255), randint(0, 255)),
            (randint(0, 255), randint(0, 255), randint(0, 255)))
        self.firework = Particle(randint(0, DISPLAY_WIDTH), DISPLAY_HEIGHT, True,
                                 self.colour)  # Creates the firework particle
        self.exploded = False
        self.particles = []
        self.min_max_particles = vector(100, 225)

    def update(self, win):  # called every frame
        if not self.exploded:
            self.firework.apply_force(gravity)
            self.firework.move()
            for tf in self.firework.trails:
                tf.show(win)

            self.show(win)

            if self.firework.vel.y >= 0:
                self.exploded = True
                self.explode()
        else:
            for particle in self.particles:
                particle.apply_force(
                    vector(gravity.x + uniform(-1, 1) / 20, gravity.y / 2 + (randint(1, 8) / 100)))
                particle.move()
                for t in particle.trails:
                    t.show(win)
                particle.show(win)

    def explode(self):
        amount = randint(self.min_max_particles.x, self.min_max_particles.y)
        for i in range(amount):
            self.particles.append(
                Particle(self.firework.pos.x, self.firework.pos.y, False, self.colours))

    def show(self, win):
        pygame.draw.circle(win, self.colour, (int(self.firework.pos.x), int(
            self.firework.pos.y)), self.firework.size)

    def remove(self):
        if self.exploded:
            for p in self.particles:
                if p.remove is True:
                    self.particles.remove(p)

            if len(self.particles) == 0:
                return True
            else:
                return False


class Particle:

    def __init__(self, x, y, firework, colour):
        self.firework = firework
        self.pos = vector(x, y)
        self.origin = vector(x, y)
        self.radius = 20
        self.remove = False
        self.explosion_radius = randint(5, 18)
        self.life = 0
        self.acc = vector(0, 0)
        # trail variables
        self.trails = []  # stores the particles trail objects
        self.prev_posx = [-10] * 10  # stores the 10 last positions
        self.prev_posy = [-10] * 10  # stores the 10 last positions

        if self.firework:
            self.vel = vector(0, -randint(17, 20))
            self.size = 5
            self.colour = colour
            for i in range(5):
                self.trails.append(Trail(i, self.size, True))
        else:
            self.vel = vector(uniform(-1, 1), uniform(-1, 1))
            self.vel.x *= randint(7, self.explosion_radius + 2)
            self.vel.y *= randint(7, self.explosion_radius + 2)
            self.size = randint(2, 4)
            self.colour = choice(colour)
            for i in range(5):
                self.trails.append(Trail(i, self.size, False))

    def apply_force(self, force):
        self.acc += force

    def move(self):
        if not self.firework:
            self.vel.x *= 0.8
            self.vel.y *= 0.8

        self.vel += self.acc
        self.pos += self.vel
        self.acc *= 0

        if self.life == 0 and not self.firework:  # check if particle is outside explosion radius
            distance = math.sqrt((self.pos.x - self.origin.x)
                                 ** 2 + (self.pos.y - self.origin.y) ** 2)
            if distance > self.explosion_radius:
                self.remove = True

        self.decay()

        self.trail_update()

        self.life += 1

    def show(self, win):
        pygame.draw.circle(win, (self.colour[0], self.colour[1], self.colour[2], 0), (int(self.pos.x), int(self.pos.y)),
                           self.size)

    def decay(self):  # random decay of the particles
        if 50 > self.life > 10:  # early stage their is a small chance of decay
            ran = randint(0, 30)
            if ran == 0:
                self.remove = True
        elif self.life > 50:
            ran = randint(0, 5)
            if ran == 0:
                self.remove = True

    def trail_update(self):
        self.prev_posx.pop()
        self.prev_posx.insert(0, int(self.pos.x))
        self.prev_posy.pop()
        self.prev_posy.insert(0, int(self.pos.y))

        for n, t in enumerate(self.trails):
            if t.dynamic:
                t.get_pos(self.prev_posx[n + dynamic_offset],
                          self.prev_posy[n + dynamic_offset])
            else:
                t.get_pos(self.prev_posx[n + static_offset],
                          self.prev_posy[n + static_offset])


class Trail:

    def __init__(self, n, size, dynamic):
        self.pos_in_line = n
        self.pos = vector(-10, -10)
        self.dynamic = dynamic

        if self.dynamic:
            self.colour = trail_colours[n]
            self.size = int(size - n / 2)
        else:
            self.colour = (255, 255, 200)
            self.size = size - 2
            if self.size < 0:
                self.size = 0

    def get_pos(self, x, y):
        self.pos = vector(x, y)

    def show(self, win):
        pygame.draw.circle(win, self.colour, (int(
            self.pos.x), int(self.pos.y)), self.size)


def update(win, fireworks):
    for fw in fireworks:
        fw.update(win)
        if fw.remove():
            fireworks.remove(fw)

    pygame.display.update()

# 主函数
def main():
    pygame.init()
    pygame.display.set_caption('2024新年快乐')
    win = pygame.display.set_mode((DISPLAY_WIDTH, DISPLAY_HEIGHT))
    myfont = pygame.font.Font('C:\Windows\Fonts\simkai.ttf', 80)
    text = myfont.render('2024新年快乐', False, (255, 0, 0))
    # 将文字绘制到屏幕上
    win.blit(text, (100, 100))
    pygame.display.flip()
    clock = pygame.time.Clock()
    fireworks = [Firework() for i in range(3)]  # create the first fireworks
    running = True

    while running:
        clock.tick(60)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                running = False

            if event.type == pygame.KEYDOWN:
            # Change game speed with number keys
                if event.key == pygame.K_1:
                    fireworks.append(Firework())
                if event.key == pygame.K_2:
                    for i in range(10):
                        fireworks.append(Firework())
        win.fill((20, 20, 30))  # draw background

        if randint(0, 20) == 1:  # create new firework
            fireworks.append(Firework())

        update(win, fireworks)

        # stats for fun
        # total_particles = 0
        # for f in fireworks:
        #    total_particles += len(f.particles)

        # print(f"Fireworks: {len(fireworks)}\nParticles: {total_particles}\n\n")

    pygame.quit()
    quit()
main()

完毕!!感谢您的收看

----------★★历史博文集合★★----------
我的零基础Python教程,Python入门篇 进阶篇 视频教程 Py安装py项目 Python模块 Python爬虫 Json Xpath 正则表达式 Selenium Etree CssGui程序开发 Tkinter Pyqt5 列表元组字典数据可视化 matplotlib 词云图 Pyecharts 海龟画图 Pandas Bug处理 电脑小知识office自动化办公 编程工具

相关推荐
梦想画家4 小时前
基于PyTorch的时间序列异常检测管道构建指南
人工智能·pytorch·python
PythonFun5 小时前
OCR图片识别翻译工具功能及源码
python·ocr·机器翻译
虫师c6 小时前
Python浪漫弹窗程序:Tkinter实现动态祝福窗口教程
python·tkinter·动画效果·gui编程·弹窗效果
灯火不休时7 小时前
95%准确率!CNN交通标志识别系统开源
人工智能·python·深度学习·神经网络·cnn·tensorflow
deephub7 小时前
FastMCP 入门:用 Python 快速搭建 MCP 服务器接入 LLM
服务器·人工智能·python·大语言模型·mcp
南宫乘风7 小时前
基于 Flask + APScheduler + MySQL 的自动报表系统设计
python·mysql·flask
番石榴AI8 小时前
基于机器学习优化的主图选择方法(酒店,景点,餐厅等APP上的主图展示推荐)
图像处理·人工智能·python·机器学习
qq7422349848 小时前
Python操作数据库之pyodbc
开发语言·数据库·python
2401_841495649 小时前
【自然语言处理】轻量版生成式语言模型GPT
人工智能·python·gpt·深度学习·语言模型·自然语言处理·transformer
云和数据.ChenGuang9 小时前
tensorflow生成随机数和张量
人工智能·python·tensorflow