脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Python - 新年到教你如何用Python实现雪夜烟花景

新年到教你如何用Python实现雪夜烟花景

2022-09-07 09:48炒鸡辣鸡123 Python

新年到,祝大家新年快乐,今天小编交大家如何用Python实现雪夜烟花景效果,实现代码真的很简单,感兴趣的朋友跟随小编一起看看吧

运行截图

新年到教你如何用Python实现雪夜烟花景

什么?你说你看不清烟花?那我换一种颜色,请点开看。

新年到教你如何用Python实现雪夜烟花景

 

实现过程

准备工作

使用语言和框架:python、pygame。
安装pygame:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ --trusted-host pypi.tuna.tsinghua.edu.cn pygame

你需要知道的基础知识

首先,pygame渲染是同步的,所以同屏渲染的点过多之后,就会造成卡顿的情况。
其次,pygame的代码逻辑是,周期性渲染一系列的屏,从而产生连续的动画。

你需要掌握的框架基础知识:

 

初始化过程

import pygame
pygame.init()
pygame.mixer.init()
pygame.font.init()

获取字体

myfont = pygame.font.SysFont('simHei', 30)
textsurface = myfont.render(a[i], False, random_color(150, 255))
screen.blit(textsurface, (80, 30))

画圈

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)

加载背景音乐

screen = pygame.display.set_mode(bg_size)
pygame.display.set_caption("新年快乐")
bg = pygame.image.load(bg_img)
pygame.mixer.music.load('D:\\CloudMusic\\小时姑娘 - 霞光-《精灵世纪》片尾曲.mp3')

 

核心代码

基础架子

首先,需要实现一个基础的事件循环的架子,如下:

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("新年快乐")
  pygame.mixer.music.load('D:\\CloudMusic\\小时姑娘 - 霞光-《精灵世纪》片尾曲.mp3')
  font_values = ['新年快乐']

  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()

 

下雪的过程

现在,需要实现下雪的过程,首先,考虑定义定义一堆初始化的下雪点

def init_xue(bg_size):
  snow_list = []
  for i in range(200):
      x_site = random.randrange(0, bg_size[0])  # 雪花圆心位置
      y_site = random.randrange(0, bg_size[1])  # 雪花圆心位置
      X_shift = random.randint(-1, 1)  # x 轴偏移量
      radius = random.randint(4, 6)  # 半径和 y 周下降量
      xxxxx = random_color(150, 255)
      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: []):
  # 雪花列表循环
  # todo 空中的雪
  for i in range(len(snow_list)):
      # 绘制雪花,颜色、位置、大小
      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)
      # 移动雪花位置(下一次循环起效)
      snow_list[i][0] += snow_list[i][2]
      snow_list[i][1] += snow_list[i][3]
      # 如果雪花落出屏幕,重设位置
      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]])

集成到上面的架子中,效果如下:

新年到教你如何用Python实现雪夜烟花景

不过目前的下雪没有质感,可以考虑在底部堆一些雪,只需要在雪落到地上做特判即可。

 

雪落到地上堆起来的过程

在前面的下雪过程的代码中,我们维护了一个Grand_list的数组,目的就是维护堆雪的效果

min_height = 100000
# todo 地上的积雪
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)

新年到教你如何用Python实现雪夜烟花景

效果图如上。

 

实现烟花的过程

首先定义出烟花类:

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 init_yanhua(bg_size):
  yanhua_list = []
  for i in range(5):
      x_site = random.randrange(0, WIN_W)  # 雪花圆心位置
      y_site = WIN_H  # 雪花圆心位置
      X_shift = 0  # x 轴偏移量
      radius = random.randint(6, 10)  # 半径和 y 周上升降量
      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 draw_yanhua(yanhua_list: [], screen, bg_size: []):
  global fk_list
  for i in range(len(yanhua_list)):
      # 绘制雪花,颜色、位置、大小
      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 放烟花
          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])

效果图如下:

新年到教你如何用Python实现雪夜烟花景

圈出来的就是上升过程的烟花。
最后就是绽放部分,其实在上升过程的代码中有维护,如果超过某个随机高度,就会生成一个烟花,只是没有渲染,现在我们把渲染加上。

 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

最终的运行效果就如最顶上的效果一样。

 

