Today is Wednesday, and there are three days left for Tanabata Festival. I'm afraid it's too late to buy gifts for my girlfriend!
Then what shall I do? Then prepare a fireworks video for her.
But not everyone can set off fireworks in the whole city except local tyrants. I can only think about an ordinary one. Although the dream is far away, I haven't given up yet. I decided to use Python to help me realize this wish. After all, Python is omnipotent.
The following is the dynamic effect of fireworks implemented in Python.
Tkinter and code implementation
This dynamic effect is completed by Tkinter library and belongs to the GUI programming part of Python. Python provides several libraries of graphical development interfaces, including Tkinter, xwPython and Jython. Tkinter is a standard GUI library for Python. It is built in Python and does not need additional installation. It can be easily implemented for some simple graphical interfaces.
The following is the code implementation of the fireworks effect of Tanabata Festival. First, import all the required libraries:
- Tkinter: final GUI implementation;
- PIL: process the image and use it in the last canvas background;
- Time: processing time to complete the update iteration of the time life cycle;
- Random: randomly generated number, which defines the random variable in the discharge process;
- math: mathematical function method to calculate the mobile use of discharge;
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 Copy code
Then define a general fireworks particle class (part). The properties of fireworks particles are as follows:
- id: identification of particles in each fireworks;
- x. y: x, y axis of fireworks;
- vx, vy: velocity of particles in the x, y axis;
- total: number of particles of each fireworks;
- age: the time the particle has spent in the background;
- Color: color;
- cv: background;
- lifespan: how long the particles will last in the background;
Then, some class methods of fireworks particles are defined in this class:
- Update: update the life time of particles by judging the particle status;
- expand: defines the time of explosion;
- alive: check whether particles still exist in the life cycle;
# Set gravity parameters GRAVITY = 0.05 # Set random color list colors = ['red', 'blue', 'yellow', 'white', 'green', 'orange', 'purple', 'seagreen', 'indigo', 'cornflowerblue'] 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 explosion 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) # Particle falling elif self.alive(): move_x = cos(radians(self.id * 360 / self.total)) self.cv.move(self.cid, self.vx + move_x, self.vy + GRAVITY * dt) self.vy += GRAVITY * dt # If the particle exceeds the maximum duration, the particle disappears elif self.cid is not None: cv.delete(self.cid) self.cid = None # Define the time of the explosion def expand(self): return self.age <= 1.2 # Check whether the particles still exist in the life cycle def alive(self): return self.age <= self.lifespan Copy code
After completing the implementation of a general fireworks particle class above, let's start the simulation cycle process of fireworks discharge: generate new fireworks in the background through recursion.
First, define a simulate simulated function, and set some parameters in the function:
- t: Time stamp;
- explode_points: list of fireworks explosion points for subsequent updates;
- num_explore: random number of fireworks;
Then create all fireworks particle classes in a cycle of all fireworks quantities. Of course, in each cycle, the particle class needs to set certain attribute parameters, most of which are generated randomly:
- Objects: store all granular objects;
- x_cordi,y_cordi: X and Y coordinate positions of randomly generated fireworks in the background (50550);
- Speed: randomly generated particle moving speed (0.5, 1.5);
- Size: randomly generated particle size (0.5, 3);
- Color: select the color in the random list of colors;
- total_particles: the number of all particles in each fireworks randomly generated;
With these parameters, we can define the cycle to generate each particle object, and store all particle objects of each fireworks in objects. That is, explore_points is a set of lists in the list, the inner list is all particle objects of each fireworks, and the outer list is all fireworks.
After all particle objects are completed, the life time of each particle is updated, and the total time is set within 1.8 seconds. Finally, through root recursion, the fireworks can be set off in the background all the time.
def simulate(cv): t = time() explode_points = [] wait_time = randint(10, 100) numb_explode = randint(6, 10) # Cycle to create all fireworks particles 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 = 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 # Keep updating within 1.8 seconds 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 # Continuously add new fireworks to the background through recursion root.after(wait_time, simulate, cv) def close(*ignore): """Stop the simulation cycle and close the window""" global root root.quit()Copy code
The above code part has nothing to do with Tkinter, but defines the particle object and the whole process of simulating the particle life cycle. Tkinter will be used to complete the final effect below.
- root: object of Tkinter class;
- cv: defines the background canvas object in Tkinter, where the height and width parameters can be adjusted according to the actual situation;
- Image: open the image object. The image will be used as the background in the canvas. The image can be selected according to your preferences;
- photo: use ImageTk to define the image object in Tkinter;
Then create an image on the canvas object (using the defined photo object as a parameter), and finally call the Tkinter object root to continue the simulate simulation process.
Note: the background picture can be changed according to your preference. You don't need to customize your own fireworks showif __name__ == '__main__': root = tk.Tk() cv = tk.Canvas(root, height=600, width=600) # Choose a good image background to fill the canvas 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()Copy code
Dry goods mainly include:
① More than 2000 Python e-books (both mainstream and classic books should be available)
② Python standard library materials (the most complete Chinese version)
③ Project source code (forty or fifty interesting and classic hand training projects and source code)
④ Videos on basic introduction to Python, crawler, web development and big data analysis (suitable for Xiaobai)
⑤ Python learning roadmap (bid farewell to non stream learning)
⑥ Two days of Python crawler training camp live rights
If you need it, you can get it from the little fat man~