Python实现过年烟花效果及打包成可执行文件
博客:Python实现过年烟花效果及打包成可执行文件
在这篇博客中,我们将详细讲解如何使用Python和Pygame库实现一个过年烟花效果的程序,并介绍如何将Python脚本打包成Windows上可以直接执行的exe文件。我们将从代码的各个模块入手,逐步解析其实现原理,并最终介绍如何使用打包工具将程序打包成可执行文件。
文章目录
1. 程序结构概述
该程序主要由以下几个模块组成:
- Pygame初始化与屏幕设置:初始化Pygame并设置屏幕大小。
- 颜色与字体定义:定义烟花和文字的颜色,并加载书法字体。
- 烟花粒子类:定义烟花爆炸后的粒子效果。
- 烟花类:定义烟花的发射、爆炸和绘制逻辑。
- 文字效果:实现七彩渐变文字的绘制。
- 主循环:控制烟花的生成、移动、爆炸以及文字的滚动显示。
接下来,我们将逐一讲解这些模块的实现细节。
2. Pygame初始化与屏幕设置
import pygame
import random
import math
import os
# 初始化pygame
pygame.init()
# 设置屏幕大小(17:9比例)
screen_width = 1700
screen_height = 900
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("过年烟花效果")
- Pygame初始化:
pygame.init()
是Pygame库的初始化函数,用于启动Pygame的所有模块。 - 屏幕设置:我们设置了一个17:9比例的屏幕,宽度为1700像素,高度为900像素。
pygame.display.set_mode()
用于创建屏幕对象,pygame.display.set_caption()
用于设置窗口标题。
3. 颜色与字体定义
# 定义颜色
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
COLORS = [
(255, 0, 0), # 红色
(255, 165, 0), # 橙色
(255, 255, 0), # 黄色
(0, 255, 0), # 绿色
(0, 0, 255), # 蓝色
(75, 0, 130), # 靛色
(238, 130, 238), # 紫色
]
# 加载书法字体
font_path = "汇文港黑v1.001.ttf"
if not os.path.exists(font_path):
raise FileNotFoundError(f"字体文件 {font_path} 未找到,请确保字体文件存在!")
font = pygame.font.Font(font_path, 99) # 使用书法字体,大小为70
- 颜色定义:我们定义了一些常见的颜色,包括黑色、白色以及彩虹七色。这些颜色将用于烟花粒子和文字的绘制。
- 字体加载:我们加载了一个书法字体文件(
汇文港黑v1.001.ttf
,这是一个免费的字体,你可以在该链接找到分享原文【發佈】匯文系列字體),并设置了字体大小为99(就是取一个长长久久之意,强迫症患者可以改成100)。如果字体文件不存在,程序会抛出错误。
4. 烟花粒子类
class Particle:
def __init__(self, x, y, color, effect_type):
self.x = x
self.y = y
self.color = color
self.radius = random.randint(2, 4)
self.speed = random.uniform(1, 3)
self.angle = random.uniform(0, 2 * math.pi)
self.life = random.randint(20, 40)
self.effect_type = effect_type # 爆炸效果类型
self.range_multiplier = random.uniform(0.5, 2.0) # 随机范围参数
def move(self):
if self.effect_type == 1: # 普通爆炸
self.x += math.cos(self.angle) * self.speed * self.range_multiplier
self.y += math.sin(self.angle) * self.speed * self.range_multiplier
elif self.effect_type == 2: # 环形爆炸
self.angle += 0.05 # 缓慢旋转
radius = self.life * self.range_multiplier # 半径随时间变化
self.x += math.cos(self.angle) * radius * 0.1
self.y += math.sin(self.angle) * radius * 0.1
elif self.effect_type == 3: # 星形爆炸
star_points = 5 # 星形的顶点数
angle_step = (2 * math.pi) / star_points
self.angle += 0.05 # 缓慢旋转
radius = self.life * self.range_multiplier # 半径随时间变化
self.x += math.cos(self.angle * star_points) * radius * 0.1
self.y += math.sin(self.angle * star_points) * radius * 0.1
elif self.effect_type == 4: # 心形爆炸
t = self.life / 40 # 参数t,控制心形轨迹
x_offset = 16 * (math.sin(t) ** 3)
y_offset = -13 * math.cos(t) + 5 * math.cos(2 * t) + 2 * math.cos(3 * t) + math.cos(4 * t)
self.x += x_offset * self.range_multiplier * 0.1
self.y += y_offset * self.range_multiplier * 0.1
elif self.effect_type == 5: # 瀑布爆炸
self.y += self.speed * self.range_multiplier # 向下扩散
self.x += math.cos(self.angle) * self.speed * 0.2 # 轻微水平扩散
elif self.effect_type == 6: # 螺旋上升爆炸
self.angle += 0.1 # 螺旋角度变化
radius = self.life * self.range_multiplier # 半径随时间变化
self.x += math.cos(self.angle) * radius * 0.1
self.y -= math.sin(self.angle) * radius * 0.1 # 向上扩散
self.life -= 1
def draw(self):
pygame.draw.circle(screen, self.color, (int(self.x), int(self.y)), self.radius)
- 粒子初始化:每个粒子都有位置、颜色、半径、速度、角度、生命周期等属性。
effect_type
决定了粒子的爆炸效果类型。 - 粒子移动:根据
effect_type
的不同,粒子会以不同的方式移动。例如,普通爆炸、环形爆炸、星形爆炸、心形爆炸等。 - 粒子绘制:使用
pygame.draw.circle()
绘制粒子。
这个部分代码比较多,不过都写了注释,需有修改的需要请按照注释修改。
5. 烟花类
class Firework:
def __init__(self):
self.x = random.randint(0, screen_width)
self.y = screen_height
self.color = random.choice(COLORS)
self.particles = []
self.exploded = False
self.speed = 10 # 加快烟花发射速度
self.effect_type = 1 if random.random() < 0.5 else random.randint(2, 6)
def explode(self, displayed_sentences):
# 检查烟花爆炸位置是否与字体重叠
for sentence, x, y in displayed_sentences:
text_width, text_height = font.size(sentence)
if (
self.x >= x - text_width // 2
and self.x <= x + text_width // 2
and self.y >= y - text_height // 2
and self.y <= y + text_height // 2
):
# 如果重叠,调整烟花爆炸位置
self.x = random.randint(0, screen_width)
self.y = random.randint(0, screen_height // 2)
break
particle_count = 150 # 增加粒子数量
for _ in range(particle_count):
particle = Particle(self.x, self.y, self.color, self.effect_type)
self.particles.append(particle)
self.exploded = True
def move(self, displayed_sentences):
if not self.exploded:
self.y -= self.speed # 使用更快的速度
if self.y <= random.randint(100, 300):
self.explode(displayed_sentences)
else:
for particle in self.particles:
particle.move()
def draw(self):
if not self.exploded:
pygame.draw.circle(screen, self.color, (int(self.x), int(self.y)), 5)
else:
for particle in self.particles:
particle.draw()
- 烟花初始化:烟花从屏幕底部随机位置发射,颜色随机,爆炸效果类型也随机。
- 烟花爆炸:当烟花上升到一定高度时,会爆炸生成多个粒子。爆炸时会检查是否与文字重叠,如果重叠则调整爆炸位置。
- 烟花移动与绘制:烟花在未爆炸时会向上移动,爆炸后会绘制所有粒子。
6. 文字效果
def draw_gradient_text(text, font, x, y, colors):
text_surface = font.render(text, True, WHITE).convert_alpha()
text_width = text_surface.get_width()
text_height = text_surface.get_height()
# 创建渐变颜色条
gradient = pygame.Surface((text_width, text_height))
for i in range(text_width):
color_index = int((i / text_width) * (len(colors) - 1))
color1 = colors[color_index]
color2 = colors[color_index + 1] if color_index + 1 < len(colors) else colors[color_index]
ratio = (i / text_width) * (len(colors) - 1) - color_index
color = (
int(color1[0] + (color2[0] - color1[0]) * ratio),
int(color1[1] + (color2[1] - color1[1]) * ratio),
int(color1[2] + (color2[2] - color1[2]) * ratio),
)
pygame.draw.line(gradient, color, (i, 0), (i, text_height))
# 将渐变颜色条与文字结合
text_surface.blit(gradient, (0, 0), special_flags=pygame.BLEND_MULT)
screen.blit(text_surface, (x, y))
- 渐变文字绘制:该函数实现了七彩渐变文字的绘制效果。首先渲染文字,然后创建一个渐变颜色条,最后将渐变颜色条与文字结合,形成渐变效果。
7. 主循环
clock = pygame.time.Clock()
fireworks = []
# 加载句子
sentences = load_sentences("words.txt")
current_sentence_index = 0
sentence_y = screen_height # 初始位置在屏幕底部
displayed_sentences = [] # 存储已经显示的句子及其位置
# 计算句子的合适位置
def calculate_sentence_positions(sentences, font):
margin = 20 # 句子之间的间距
total_height = sum(font.size(sentence)[1] for sentence in sentences) + margin * (len(sentences) - 1)
start_y = screen_height * 0.4 - total_height // 2 # 整体居中在屏幕40%的位置
positions = []
y = start_y
for sentence in sentences:
text_width, text_height = font.size(sentence)
x = (screen_width - text_width) // 2
positions.append((x, y))
y += text_height + margin # 下一句的位置
return positions
# 计算所有句子的目标位置
sentence_positions = calculate_sentence_positions(sentences, font)
# 初始化时立即生成多个烟花
for _ in range(10): # 生成10个烟花
fireworks.append(Firework())
running = True
while running:
screen.fill(BLACK)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# 添加新的烟花
if random.random() < 0.1: # 增加烟花生成概率
fireworks.append(Firework())
# 更新和绘制烟花
for firework in fireworks:
firework.move(displayed_sentences)
firework.draw()
# 移除已经消失的烟花
fireworks = [firework for firework in fireworks if not firework.exploded or any(particle.life > 0 for particle in firework.particles)]
# 绘制当前句子
if current_sentence_index < len(sentences):
current_sentence = sentences[current_sentence_index]
text_width, text_height = font.size(current_sentence)
target_x, target_y = sentence_positions[current_sentence_index]
# 如果句子未到达目标位置,继续滚动
if sentence_y > target_y:
draw_gradient_text(current_sentence, font, (screen_width - text_width) // 2, sentence_y, COLORS)
sentence_y -= 5 # 控制字体滚动速度
else:
# 句子停止后,将其添加到已显示句子列表中
displayed_sentences.append((current_sentence, target_x, target_y))
current_sentence_index += 1 # 切换到下一句
sentence_y = screen_height # 重置到屏幕底部
# 绘制所有已显示的句子
for sentence, x, y in displayed_sentences:
draw_gradient_text(sentence, font, x, y, COLORS)
pygame.display.flip()
clock.tick(30)
pygame.quit()
- 主循环:主循环负责控制程序的运行。它不断更新烟花的状态、绘制烟花和文字,并处理用户输入(如关闭窗口)。
- 烟花生成与移除:每隔一段时间生成新的烟花,移除已经消失的烟花。
- 文字滚动显示:文字从屏幕底部滚动到指定位置,形成动态效果。
8. 打包成可执行文件
为了将Python脚本打包成Windows上可以直接执行的exe文件,我们可以使用 PyInstaller
工具。以下是具体步骤:
8.1 安装 PyInstaller
首先,确保你已经安装了 PyInstaller
。如果没有安装,可以使用以下命令进行安装:
pip install pyinstaller
8.2 打包脚本
在命令行中,导航到脚本所在的目录,然后运行以下命令:
pyinstaller --onefile --windowed 过年烟花.py
--onefile
:将所有依赖打包成一个单独的exe文件。--windowed
:不显示命令行窗口(适用于GUI程序)。
这里有一点要特别注意,如果是第一次使用pyinstaller
可能会出现这个bug
pyinstaller : 无法将“pyinstaller”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。
所在位置 行:1 字符: 1
+ pyinstaller --onefile --windowed 过年烟花.py
+ ~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (pyinstaller:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
这个原因pyinstaller没有加入环境变量导致的,Windows容易出现这个问题,快捷方案如下(交给解释器自己去处理):
python -m PyInstaller --onefile --windowed 过年烟花.py
如果还有疑问可以参考我的另外一篇博客。
8.3 获取可执行文件
打包完成后,你可以在 dist
目录下找到生成的 过年烟花.exe
文件。你可以将这个文件分发给其他Windows用户,他们无需安装Python环境即可运行该程序。
此时要注意的是打包好的文件是个exe文件,但是我们之前使用的ttf文件和txt并不会自动打包进去,因为我们需要手动复制粘贴一下。直接放到exe文件的目录即可。
8.4 下载源代码与打包好的文件
百度网盘链接:通过网盘分享的文件:2025 过年烟花
链接: https://pan.baidu.com/s/1n8T54A8QiHGrw0H5bs3Wfw?pwd=49ht 提取码: 49ht
9. 总结
通过这篇博客,我们详细讲解了如何使用Python和Pygame实现一个过年烟花效果的程序,并介绍了如何将Python脚本打包成Windows上可以直接执行的exe文件。
希望这篇博客对你有所帮助,祝你在编程的道路上越走越远!同时也提前祝大家2025新年快乐。
原文地址:https://blog.csdn.net/FontThrone/article/details/145247287
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!