完整代码

将上述过程进行组合,结果如下,感兴趣的朋友可以按自己的需求进行优化。

import pygame
import random
import math
pygame.init()
pygame.mixer.init()
pygame.font.init()
WIN_W = 2200
WIN_H = 1300
t1 = 0.18  # 时间流速
show_n = 0
show_frequency = 0.0015  # 烟花绽放频率,数值越大频率越高
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)  # 雪花圆心位置
      y_site = WIN_H  # 雪花圆心位置
      X_shift = 0  # x 轴偏移量
      radius = random.randint(6, 10)  # 半径和 y 周上升降量
      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])  # 雪花圆心位置
      y_site = random.randrange(0, bg_size[1])  # 雪花圆心位置
      X_shift = random.randint(-1, 1)  # x 轴偏移量
      radius = random.randint(4, 6)  # 半径和 y 周下降量
      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: []):
  # 雪花列表循环
  # todo 空中的雪
  for i in range(len(snow_list)):
      # 绘制雪花,颜色、位置、大小
      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)
      # 移动雪花位置(下一次循环起效)
      snow_list[i][0] += snow_list[i][2]
      snow_list[i][1] += snow_list[i][3]
      # 如果雪花落出屏幕,重设位置
      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)):
      # 绘制雪花,颜色、位置、大小
      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 放烟花
          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("新年快乐")
  # bg = pygame.image.load(bg_img)
  pygame.mixer.music.load('D:\\CloudMusic\\小时姑娘 - 霞光-《精灵世纪》片尾曲.mp3')
  grand_list = []
  font_values = ['新年快乐']
  grand_has = set()
  clock = pygame.time.Clock()
  yanhua_list = init_yanhua(bg_size)
  snow_list = init_xue(bg_size)
  # 游戏主循环
  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))
      # # 放烟花
      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
      # todo 地上的积雪
      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()

到此这篇关于新年到教你如何用Python实现雪夜烟花景的文章就介绍到这了,更多相关Python雪夜烟花景内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/xielinrui123/article/details/122701390

延伸 · 阅读

精彩推荐
  • Python用Python实现局域网控制电脑

    用Python实现局域网控制电脑

    大家好,本篇文章主要讲的是用Python实现局域网控制电脑,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下...

    小木_.6822022-08-31
  • PythonPython的SimpleHTTPServer模块用处及使用方法简介

    Python的SimpleHTTPServer模块用处及使用方法简介

    这篇文章主要介绍了Python的SimpleHTTPServer模块用处及使用方法简介,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下...

    Mr.joey5782021-01-07
  • Python浅谈python中的@以及@在tensorflow中的作用说明

    浅谈python中的@以及@在tensorflow中的作用说明

    这篇文章主要介绍了浅谈python中的@以及@在tensorflow中的作用说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    GZKPeng4762021-09-15
  • PythonPython的数据类型与标识符和判断语句详解

    Python的数据类型与标识符和判断语句详解

    在本篇文章里小编给大家整理了一篇关于python数据类型与标识符和判断语句的介绍,有需要的朋友们可以学习下,希望能够给你带来帮助...

    lyl05156610602022-01-10
  • Pythonpython编写五子棋游戏

    python编写五子棋游戏

    这篇文章主要为大家详细介绍了python编写五子棋游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    MiManchi7293922021-11-12
  • PythonPython超有用的多版本管理工具pyenv

    Python超有用的多版本管理工具pyenv

    使用不同的Python版本,如果我们把需要的不同版本的Python都下载到服务器上,管理起来会非常困难,多版本并存又容易互相干扰,接下来就来介绍一个Pytho...

    tigeriaf9732022-01-12
  • Python详解用Python把PDF转为Word方法总结

    详解用Python把PDF转为Word方法总结

    这篇文章主要介绍了详解用Python把PDF转为Word方法总结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们...

    琪老师60611362021-10-21
  • Pythonpython3实现读取chrome浏览器cookie

    python3实现读取chrome浏览器cookie

    这里给大家分享的是python3读取chrome浏览器的cookie(CryptUnprotectData解密)的代码,主要思路是读取到的cookies被封装成字典,可以直接给requests使用。 ...

    黑暗圣堂武士16732020-08-28