PK creative Spring Festival, I am participating in the “Spring Festival creative submission contest”, please see: Spring Festival creative submission Contest
Run a screenshot
Operation effect:
What? You said you couldn’t see the fireworks? I’ll do it in a different color. Please click on it.
The implementation process
The preparatory work
Use languages and frameworks: Python, PyGame. Pygame installation:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ --trusted-host pypi.tuna.tsinghua.edu.cn pygame
Copy the code
The basics you need to know
First of all, PyGame renders synchronously, so too many points on the same screen can cause stuttering. Second, PyGame’s code logic is to periodically render a series of screens to produce a continuous animation.
Framework basics you need to know:
- Initialization process
import pygame
pygame.init()
pygame.mixer.init()
pygame.font.init()
Copy the code
- To get the font
myfont = pygame.font.SysFont('simHei'.30)
textsurface = myfont.render(a[i], False, random_color(150.255))
screen.blit(textsurface, (80.30))
Copy the code
- circle
pygame.draw.circle(screen, (snow_list[i][4], snow_list[i][5], snow_list[i][6]), snow_list[i][:2],
snow_list[i][3] - 3)
Copy the code
- Loading background music
screen = pygame.display.set_mode(bg_size)
pygame.display.set_caption("Happy New Year")
bg = pygame.image.load(bg_img)
pygame.mixer.music.load('D:\ CloudMusic\ Hour Girl - Xiaguang - End song of "Fairy Century".mp3')
Copy the code
The core code
Basic frame
First, you need to implement a basic event loop for the shelf, as follows:
def main() :
global show_n
global fk_list
bg_size = (WIN_W, WIN_H)
screen = pygame.display.set_mode(bg_size)
pygame.display.set_caption("Happy New Year")
pygame.mixer.music.load('D:\ CloudMusic\ Hour Girl - Xiaguang - End song of "Fairy Century".mp3')
font_values = ['Happy New Year']
grand_has = set()
clock = pygame.time.Clock()
while True:
if not pygame.mixer.music.get_busy():
pygame.mixer.music.play()
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
screen.fill((0.0.0))... . pygame.display.update() time_passed = clock.tick(50)
if __name__ == '__main__':
main()
Copy the code
The process of snow
Now, to implement the snow process, first consider defining a set of initial snow points
def init_xue(bg_size) :
snow_list = []
for i in range(200):
x_site = random.randrange(0, bg_size[0]) # snowflake center position
y_site = random.randrange(0, bg_size[1]) # snowflake center position
X_shift = random.randint(-1.1) # x offset
radius = random.randint(4.6) # radius and y cycle drop
xxxxx = random_color(150.255)
snow_list.append([x_site, y_site, X_shift, radius, 255.255.255])
return snow_list
Copy the code
Then implement the process of rendering the snow
def draw_xue(snow_list: [], screen, bg_size: [], grand_has: set, grand_list: []) :
# Snowflake list loop
Snow in the sky
for i in range(len(snow_list)):
# Draw snowflakes, color, position, size
pygame.draw.circle(screen, (snow_list[i][4], snow_list[i][5], snow_list[i][6]), snow_list[i][:2],
snow_list[i][3] - 3)
# Move snowflake position (next loop works)
snow_list[i][0] += snow_list[i][2]
snow_list[i][1] += snow_list[i][3]
If snow falls off the screen, reset the position
if snow_list[i][1] > bg_size[1] :# tmp = []
snow_list[i][1] = random.randrange(-50, -10)
snow_list[i][0] = random.randrange(0, bg_size[0])
x = snow_list[i][0]
y = bg_size[1]
while (grand_has.__contains__(x * 10000 + y)):
y = y - snow_list[i][3]
grand_has.add(x * 10000 + y)
grand_list.append(
[x, y, snow_list[i][2], snow_list[i][3], snow_list[i][4], snow_list[i][5],
snow_list[i][6]])
Copy the code
Integrated into the shelf above, the effect is as follows:
However, the current snow has no texture, you can consider piling some snow on the bottom, just need to make a special judgment when the snow falls to the ground.
The process of snow falling to the ground and piling up
In the previous snow procedure code, we maintained an array of Grand_list to maintain the effect of the snow pile
min_height = 100000
Snow on the ground
for i in range(len(grand_list)):
if grand_list[i][0] < 375:
min_height = min(min_height, grand_list[i][1])
Copy the code
Then enter the maintenance program:
draw_xue(snow_list, screen, bg_size, grand_has, grand_list)
Copy the code
Finally, draw the snow
for i in range(len(grand_list)):
pygame.draw.circle(screen, (grand_list[i][4], grand_list[i][5], grand_list[i][6]), grand_list[i][:2],
grand_list[i][3] - 3)
Copy the code
The renderings are shown above.
The process of realizing fireworks
First of all, define the fireworks category:
class Fireworks() :
is_show = False
x, y = 0.0
vy = 0
p_list = []
color = [0.0.0]
v = 0
def __init__(self, x, y, vy, n=300, color=[0.255.0], v=10) :
self.x = x
self.y = y
self.vy = vy
self.color = color
self.v = v
for i in range(n):
self.p_list.append([random.random() * 2 * math.pi, 0, v * math.pow(random.random(), 1 / 3)])
def run(self) :
global show_n
for p in self.p_list:
p[1] = p[1] + (random.random() * 0.6 + 0.7) * p[2]
p[2] = p[2] * 0.97
if p[2] < 1.2:
self.color[0] * =0.9999
self.color[1] * =0.9999
self.color[2] * =0.9999
if max(self.color) < 10 or self.y > WIN_H + p[1]:
show_n -= 1
self.is_show = False
break
self.vy += 10 * t1
self.y += self.vy * t1
Copy the code
Then, we need to plot the point of ascent before the firework is released, which is similar to the initialization of snow.
def init_yanhua(bg_size) :
yanhua_list = []
for i in range(5):
x_site = random.randrange(0, WIN_W) # snowflake center position
y_site = WIN_H # snowflake center position
X_shift = 0 # x offset
radius = random.randint(6.10) # radius and y-cycle rise and fall
xxxxx = random_color(150.255)
red = xxxxx[0]
green = xxxxx[1]
blue = xxxxx[2]
yanhua_list.append([x_site, y_site, X_shift, radius, red, green, blue])
return yanhua_list
Copy the code
And then I’m going to draw the ascent
def draw_yanhua(yanhua_list: [], screen, bg_size: []) :
global fk_list
for i in range(len(yanhua_list)):
# Draw snowflakes, color, position, size
pygame.draw.circle(screen, (yanhua_list[i][4], yanhua_list[i][5], yanhua_list[i][6]), yanhua_list[i][:2],
yanhua_list[i][3] - 3)
yanhua_list[i][0] += yanhua_list[i][2]
yanhua_list[i][1] -= yanhua_list[i][3]
if yanhua_list[i][1] < =0:
# tmp = []
yanhua_list[i][1] = WIN_H
yanhua_list[i][0] = random.randrange(0, bg_size[0])
if yanhua_list[i][1] <= random.randint(200.400) :# Todo fireworks
fk = Fireworks(yanhua_list[i][0], yanhua_list[i][1] -20, n=300, color=red_random(1.150), v=10)
fk_list.append(fk)
yanhua_list[i][1] = WIN_H
yanhua_list[i][0] = random.randrange(0, bg_size[0])
Copy the code
The renderings are as follows:
Circled are the fireworks of the ascent.
And finally, the bloom part, which is actually maintained in the code for the ascent process, if you go beyond a certain random height, it will generate a firework, but it’s not rendered, so now we add the render.
for fk in fk_list:
fk.run()
for p in fk.p_list:
x, y = fk.x + p[1] * math.cos(p[0]), fk.y + p[1] * math.sin(p[0])
if random.random() < 0.055:
screen.set_at((int(x), int(y)), (255.255.255))
else:
screen.set_at((int(x), int(y)), (int(fk.color[0]), int(fk.color[1]), int(fk.color[2])))
tmp = []
for fk in fk_list:
for p in fk.p_list:
x, y = fk.x + p[1] * math.cos(p[0]), fk.y + p[1] * math.sin(p[0])
if y < WIN_H - 1000:
tmp.append(fk)
break
fk_list = tmp
Copy the code
The end result is just like the top effect.
The complete code
By combining the above processes, the result is as follows, which interested friends can optimize according to their own needs.
import pygame
import random
import math
pygame.init()
pygame.mixer.init()
pygame.font.init()
WIN_W = 2200
WIN_H = 1300
t1 = 0.18 # Time flow rate
show_n = 0
show_frequency = 0.0015 # Fireworks burst frequency, the higher the value, the higher the frequency
color_list = [
[255.0.0]
]
yanhua_map = {}
fk_list = []
class Fireworks() :
is_show = False
x, y = 0.0
vy = 0
p_list = []
color = [0.0.0]
v = 0
def __init__(self, x, y, vy, n=300, color=[0.255.0], v=10) :
self.x = x
self.y = y
self.vy = vy
self.color = color
self.v = v
for i in range(n):
self.p_list.append([random.random() * 2 * math.pi, 0, v * math.pow(random.random(), 1 / 3)])
def run(self) :
global show_n
for p in self.p_list:
p[1] = p[1] + (random.random() * 0.6 + 0.7) * p[2]
p[2] = p[2] * 0.97
if p[2] < 1.2:
self.color[0] * =0.9999
self.color[1] * =0.9999
self.color[2] * =0.9999
if max(self.color) < 10 or self.y > WIN_H + p[1]:
show_n -= 1
self.is_show = False
break
self.vy += 10 * t1
self.y += self.vy * t1
def random_color(l, r) :
return [random.randint(l, r), random.randint(l, r), random.randint(l, r)]
def red_random(l, r) :
return [255, random.randint(l, r), random.randint(l, r)]
def init_yanhua(bg_size) :
yanhua_list = []
for i in range(5):
x_site = random.randrange(0, WIN_W) # snowflake center position
y_site = WIN_H # snowflake center position
X_shift = 0 # x offset
radius = random.randint(6.10) # radius and y-cycle rise and fall
xxxxx = random_color(150.255)
red = xxxxx[0]
green = xxxxx[1]
blue = xxxxx[2]
yanhua_list.append([x_site, y_site, X_shift, radius, red, green, blue])
return yanhua_list
def init_xue(bg_size) :
snow_list = []
for i in range(200):
x_site = random.randrange(0, bg_size[0]) # snowflake center position
y_site = random.randrange(0, bg_size[1]) # snowflake center position
X_shift = random.randint(-1.1) # x offset
radius = random.randint(4.6) # radius and y cycle drop
xxxxx = random_color(150.255)
# red = xxxxx[0]
# green = xxxxx[1]
# blue = xxxxx[2]
snow_list.append([x_site, y_site, X_shift, radius, 255.255.255])
return snow_list
def draw_xue(snow_list: [], screen, bg_size: [], grand_has: set, grand_list: []) :
# Snowflake list loop
Snow in the sky
for i in range(len(snow_list)):
# Draw snowflakes, color, position, size
pygame.draw.circle(screen, (snow_list[i][4], snow_list[i][5], snow_list[i][6]), snow_list[i][:2],
snow_list[i][3] - 3)
# Move snowflake position (next loop works)
snow_list[i][0] += snow_list[i][2]
snow_list[i][1] += snow_list[i][3]
If snow falls off the screen, reset the position
if snow_list[i][1] > bg_size[1] :# tmp = []
snow_list[i][1] = random.randrange(-50, -10)
snow_list[i][0] = random.randrange(0, bg_size[0])
x = snow_list[i][0]
y = bg_size[1]
while (grand_has.__contains__(x * 10000 + y)):
y = y - snow_list[i][3]
grand_has.add(x * 10000 + y)
grand_list.append(
[x, y, snow_list[i][2], snow_list[i][3], snow_list[i][4], snow_list[i][5],
snow_list[i][6]])
def draw_yanhua(yanhua_list: [], screen, bg_size: []) :
global fk_list
for i in range(len(yanhua_list)):
# Draw snowflakes, color, position, size
pygame.draw.circle(screen, (yanhua_list[i][4], yanhua_list[i][5], yanhua_list[i][6]), yanhua_list[i][:2],
yanhua_list[i][3] - 3)
# Move snowflake position (next loop works)
yanhua_list[i][0] += yanhua_list[i][2]
yanhua_list[i][1] -= yanhua_list[i][3]
If snow falls off the screen, reset the position
if yanhua_list[i][1] < =0:
# tmp = []
yanhua_list[i][1] = WIN_H
yanhua_list[i][0] = random.randrange(0, bg_size[0])
if yanhua_list[i][1] <= random.randint(200.400) :# Todo fireworks
fk = Fireworks(yanhua_list[i][0], yanhua_list[i][1] -20, n=300, color=red_random(1.150), v=10)
fk_list.append(fk)
yanhua_list[i][1] = WIN_H
yanhua_list[i][0] = random.randrange(0, bg_size[0])
def show_shi(a: list, n, screen) :
i = 2 * n - 1
j = 2 * n
if i >= len(a):
i = len(a) - 2
j = len(a) - 1
if i >= 0:
myfont = pygame.font.SysFont('simHei'.30)
textsurface = myfont.render(a[i], False, random_color(150.255))
screen.blit(textsurface, (WIN_W / 2.30))
if j >= 0:
myfont = pygame.font.SysFont('simHei'.100)
textsurface = myfont.render(a[j], False, red_random(1.1))
screen.blit(textsurface, (WIN_W / 2 - 200.50))
def main() :
global show_n
global fk_list
bg_size = (WIN_W, WIN_H)
screen = pygame.display.set_mode(bg_size)
# bg_img = "./1.png"
pygame.display.set_caption("Happy New Year")
# bg = pygame.image.load(bg_img)
pygame.mixer.music.load('D:\ CloudMusic\ Hour Girl - Xiaguang - End song of "Fairy Century".mp3')
grand_list = []
font_values = ['Happy New Year']
grand_has = set()
clock = pygame.time.Clock()
yanhua_list = init_yanhua(bg_size)
snow_list = init_xue(bg_size)
# Game main loop
while True:
if not pygame.mixer.music.get_busy():
pygame.mixer.music.play()
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit()
screen.fill((0.0.0))
draw_yanhua(yanhua_list, screen, bg_size)
if len(fk_list) ! =0:
print(len(fk_list))
# # Fireworks
show_shi(font_values, 0, screen)
for fk in fk_list:
fk.run()
for p in fk.p_list:
x, y = fk.x + p[1] * math.cos(p[0]), fk.y + p[1] * math.sin(p[0])
if random.random() < 0.055:
screen.set_at((int(x), int(y)), (255.255.255))
else:
screen.set_at((int(x), int(y)), (int(fk.color[0]), int(fk.color[1]), int(fk.color[2])))
tmp = []
for fk in fk_list:
for p in fk.p_list:
x, y = fk.x + p[1] * math.cos(p[0]), fk.y + p[1] * math.sin(p[0])
if y < WIN_H - 1000:
tmp.append(fk)
break
fk_list = tmp
min_height = 100000
Snow on the ground
for i in range(len(grand_list)):
if grand_list[i][0] < 375:
min_height = min(min_height, grand_list[i][1])
draw_xue(snow_list, screen, bg_size, grand_has, grand_list)
for i in range(len(grand_list)):
pygame.draw.circle(screen, (grand_list[i][4], grand_list[i][5], grand_list[i][6]), grand_list[i][:2],
grand_list[i][3] - 3)
pygame.display.update()
time_passed = clock.tick(50)
if __name__ == '__main__':
main()
Copy the code