2021 Fireworks-Happy New Year-Python

table of Contents

Preface

1. Knowledge introduction

2. Complete code

Three references


Preface

Yesterday, WeChat updated the version, adding the expression of fireworks. Some students from XM made suggestions to use python programming to achieve the effect of fireworks. As the 2021 Chinese New Year is coming, I wish you all a happy Chinese New Year and wish our motherland prosperous!

Gif production: https://en.softonic.com/best/free-to-play-games/?utm_source=wakeup

 

1. Knowledge introduction

1. Tkinter: The protagonist of this small project is a python graphics module. And Python3 already comes with this module, so there is no need to install it separately. It is a bit like the swing graphics module in java (integrated by many components, components are added by creating instances, and components are positioned on the window by coordinates).

2. PIL: Python Imaging Library, a standard module for image processing on the Python platform. It also comes with Python3 and is used in this project to import background images.

3.time: I believe this module will not be unfamiliar to everyone. Import it to control the blooming, falling and disappearing time of fireworks.

4.random: Random number module, used to generate random coordinate points of fireworks, random blooming speed, random disappearing time.

5.math: Everyone should be familiar with this module. The purpose of importing it is to spread the particles of the firework blooming at a certain angle.

2. Complete code

# -*- coding: utf-8 -*-
"""
Spyder Editor

This is a temporary script file.
"""

'''
FIREWORKS SIMULATION WITH TKINTER
*self-containing code
*to run: simply type python simple.py in your console
*compatible with both Python 2 and Python 3
*Dependencies: tkinter, Pillow (only for background image)
*The design is based on high school physics, with some small twists only for aesthetics purpose
'''
import tkinter as tk
# from tkinter import messagebox
# from tkinter import PhotoImage
from PIL import Image, ImageTk ,ImageDraw
from time import time, sleep
from random import choice, uniform, randint
from math import sin, cos, radians
from PIL import ImageFont

# gravity, act as our constant g, you can experiment by changing it
GRAVITY = 0.05
# list of color, can choose randomly or use as a queue (FIFO)
colors = ['red', 'blue', 'yellow', 'white', 'green', 'orange', 'purple', 
          'red', 'blue', 'yellow', 'white', 'green', 'orange', 'purple','seagreen', 'indigo', 'cornflowerblue']


'''
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
'''


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

    def update(self, dt):
        self.age += dt

        # particle expansions
        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)

        # falling down in projectile motion
        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

        # remove article if it is over the lifespan
        elif self.cid is not None:
            cv.delete(self.cid)
            self.cid = None

    # define time frame for expansion
    def expand(self):
        return self.age <= 1.2

    # check if particle is still alive in lifespan
    def alive(self):
        return self.age <= self.lifespan


'''
Firework simulation loop:
Recursively call to repeatedly emit new fireworks on canvas
a list of list (list of stars, each of which is a list of particles)
is created and drawn on canvas at every call, 
via update protocol inside each 'part' object 
'''


def simulate(cv):
    t = time()
    explode_points = []
    wait_time = randint(10, 100)
    
    numb_explode = randint(6, 10)
    # create list of list of all particles in all simultaneous explosion
    # 创建一个所有粒子同时扩大的二维列表
    for point in range(numb_explode):
        objects = []
        x_cordi = randint(50, 1250)
        y_cordi = randint(50, 500)
#        烟花降落的速度
        speed = uniform(1, 4)
        size = uniform(0.5, 3)
        color = choice(colors)
        explosion_speed = uniform(1.5, 6)
        total_particles = randint(20, 100)
        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,
                     vx=speed, vy=speed, color=color, size=size, lifespan=uniform(0.6, 1.75))
            objects.append(r)
        explode_points.append(objects)

    total_time = .0
    # keeps undate within a timeframe of 1.8 second
    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
    # recursive call to continue adding new explosion on canvas
    root.after(wait_time, simulate, cv)


def close(*ignore):
    """Stops simulation loop and closes the window."""
    global root
    root.quit()


if __name__ == '__main__':
    
    
    root = tk.Toplevel()
    root.title("2021新年快乐呀^_^")
    
    cv = tk.Canvas(root, height=854, width=1280)
    
    
    # use a nice background image
#    image = Image.open("image1.jpg")
#    photo = ImageTk.PhotoImage(image)
#    
    #设置字体,如果没有,也可以不设置
    font = ImageFont.truetype("C:\\Windows\\Fonts\\simsun.ttc",60)    #现在是宋体
    #打开底版图片
    image=Image.open("image1.jpg")
    # 在图片上添加文字 1
    draw = ImageDraw.Draw(image)
    draw.text((400, 50),"2021要加油哦",fill = "yellow",font=font)
#    draw = ImageDraw.Draw(image)
    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()
    

Three references

 

  1. Code reference link: https://github.com/tuangauss/DataScienceProjects/blob/master/Python/fireworks.py
  2. Add text to the python picture: https://blog.csdn.net/dyyay521/article/details/102546637
  3. 【解决问题】Python-Error:image "pyimage1" doesn't exist:https://blog.csdn.net/weixin_44436677/article/details/105498762

Guess you like

Origin blog.csdn.net/weixin_43442778/article/details/113001590