pygame使用多种方法让背景和人物运动起来

在上一篇文章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()  # 刷新窗口

运行效果如下:
在这里插入图片描述

终于写完这篇关于运动的内容,写得非常匆忙,因此代码没有仔细排版和解释,希望对大家有帮忙,比心。

欢迎关注我,感谢支持!

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值