看到很多小伙伴使用python实现了很多动态的效果,非常漂亮。
闲来无事,也参考做法,自己做了一幅雪落动图。过程中,遇到了一些问题,花了点时间搞定。
基础代码问了chatGPT,但是初始实现效果,不是很理想。
- import pygame
- import random
- # 初始化Pygame
- pygame.init()
-
- # 设置窗口尺寸和标题
- window_width = 800
- window_height = 600
- window = pygame.display.set_mode((window_width, window_height))
- pygame.display.set_caption("雪花飘落")
-
- # 定义雪花颜色为白色
- WHITE = (255, 255, 255)
-
- # 创建雪花列表
- snowflakes = []
-
- # 创建雪花对象
- class Snowflake:
- def __init__(self, x, y, size):
- self.x = x
- self.y = y
- self.size = size
- self.speed = random.randint(1, 8)
-
- def fall(self):
- self.y += self.speed
- if self.y > window_height:
- self.y = random.randint(-50, -10)
- self.x = random.randint(0, window_width)
-
- def draw(self):
- pygame.draw.circle(window, WHITE, (self.x, self.y), self.size)
- # 创建GIF帧的列表
-
- # 主循环
- running = True
- while running:
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- running = False
-
- # 清空窗口
- window.fill((0, 0, 0))
-
- # 生成雪花
- # 控制生成雪花的数量,数量可以更改
- if len(snowflakes) < 100:
- x = random.randint(0, window_width)
- y = random.randint(0, window_height)
- # 定义雪花的大小,1-5之间随机,可以根据自己需求更改
- size = random.randint(1, 5)
- snowflake = Snowflake(x, y, size)
- snowflakes.append(snowflake)
-
- # 更新和绘制雪花
- for snowflake in snowflakes:
- snowflake.fall()
- snowflake.draw()
-
- # 刷新窗口
- pygame.display.flip()
-
- # 控制帧率
- pygame.time.delay(10)
-
- # 退出时关闭Pygame
- pygame.quit()
呈现效果如下:
原始代码是黑色背景,肯定不是我们期望的样子,我们预期增加一张美丽的背景图片来润色。
更换雪景背景,首先要导入一个模块
- from PIL import Image
-
根据背景图片修改窗口的大小。
- window_width = 1280
- window_height = 800
加载背景图片,图片把他放到了与代码文件相同的路径下。
- # 加载背景图片
- background_image= pygame.image.load("snow.jpg")
在窗口绘制背景图片,取代这一行代码:window.fill((0, 0, 0))
- # 绘制背景图片
- window.blit(background_image,(0,0))
更换背景后,效果呈现:
因为产生的动图,还没有定义格式,我们转变为GIF的动图。
先创建一个帧列表
- # 创建GIF帧的列表
- frames = []
获取当前帧的截图,并添加到列表
- # 获取当前帧的截图并添加到帧列表
- pygame_image = pygame.surfarray.array3d(pygame.display.get_surface())
- pil_image = Image.fromarray(pygame_image)
- pil_image = pil_image.rotate(-90,expand=True)
- frames.append(pil_image.copy())
这里需要注意pil_image = pil_image.rotate(-90,expand=True)的应用,默认压缩后的GIF动图可以因为某些原因自动旋转90度。我们通过pil_image.rotate设定产生的动图旋转方向和角度来纠正。
最后是将帧列表保存为GIF格式的文件
- # 保存帧列表为GIF文件
-
- frames[0].save("snowfall.gif", save_all=True, append_images=frames[1:], duration=100, loop=0)
我们详细解释一下这段代码:
frames[0].save(“snowfall.gif”, save_all=True, append_images=frames[1:], duration=100, loop=0):这一行代码的目的是保存动画。具体说明如下:
- import pygame
- import random
- from PIL import Image
- # 初始化Pygame
- pygame.init()
-
- # 设置窗口尺寸和标题
- window_width = 1280
- window_height = 800
- window = pygame.display.set_mode((window_width, window_height))
- pygame.display.set_caption("雪花飘落")
-
- # 定义雪花颜色为白色
- WHITE = (255, 255, 255)
-
- # 加载背景图片
- background_image= pygame.image.load("snow.jpg")
- # 创建雪花列表
- snowflakes = []
-
- # 创建雪花对象
- class Snowflake:
- def __init__(self, x, y, size):
- self.x = x
- self.y = y
- self.size = size
- self.speed = random.randint(1, 8)
-
- def fall(self):
- self.y += self.speed
- if self.y > window_height:
- self.y = random.randint(-50, -10)
- self.x = random.randint(0, window_width)
-
- def draw(self):
- pygame.draw.circle(window, WHITE, (self.x, self.y), self.size)
- # 创建GIF帧的列表
- frames = []
-
- # 主循环
- running = True
- while running:
- for event in pygame.event.get():
- if event.type == pygame.QUIT:
- running = False
-
- # 清空窗口
- # window.fill((0, 0, 0))
- # 绘制背景图片
- window.blit(background_image,(0,0))
-
- # 生成雪花
- # 控制生成雪花的数量
- if len(snowflakes) < 100:
- x = random.randint(0, window_width)
- y = random.randint(0, window_height)
- # 定义雪花的大小,1-5之间随机
- size = random.randint(1, 5)
- snowflake = Snowflake(x, y, size)
- snowflakes.append(snowflake)
-
- # 更新和绘制雪花
- for snowflake in snowflakes:
- snowflake.fall()
- snowflake.draw()
-
- # 刷新窗口
- pygame.display.flip()
-
- # 获取当前帧的截图并添加到帧列表
- pygame_image = pygame.surfarray.array3d(pygame.display.get_surface())
- pil_image = Image.fromarray(pygame_image)
- pil_image = pil_image.rotate(-90,expand=True)
- frames.append(pil_image.copy())
-
- # 控制帧率
- pygame.time.delay(10)
-
- # 退出时关闭Pygame
- pygame.quit()
-
- # 保存帧列表为GIF文件
-
- frames[0].save("snowfall.gif", save_all=True, append_images=frames[1:], duration=100, loop=0)