在上一篇文章pygame的基础知识详解(主窗口创建、图像绘制、时钟对象和事件响应等知识点),请惠存(https://blog.csdn.net/dhjabc_1/article/details/116081725)
的基础上,继续深入研究如何让背景和人物动起来。
文章目录
一、背景运动
(一)让背景循环运动
使用代码:
import pygame
import sys
# 全局初始化
pygame.init()
# 设置窗口的分辨率和标题
resolution = width,height = 480,700 #设置窗口大小和标题
windowSurface = pygame.display.set_mode(resolution) #设置分辨率并得到全局的【绘图表面】
pygame.display.set_caption("风景如画")#设置标题
#加载背景图,返回的表面可以用于绘制其它对象于其上
bgSurface = pygame.image.load("temp.jpg").convert()
bgSurface1 = pygame.transform.flip(bgSurface, True, False)
frameRect = bgSurface.get_rect()
clock = pygame.time.Clock()
i = 0
while True:
# 将背景图像绘制于窗口表面windowSurface
for event in pygame.event.get():
# 处理退出事件
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
windowSurface.blit(bgSurface1, (-i, 0))
windowSurface.blit(bgSurface, (frameRect.width-i, 0))
i = (i+1) % frameRect.width
# frameRect.x += 1
# 绘制结束,刷新界面
pygame.display.flip()
# 时钟停留一帧的时长
clock.tick(60)
运行效果
二、人物运动
(一)预处理人物图片
1、一个大图片分散成多个小图片
原始图片:
处理过程:把上述图片打散成一个个小图片。
代码如下:
from PIL import Image
# 分割图片
def cut_image(image, count):
width, height = image.size
item_width = int(width / count)
item_height = height
box_list = []
# (left, upper, right, lower)
for i in range(count): # 只保存中间的5张(第0张、第6张舍去)
box = (i * item_width, 0, (i + 1) * item_width, item_height)
box_list.append(box)
image_list = [image.crop(box) for box in box_list]
return image_list
# 保存分割后的图片
def save_images(image_list, dir_name, file_name):
index = 1
for image in image_list:
image.save(dir_name + file_name + '_' + str(index) + '.png', 'PNG')
index += 1
if __name__ == '__main__':
image = Image.open(r'final.jpg') # 读取一张图片
image_list = cut_image(image, 9) # 分割图片
save_images(image_list, r'.\\out\\', r'out') # 保存分割后的图片
输出结果:
2、多个小图片合并成一个大图片
代码如下:
import os
import PIL.Image as Image
IMAGES_PATH = r'.\img\\' # 图片集地址
IMAGES_FORMAT = ['.jpg', '.png'] # 图片格式
IMAGE_SIZE = 256 # 每张小图片的大小
IMAGE_SAVE_PATH = r'final.jpg' # 图片转换后的地址
# 获取图片集地址下的所有图片名称
image_names = [name for name in os.listdir(IMAGES_PATH) for item in IMAGES_FORMAT if
os.path.splitext(name)[1] == item]
# 定义图像拼接函数
def image_compose():
to_image = Image.new('RGB', (len(image_names) * IMAGE_SIZE, IMAGE_SIZE)) # 创建一个新图
# 循环遍历,把每张图片按顺序粘贴到对应位置上
for i in range(len(image_names)):
from_image = Image.open(IMAGES_PATH + image_names[i]).resize(
(IMAGE_SIZE, IMAGE_SIZE), Image.ANTIALIAS)
print(from_image.size)
to_image.paste(from_image, (i * IMAGE_SIZE,0))
return to_image.save(IMAGE_SAVE_PATH) # 保存新图
if __name__ == '__main__':
image_compose() # 调用函数
(二)让人物在窗口动起来
1、使用大图显示运动效果
相关代码如下:
import sys, pygame
pygame.init() # 初始化pygame类
screen = pygame.display.set_mode((300, 400)) # 设置窗口大小
pygame.display.set_caption('运动的小人物') # 设置窗口标题
image = pygame.image.load('final.png') # 加载图片
tick = pygame.time.Clock()
frameNumber = 9 # 设置帧数,示例图片有6帧
frameRect = image.get_rect() # 获取全图的框体数据,以此计算单帧框体
frameRect.width //= frameNumber # 获取每一帧的边框数据
fps = 10 # 设置刷新率,数字越大刷新率越高
fcclock = pygame.time.Clock()
n = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
if n < frameNumber:
frameRect.x = frameRect.width * n
n += 1
else:
n = 0
screen.fill((255, 255, 255)) # 设置背景为白色
screen.blit(image, (50, 50), frameRect)
fcclock.tick(fps)
pygame.display.flip() # 刷新窗口
运行效果如下:
2、使用多个小图显示运动效果
运行代码:
import sys, pygame
pygame.init() # 初始化pygame类
screen = pygame.display.set_mode((300, 400)) # 设置窗口大小
pygame.display.set_caption('运动的小人物') # 设置窗口标题
tick = pygame.time.Clock()
fps = 10 # 设置刷新率,数字越大刷新率越高
fcclock = pygame.time.Clock()
dSurface1 = pygame.image.load("./out/out_1.png").convert_alpha()
dSurface2 = pygame.image.load("./out/out_2.png").convert_alpha()
dSurface3 = pygame.image.load("./out/out_3.png").convert_alpha()
dSurface4 = pygame.image.load("./out/out_4.png").convert_alpha()
dSurface5 = pygame.image.load("./out/out_5.png").convert_alpha()
dSurface6 = pygame.image.load("./out/out_6.png").convert_alpha()
dSurface7 = pygame.image.load("./out/out_7.png").convert_alpha()
dSurface8 = pygame.image.load("./out/out_8.png").convert_alpha()
dSurface9 = pygame.image.load("./out/out_9.png").convert_alpha()
dList = [dSurface1,dSurface2,dSurface3,dSurface4,dSurface5,dSurface6,dSurface7,dSurface8,dSurface9]
i = 0
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screen.fill((255, 255, 255)) # 设置背景为白色
screen.blit(dList[i%9], (50, 50))
fcclock.tick(fps)
i += 1
pygame.display.flip() # 刷新窗口
运行效果同上。
三、进一步动起来
(一)背景和人物都运动起来
代码如下:
import pygame
import sys
# 全局初始化
pygame.init()
# 设置窗口的分辨率和标题
resolution = width,height = 480,700 #设置窗口大小和标题
windowSurface = pygame.display.set_mode(resolution) #设置分辨率并得到全局的【绘图表面】
pygame.display.set_caption("风景如画")#设置标题
#加载背景图,返回的表面可以用于绘制其它对象于其上
bgSurface = pygame.image.load("temp.jpg").convert()
bgSurface1 = pygame.transform.flip(bgSurface, True, False)
dSurface1 = pygame.image.load("./out/out_1.png").convert_alpha()
dSurface2 = pygame.image.load("./out/out_2.png").convert_alpha()
dSurface3 = pygame.image.load("./out/out_3.png").convert_alpha()
dSurface4 = pygame.image.load("./out/out_4.png").convert_alpha()
dSurface5 = pygame.image.load("./out/out_5.png").convert_alpha()
dSurface6 = pygame.image.load("./out/out_6.png").convert_alpha()
dSurface7 = pygame.image.load("./out/out_7.png").convert_alpha()
dSurface8 = pygame.image.load("./out/out_8.png").convert_alpha()
dSurface9 = pygame.image.load("./out/out_9.png").convert_alpha()
dList = [dSurface1,dSurface2,dSurface3,dSurface4,dSurface5,dSurface6,dSurface7,dSurface8,dSurface9]
frameRect = bgSurface.get_rect()
clock = pygame.time.Clock()
i = 0
j = 0
k = 0
Surface = [bgSurface,bgSurface1]
while True:
# 将背景图像绘制于窗口表面windowSurface
for event in pygame.event.get():
# 处理退出事件
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
windowSurface.blit(Surface[j], (-i, 0))
windowSurface.blit(Surface[(j+1)%2], (frameRect.width-i, 0))
windowSurface.blit(dList[k%9], (50, 300))
k = k + 1
i = i+5
if i == frameRect.width:
j += 1
j = j%2
i = i % frameRect.width
# 绘制结束,刷新界面
pygame.display.flip()
# 时钟停留一帧的时长
clock.tick(15)
运行效果如下:
(二)人物真正动起来
代码如下:
import sys, pygame
pygame.init() # 初始化pygame类
screen = pygame.display.set_mode((600, 800)) # 设置窗口大小
pygame.display.set_caption('运动的小人物') # 设置窗口标题
tick = pygame.time.Clock()
fps = 10 # 设置刷新率,数字越大刷新率越高
fcclock = pygame.time.Clock()
dSurface1 = pygame.image.load("./out/out_1.png").convert_alpha()
dSurface2 = pygame.image.load("./out/out_2.png").convert_alpha()
dSurface3 = pygame.image.load("./out/out_3.png").convert_alpha()
dSurface4 = pygame.image.load("./out/out_4.png").convert_alpha()
dSurface5 = pygame.image.load("./out/out_5.png").convert_alpha()
dSurface6 = pygame.image.load("./out/out_6.png").convert_alpha()
dSurface7 = pygame.image.load("./out/out_7.png").convert_alpha()
dSurface8 = pygame.image.load("./out/out_8.png").convert_alpha()
dSurface9 = pygame.image.load("./out/out_9.png").convert_alpha()
dList = [dSurface1,dSurface2,dSurface3,dSurface4,dSurface5,dSurface6,dSurface7,dSurface8,dSurface9]
i = 0
SPEED = [5,5]
frameRect = dSurface1.get_rect() # 获取全图的框体数据,以此计算单帧框体
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
frameRect = frameRect.move(SPEED[0], SPEED[1])
screen.fill((255, 255, 255)) # 设置背景为白色
screen.blit(dList[i%9],frameRect)
fcclock.tick(fps)
i += 1
pygame.display.flip() # 刷新窗口
运行效果如下:
终于写完这篇关于运动的内容,写得非常匆忙,因此代码没有仔细排版和解释,希望对大家有帮忙,比心。
欢迎关注我,感谢支持!