新年到教你如何用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]])

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

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

雪落到地上堆起来的过程

在前面的下雪过程的代码中,我们维护了一个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)

效果图如上。

实现烟花的过程

首先定义出烟花类:

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

效果图如下:

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

 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雪夜烟花景内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python Pygame制作雪夜烟花景

    目录 运行截图 实现过程 核心代码 基础架子 下雪的过程 雪落到地上堆起来的过程 实现烟花的过程 完整代码 运行截图 运行效果: 什么?你说你看不清烟花?那我换一种颜色,请点开看. 实现过程 准备工作 使用语言和框架:python.pygame. 安装pygame: pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ --trusted-host pypi.tuna.tsinghua.edu.cn pygame 你需要知道的基础知识

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

    运行截图 运行效果: 什么?你说你看不清烟花?那我换一种颜色,请点开看. 实现过程 准备工作 使用语言和框架:python.pygame.安装pygame: pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ --trusted-host pypi.tuna.tsinghua.edu.cn pygame 你需要知道的基础知识 首先,pygame渲染是同步的,所以同屏渲染的点过多之后,就会造成卡顿的情况.其次,pygame的代码逻辑是,

  • 教你如何用python操作摄像头以及对视频流的处理

    实验介绍 此次实验帮助大家利用 OpenCV 去读取摄像头的视频流,你可以直接使用笔记本本身的摄像头,也可以用 USB 连接直接的摄像头.如果你在操作过程中,摄像头读取失败, 实验中还为你提供了几个问题排查步骤.当然,对视频进行操作时还需要讲解视频相关的编解码格式以及特定帧的读取.在实验的最后,还提供了 OpenCV 的项目实战:视频录制与视频读取. 知识点 视频录制 视频编解码格式 视频读取以及特定帧的读取 视频录制 使用 OpenCV 录制视频,主要涉及 OpenCV 的 VideoWrit

  • 教你如何用python开发一款数字推盘小游戏

    今年年初,新一季的<最强大脑>开播了,第一集选拔的时候大家做了一个数字游戏,名叫<数字华容道>,当时何猷君以二十几秒的成绩夺得该项目的冠军,看了这个游戏之后我决定要写一个<数字华容道>的程序,过去了半年,我终于记起了这件事,今天就来实现. 数字推盘游戏(n-puzzle)是一种智力游戏,常见的类型有十五数字推盘游戏和八数字推盘游戏等.十五数字推盘游戏的板上会有十五个方块和一个大小相当于一个方块的空位(供方块移动之用),当15个数字依次排序并且最后一个格子为空位即代表挑战

  • 教你如何用python爬取王者荣耀月收入流水线

    前言 王者荣耀是最近几年包括现在一直都是最热销的手游,收益主要来源是游戏里面人物皮肤.今天就来爬取展示王者荣耀近一年收入流水线动图,看看王者荣耀有多赚钱(哈哈哈哈) 主要可视化内容: 一.App收入排行流水线 1.1.获取数据 数据来源于:七麦数据,里面数据都是通过异步加载,因此只需要找到异步链接,修改参数就可以直接获取到数据. 备注:需要cookie才可以获取数据. 请求链接 https://api.qimai.cn/pred/appMonthPred?analysis=eEcbRhNVVB9

  • 教你如何用Python实现人脸识别(含源代码)

    工具与图书馆 Python-3.x CV2-4.5.2 矮胖-1.20.3 人脸识别-1.3.0 若要安装上述软件包,请使用以下命令. pip install numpy opencv-python 要安装FaceRecognition,首先安装dlib包. pip install dlib 现在,使用以下命令安装面部识别模块 pip install face_recognition 下载人脸识别Python代码 请下载python面部识别项目的源代码: 人脸识别工程代码 项目数据集 我们可以使

  • Python办公自动化之教你如何用Python将任意文件转为PDF格式

    一.word转PDF 这里借助Python的docx2pdf去完成转换操作,该库的安装命令如下: pip install docx2pdf 目标:读取文件夹下的全部word文件,然后进行转换,最后保存到对应的文件夹中. 这里辰哥新建两个word文件作为演示,打开其中一个word看看 里面不仅有文字,同时包含有图片 import os from docx2pdf import convert word_path = 'word_path' word_to_pdf = 'word_to_pdf' f

  • 教你如何用一行Python代码实现GUI图形界面

    目录 1.选择文件夹 2.选择文件 3.选择日期 4.输入文本 5.弹窗无按钮 6.弹窗无标题 7.弹窗只有OK按钮 8.弹窗只有Error按钮(红色) 9.显示通知窗口 10.弹窗选择 11.自定义弹窗 12.实战 GUI(图形用户界面),顾名思义就是用图形的方式,来显示计算机操作的界面,更加方便且直观. 一个好看又好用的GUI,可以大大提高大家的使用体验,提高效率. 比如你想开发一个计算器,如果只是一个程序输入,输出窗口的话,是没有用户体验的. 所以开发一个图形化的小窗口,就变得很有必要.

  • 手把手教你如何用Pycharm2020.1.1配置远程连接的详细步骤

    配置说明 使用Pycharm 2020.1.1 professional 专业版.(据说只有专业版可以远程连接)如果不是专业的伙伴,可以用校园邮箱注册一个专业版,免费的哦! 步骤 1. 设置Connection 配置文件在这里Tools->Deployment->Configuration 进入后看到如下界面. 如果你是首次设置,需要点击左上角的"+"添加配置信息.类型选择"SFTP".然后添加SHH configuration信息,界面如下.填写Hos

  • 教你如何用pycharm安装pyqt5及其相关配置

    目录 一.配置专门的虚拟环境 1.单独创建一个文件夹来专门存放pyqt5的代码并建立虚拟环境 2.进入pycharm,并打开python-pyqt5项目 3.配置虚拟环境 二.配置虚拟的python环境 三.安装pyqt5和pyqt5-tools工具 1.安装:pyqt5 2.安装:pyqt5-tools 四.配置系统环境变量 五.配置Qt Designer 六.配置PyUIC 七.注意事项 一.配置专门的虚拟环境 原因:不同项目采用不同版本的python,所依赖的库的版本也不一样,为了避免版本

随机推荐