第081讲: Pygame:提高游戏的颜值1 | 学习记录(小甲鱼零基础入门学习Python)

版权声明:转载请标明出处: https://blog.csdn.net/qq_38970783/article/details/89088555

毋庸置疑,在这个出门看脸的时代,高颜值的界面会给你的游戏带来更多的眼球。这两节课我们就来谈谈如何提高Pygame游戏的颜值。

我们一直通过 display 模块的 set_mode() 方法来指定界面的大小,这个方法会返回一个 Surface 对象,我们就使用这个 Surface 对象作为界面。今天我们就来仔细讲解 set_mode() 方法。

set_mode(resolution = (0, 0), flags = 0, depth = 0) -> Surface

这个方法有三个参数,

第一个参数 resolution 用于指定界面的大小。如果什么都不给的话,就是使用默认的(0, 0),Pygame 会根据当前的屏幕分辨率来创建一个窗口。大家要注意,这一功能只有在SDL版本高于或等于1.2.10时才会实现。如果是低于这个版本号,就会抛出异常。所以一般情况下,第一个参数还是给定较好。

注意:在使用这些参数的时候不用添加关键词,直接输入就好,添加关键词会出异常

第二个参数 flags 是指定扩展选项,同时指定多组选项可以使用 管道操作符 “|”, 这儿是 flags 参数提供的几个可选项:

第二个参数 flags 是指定扩展选项,同时指定多组选项可以使用 管道操作符 “|”, 这儿是 flags 参数提供的几个可选项:

选项

含义

pygame.FULLSCREEN 创建一个全屏显示
pygame.DOUBLEBUF 1. 双缓冲模式 
2. 推荐和 HWSURFACE 或 OPENGL 一起使用
pygame.HWSURFACE 硬件加速,只有在 FULLSCREEN 下可以使用
pygame.OPENGL 创建一个 OPENGL 渲染的显示
pygame.RESIZABLE 创建一个可调整尺寸的窗口
pygame.NOFRAME 创建一个没有边框和控制按钮的窗口

第三个参数 depth 用于指定颜色的位数,一般不推荐自己设置,Pygame 会根据当前的操作系统去取一个最合适的值。

大家可能会注意一个情况,我们玩的大多数游戏都是全屏模式,不是全屏还不给玩,你知道是为什么吗?

因为全屏的好处有太多了,你可以显示更多的内容,可以开启硬件加速,最重要的是你一个程序霸占了所有的屏幕,其他软件就不能玩了。

全屏模式在Pygame中非常简单,只需要将第二个参数设置为 FULLSCREEN 即可,同时,我们还可以加上硬件加速。

我们需要关联一个快捷键,让我们的全屏得到控制。

代码如下:(自己设置了 在使用方向键自己控制小猪后之后,可以按 esc 键回复自动运动)

import pygame
import sys
 
# 初始化Pygame
pygame.init()
 
size = width, height = 800, 600
speed = [-2, 1]
bg = (255, 255, 255) # RGB
 
#实例化Pygame 的time 模块的 Clock 对象
clock = pygame.time.Clock()
 
# 创建指定大小的窗口 Surface
screen = pygame.display.set_mode(size)
# 设置窗口标题
pygame.display.set_caption("初次见面,请大家多多关照!")
#设置全屏模式
fullscrean = False
# 加在图片
turtle = pygame.image.load(r"D:\Code\Python\3.png")
# 获得图像的位置矩形
position = turtle.get_rect()
#左转
turn_left = turtle
#右转
turn_right = pygame.transform.flip(turtle, True, False) #水平翻转,垂直不翻转
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        #如果事件类型是按下某个键
        if event.type == pygame.KEYDOWN:
            #如果按下的是左键
            if event.key == pygame.K_LEFT:
                #使小猪翻转
                turtle = turn_left
                speed = [-1,0]
            #如果按下的是右键
            if event.key == pygame.K_RIGHT:
                turtle = turn_right
                speed = [1,0]
            #如果按下的是上键
            if event.key == pygame.K_UP:
                speed = [0,-1]
            #如果按下的是下键
            if event.key == pygame.K_DOWN:
                speed = [0,1]
            #如果按下的是esc,退出人工控制模式
            if event.key == pygame.K_ESCAPE:
                speed = [-2, 1]
                # 移动图像
                position = position.move(speed)
                #触碰到边界
                if position.left < 0 or position.right > width:
                    # 翻转图像
                    turtle = pygame.transform.flip(turtle, True, False) #水平翻转,垂直不翻转
                    # 反方向移动
                    speed[0] = -speed[0]
            
                if position.top < 0 or position.bottom > height:
                    speed[1] = -speed[1]
            #如果按下的是F11键,那么全屏
            if event.key == pygame.K_F11 :
                fullscrean = not fullscrean
                size = pygame.display.list_modes()[1]
                screen = pygame.display.set_mode(size,pygame.FULLSCREEN | pygame.HWSURFACE)
                #点击两次F11后,回复原始界面大小
                if fullscrean == False :
                    size = width, height = 800, 600
                    screen = pygame.display.set_mode(size)
 
    # 移动图像
    position = position.move(speed)
    #触碰到边界
    if position.left < 0 or position.right > width:
        # 翻转图像
        turtle = pygame.transform.flip(turtle, True, False) #水平翻转,垂直不翻转
        # 反方向移动
        speed[0] = -speed[0]
 
    if position.top < 0 or position.bottom > height:
        speed[1] = -speed[1]
 
    # 填充背景
    screen.fill(bg)
    # 更新图像
    screen.blit(turtle, position)
    # 更新界面
    pygame.display.flip()
    # 延迟10毫秒
    #pygame.time.delay(10)
    #设置帧率
    clock.tick(200)

(其实,上面的程序在全屏时还存在一个小BUG,不知道大家发现了没有,小猪在原始尺寸的位置就调头了,大家可以动手修改一下,很简单的。)(修改的代码如下:)

import pygame
import sys
 
# 初始化Pygame
pygame.init()
 
size = width, height = 800, 600
speed = [-2, 1]
bg = (255, 255, 255) # RGB
 
#实例化Pygame 的time 模块的 Clock 对象
clock = pygame.time.Clock()
 
# 创建指定大小的窗口 Surface
screen = pygame.display.set_mode(size)
# 设置窗口标题
pygame.display.set_caption("初次见面,请大家多多关照!")
#设置全屏模式
fullscrean = False
# 加在图片
turtle = pygame.image.load(r"D:\Code\Python\3.png")
# 获得图像的位置矩形
position = turtle.get_rect()
#左转
turn_left = turtle
#右转
turn_right = pygame.transform.flip(turtle, True, False) #水平翻转,垂直不翻转
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        #如果事件类型是按下某个键
        if event.type == pygame.KEYDOWN:
            #如果按下的是左键
            if event.key == pygame.K_LEFT:
                #使小猪翻转
                turtle = turn_left
                speed = [-1,0]
            #如果按下的是右键
            if event.key == pygame.K_RIGHT:
                turtle = turn_right
                speed = [1,0]
            #如果按下的是上键
            if event.key == pygame.K_UP:
                speed = [0,-1]
            #如果按下的是下键
            if event.key == pygame.K_DOWN:
                speed = [0,1]
            #如果按下的是esc,退出人工控制模式
            if event.key == pygame.K_ESCAPE:
                speed = [-2, 1]
                # 移动图像
                position = position.move(speed)
                #触碰到边界
                if position.left < 0 or position.right > width:
                    # 翻转图像
                    turtle = pygame.transform.flip(turtle, True, False) #水平翻转,垂直不翻转
                    # 反方向移动
                    speed[0] = -speed[0]
            
                if position.top < 0 or position.bottom > height:
                    speed[1] = -speed[1]
            #如果按下的是F11键,那么全屏
            if event.key == pygame.K_F11 :
                fullscrean = not fullscrean
                size = width, height = pygame.display.list_modes()[1]
                screen = pygame.display.set_mode(size,pygame.FULLSCREEN | pygame.HWSURFACE)

                #点击两次F11后,回复原始界面大小
                if fullscrean == False :
                    size = width, height = 800, 600
                    screen = pygame.display.set_mode(size)
 
    # 移动图像
    position = position.move(speed)
    #触碰到边界
    if position.left < 0 or position.right > width:
        # 翻转图像
        turtle = pygame.transform.flip(turtle, True, False) #水平翻转,垂直不翻转
        # 反方向移动
        speed[0] = -speed[0]
 
    if position.top < 0 or position.bottom > height:
        speed[1] = -speed[1]
 
    # 填充背景
    screen.fill(bg)
    # 更新图像
    screen.blit(turtle, position)
    # 更新界面
    pygame.display.flip()
    # 延迟10毫秒
    #pygame.time.delay(10)
    #设置帧率
    clock.tick(200)

接下来我们又发现了一个 BUG,就是如果在全屏模式下,小猪跑出了原始尺寸的边界的时候恢复原始尺寸,小猪就不见了,在这种情况下,我们应该复位:

import pygame
import copy
import sys
 
# 初始化Pygame
pygame.init()
 
size = width, height = 800, 600
speed = [-2, 1]
bg = (255, 255, 255) # RGB
 
#实例化Pygame 的time 模块的 Clock 对象
clock = pygame.time.Clock()
 
# 创建指定大小的窗口 Surface
screen = pygame.display.set_mode(size)
# 设置窗口标题
pygame.display.set_caption("初次见面,请大家多多关照!")
#设置全屏模式
fullscrean = False
# 加在图片
turtle = pygame.image.load(r"D:\Code\Python\3.png")
# 获得图像的位置矩形
position0 = turtle.get_rect()
position = copy.deepcopy(position0)
#左转
turn_left = turtle
#右转
turn_right = pygame.transform.flip(turtle, True, False) #水平翻转,垂直不翻转
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        #如果事件类型是按下某个键
        if event.type == pygame.KEYDOWN:
            #如果按下的是左键
            if event.key == pygame.K_LEFT:
                #使小猪翻转
                turtle = turn_left
                speed = [-1,0]
            #如果按下的是右键
            if event.key == pygame.K_RIGHT:
                turtle = turn_right
                speed = [1,0]
            #如果按下的是上键
            if event.key == pygame.K_UP:
                speed = [0,-1]
            #如果按下的是下键
            if event.key == pygame.K_DOWN:
                speed = [0,1]
            #如果按下的是esc,退出人工控制模式
            if event.key == pygame.K_ESCAPE:
                speed = [-2, 1]
                # 移动图像
                position = position.move(speed)
                #触碰到边界
                if position.left < 0 or position.right > width:
                    # 翻转图像
                    turtle = pygame.transform.flip(turtle, True, False) #水平翻转,垂直不翻转
                    # 反方向移动
                    speed[0] = -speed[0]
            
                if position.top < 0 or position.bottom > height:
                    speed[1] = -speed[1]
            #如果按下的是F11键,那么全屏
            if event.key == pygame.K_F11 :
                fullscrean = not fullscrean
                size = width, height = pygame.display.list_modes()[1]
                screen = pygame.display.set_mode(size,pygame.FULLSCREEN | pygame.HWSURFACE)
                #点击两次F11后,回复原始界面大小
                if fullscrean == False :
                    size = width, height = 800, 600
                    screen = pygame.display.set_mode(size)
                    #获取图像位置
                    position = turtle.get_rect()
                    #如果恢复原始屏幕大小的时候超出界面,那么复位
                    if position.right > width or position.bottom > height :
                        position  = position0

 
    # 移动图像
    position = position.move(speed)
    #触碰到边界
    if position.left < 0 or position.right > width:
        # 翻转图像
        turtle = pygame.transform.flip(turtle, True, False) #水平翻转,垂直不翻转
        # 反方向移动
        speed[0] = -speed[0]
 
    if position.top < 0 or position.bottom > height:
        speed[1] = -speed[1]
 
    # 填充背景
    screen.fill(bg)
    # 更新图像
    screen.blit(turtle, position)
    # 更新界面
    pygame.display.flip()
    # 延迟10毫秒
    #pygame.time.delay(10)
    #设置帧率
    clock.tick(200)

当我们运行程序时按下 F11,就会全屏显示,这里的全屏尺寸 (1920,1080)是我知道自己电脑的尺寸设置的。但是你的游戏是开发给大家用的,这样子你就不知道用户的显示器的尺寸了,那怎么办呢?

事实上有一种方法可以获得,Pygame 我们可以使用 display 模块里的 list_modes() 方法。

pygame.display.set_modes()

我们打开 IDLE 尝试一下:

它会打印当前显示器支持的所有分辨率尺寸。list_modes() 是返回一个列表,从大到小依次列举当前显示器支持的分辨率,所以全屏的话,就是将这个列表获取之后,取第一个元素作为 set_mode() 的尺寸即可。

>>>import pyagme
pygame 1.9.4
Hello from the pygame community. https://www.pygame.org/contribute.html
>>>pygame.init()
(6,0)
>>>pygame.display.list_modes()
[(1920, 1080), (1680, 1050), (1440, 900), (1280, 1024), (1280, 960), (1280, 720), (1024, 768), (800, 600)]

我们接下来谈谈使得窗口可变。默认情况下窗口是不可以通过拖拽来改变窗口大小的。

你想一下,游戏里面的任务都是提前设定好尺寸的,被你一拖拽,马上面目全非了。

尽管如此,Pygame 还是提供了支持改变窗口尺寸的选项。就是设置 RESIZABLE 选项来实现。

如果用户调整窗口尺寸时,会引发一个事件,叫做 VIDEORESIZE

如果只是在 set_mode() 中添加参数 pygame.RESIZABLE ,如下:

screen = pygame.display.set_mode(size, pygame.RESIZABLE)

在这里插入图片描述
显然是没有任何作用的,我们需要关注 VIDEORESIZE 事件,并执行相应操作,如下:

import pygame
import copy
import sys
 
# 初始化Pygame
pygame.init()
 
size = width, height = 800, 600
speed = [-2, 1]
bg = (255, 255, 255) # RGB
 
#实例化Pygame 的time 模块的 Clock 对象
clock = pygame.time.Clock()
 
# 创建指定大小的窗口 Surface
screen = pygame.display.set_mode(size,pygame.RESIZABLE)
# 设置窗口标题
pygame.display.set_caption("初次见面,请大家多多关照!")
#设置全屏模式
fullscrean = False
# 加在图片
turtle = pygame.image.load(r"D:\Code\Python\3.png")
# 获得图像的位置矩形
position0 = turtle.get_rect()
position = copy.deepcopy(position0)
#左转
turn_left = turtle
#右转
turn_right = pygame.transform.flip(turtle, True, False) #水平翻转,垂直不翻转
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        #如果事件类型是按下某个键
        if event.type == pygame.KEYDOWN:
            #如果按下的是左键
            if event.key == pygame.K_LEFT:
                #使小猪翻转
                turtle = turn_left
                speed = [-1,0]
            #如果按下的是右键
            if event.key == pygame.K_RIGHT:
                turtle = turn_right
                speed = [1,0]
            #如果按下的是上键
            if event.key == pygame.K_UP:
                speed = [0,-1]
            #如果按下的是下键
            if event.key == pygame.K_DOWN:
                speed = [0,1]
            #如果按下的是esc,退出人工控制模式
            if event.key == pygame.K_ESCAPE:
                speed = [-2, 1]
                # 移动图像
                position = position.move(speed)
                #触碰到边界
                if position.left < 0 or position.right > width:
                    # 翻转图像
                    turtle = pygame.transform.flip(turtle, True, False) #水平翻转,垂直不翻转
                    # 反方向移动
                    speed[0] = -speed[0]
            
                if position.top < 0 or position.bottom > height:
                    speed[1] = -speed[1]
            #如果按下的是F11键,那么全屏
            if event.key == pygame.K_F11 :
                fullscrean = not fullscrean
                size = width, height = pygame.display.list_modes()[1]
                screen = pygame.display.set_mode(size,pygame.FULLSCREEN | pygame.HWSURFACE)
                #点击两次F11后,回复原始界面大小
                if fullscrean == False :
                    size = width, height = 800, 600
                    screen = pygame.display.set_mode(size)
                    #获取图像位置
                    position = turtle.get_rect()
                    #如果恢复原始屏幕大小的时候超出界面,那么复位
                    if position.right > width or position.bottom > height :
                        position  = position0
        #如果事件类型中出现了调节窗口大小的事件
        if event.type == pygame.VIDEORESIZE:
            #这个事件有SIZE,W,H这三个参数,可以调用
            size = width,height =  event.size
            screen = pygame.display.set_mode(size,pygame.RESIZABLE)

 
    # 移动图像
    position = position.move(speed)
    #触碰到边界
    if position.left < 0 or position.right > width:
        # 翻转图像
        turtle = pygame.transform.flip(turtle, True, False) #水平翻转,垂直不翻转
        # 反方向移动
        speed[0] = -speed[0]
 
    if position.top < 0 or position.bottom > height:
        speed[1] = -speed[1]
 
    # 填充背景
    screen.fill(bg)
    # 更新图像
    screen.blit(turtle, position)
    # 更新界面
    pygame.display.flip()
    # 延迟10毫秒
    #pygame.time.delay(10)
    #设置帧率
    clock.tick(200)

我们接下来谈谈图像的变化

想要给我们的程序加特技,那么你的图像还必须支持一定的变换,例如我们演示过的左右翻转,还有按角度转动、放大、缩小。

Pygame 有一个模块是可以支持的,就是 transform 模块,下面列举了该模块几个常用的方法:
在这里插入图片描述
我们来给大家讲几个,其实 tranform 的这些方法事实上玩的都是像素的小把戏,事实上就是将像素进行相应的转换,位置更改,大多数变换之后难免会有一些精度的遗失,只有flip() 方法不会,因此,我们不建议对变换后的 Surface 对象进行再变换,因为这样几轮之后,图像就会惨不忍睹了。

前面的代码,我们使用 flip() 方法使得小猪撞墙之后翻转,下面我们修改代码,使得小猪可以实现缩放,分别响应我们键盘上的 等于号("=",放大),减号(“-”,缩小),空格 就恢复到原来大小。

import pygame
import copy
import sys
 
# 初始化Pygame
pygame.init()
 
size = width, height = 800, 600
speed = [-2, 1]
bg = (255, 255, 255) # RGB
 
#实例化Pygame 的time 模块的 Clock 对象
clock = pygame.time.Clock()
#设置放大倍数,初始为1.0
multiple = 1.0
# 创建指定大小的窗口 Surface
screen = pygame.display.set_mode(size,pygame.RESIZABLE)
# 设置窗口标题
pygame.display.set_caption("初次见面,请大家多多关照!")
#设置全屏模式
fullscrean = False
# 加载图片
turtle0 = pygame.image.load(r"D:\Code\Python\3.png")
turtle = turtle0
turtle0_rect = turtle0.get_rect()
position = turtle_rect = turtle0_rect
# 获得图像的位置矩形
position0 = turtle.get_rect()
position = copy.deepcopy(position0)
#左转
turn_left = turtle
#右转
turn_right = pygame.transform.flip(turtle, True, False) #水平翻转,垂直不翻转
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        #如果事件类型是按下某个键
        if event.type == pygame.KEYDOWN:
            #如果按下的是左键
            if event.key == pygame.K_LEFT:
                #使小猪翻转
                turtle = turn_left
                speed = [-1,0]
            #如果按下的是右键
            if event.key == pygame.K_RIGHT:
                turtle = turn_right
                speed = [1,0]
            #如果按下的是上键
            if event.key == pygame.K_UP:
                speed = [0,-1]
            #如果按下的是下键
            if event.key == pygame.K_DOWN:
                speed = [0,1]
            #如果按下的是esc,退出人工控制模式
            if event.key == pygame.K_ESCAPE:
                speed = [-2, 1]
                # 移动图像
                position = position.move(speed)
                #触碰到边界
                if position.left < 0 or position.right > width:
                    # 翻转图像
                    turtle = pygame.transform.flip(turtle, True, False) #水平翻转,垂直不翻转
                    # 反方向移动
                    speed[0] = -speed[0]
                if position.top < 0 or position.bottom > height:
                    speed[1] = -speed[1]
                
            #如果按下的是F11键,那么全屏
            if event.key == pygame.K_F11 :
                fullscrean = not fullscrean
                size = width, height = pygame.display.list_modes()[1]
                screen = pygame.display.set_mode(size,pygame.FULLSCREEN | pygame.HWSURFACE)
                #点击两次F11后,回复原始界面大小
                if fullscrean == False :
                    size = width, height = 800, 600
                    screen = pygame.display.set_mode(size)
                    #获取图像位置
                    position = turtle.get_rect()
                    #如果恢复原始屏幕大小的时候超出界面,那么复位
                    if position.right > width or position.bottom > height :
                        position  = position0

                    # 放大、缩小小乌龟(=\-),空格键恢复原始尺寸
            if event.key == pygame.K_EQUALS or event.key == pygame.K_MINUS or event.key == pygame.K_SPACE:
                #如果按下的是=键,方法
                if event.key == pygame.K_EQUALS and multiple < 2:
                    multiple += 0.1
                #如果按下的是-键,缩小
                if event.key == pygame.K_MINUS and multiple > 0.5:
                    multiple -= 0.1
                #如果按下的是空格键,恢复原状
                if event.key == pygame.K_SPACE:
                    multiple = 1.0
                turtle = pygame.transform.smoothscale(turtle0, \
                                             (int(turtle0_rect.width * multiple), \
                                             int(turtle0_rect.height * multiple)))
                # 相应修改龟头两个朝向的 Surface 对象,否则一单击移动就打回原形 
                l_head = turtle
                r_head = pygame.transform.flip(turtle, True, False)
                # 获得小乌龟缩放后的新尺寸
                turtle_rect = turtle.get_rect()
            position.width, position.height = turtle_rect.width, turtle_rect.height
            
        #如果事件类型中出现了调节窗口大小的事件
        if event.type == pygame.VIDEORESIZE:
            #这个事件有SIZE,W,H这三个参数,可以调用
            size = width,height =  event.size
            screen = pygame.display.set_mode(size,pygame.RESIZABLE)

 
    # 移动图像
    position = position.move(speed)
    #触碰到边界
    if position.left < 0 or position.right > width:
        # 翻转图像
        turtle = pygame.transform.flip(turtle, True, False) #水平翻转,垂直不翻转
        # 反方向移动
        speed[0] = -speed[0]
 
    if position.top < 0 or position.bottom > height:
        speed[1] = -speed[1]
 
    # 填充背景
    screen.fill(bg)
    # 更新图像
    screen.blit(turtle, position)
    # 更新界面
    pygame.display.flip()
    # 延迟10毫秒
    #pygame.time.delay(10)
    #设置帧率
    clock.tick(200)

这里还是有问题的,第一个Bug就是当我们按下方向键的时候,它就会恢复原形,这是因为我们按下方向键时,调用的 r_head 和 l_head 是原形小蛇赋值的,所以,我们还需要将缩放后的小蛇赋值给 r_head 和 l_head ,在这之前,我们需要判断一下小蛇的运动方向,确定把当前 的 小蛇 赋值给 r_head 还是 l_head 。修改如下:

import pygame
import copy
import sys
 
# 初始化Pygame
pygame.init()
 
size = width, height = 800, 600
speed = [-2, 1]
bg = (255, 255, 255) # RGB
 
#实例化Pygame 的time 模块的 Clock 对象
clock = pygame.time.Clock()
#设置放大倍数,初始为1.0
multiple = 1.0
# 创建指定大小的窗口 Surface
screen = pygame.display.set_mode(size,pygame.RESIZABLE)
# 设置窗口标题
pygame.display.set_caption("初次见面,请大家多多关照!")
#设置全屏模式
fullscrean = False
# 加载图片
turtle0 = pygame.image.load(r"D:\Code\Python\3.png")
turtle = turtle0
turtle0_rect = turtle0.get_rect()
position = turtle_rect = turtle0_rect
# 获得图像的位置矩形
position0 = turtle.get_rect()
position = copy.deepcopy(position0)
#左转
turn_left = turtle
#右转
turn_right = pygame.transform.flip(turtle, True, False) #水平翻转,垂直不翻转
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        #如果事件类型是按下某个键
        if event.type == pygame.KEYDOWN:
            #如果按下的是左键
            if event.key == pygame.K_LEFT:
                #使小猪翻转
                turtle = turn_left
                speed = [-1,0]
            #如果按下的是右键
            if event.key == pygame.K_RIGHT:
                turtle = turn_right
                speed = [1,0]
            #如果按下的是上键
            if event.key == pygame.K_UP:
                speed = [0,-1]
            #如果按下的是下键
            if event.key == pygame.K_DOWN:
                speed = [0,1]
            #如果按下的是esc,退出人工控制模式
            if event.key == pygame.K_ESCAPE:
                speed = [-2, 1]
                # 移动图像
                position = position.move(speed)
                #触碰到边界
                if position.left < 0 or position.right > width:
                    # 翻转图像
                    turtle = pygame.transform.flip(turtle, True, False) #水平翻转,垂直不翻转
                    # 反方向移动
                    speed[0] = -speed[0]
                if position.top < 0 or position.bottom > height:
                    speed[1] = -speed[1]
                
            #如果按下的是F11键,那么全屏
            if event.key == pygame.K_F11 :
                fullscrean = not fullscrean
                size = width, height = pygame.display.list_modes()[1]
                screen = pygame.display.set_mode(size,pygame.FULLSCREEN | pygame.HWSURFACE)
                #点击两次F11后,回复原始界面大小
                if fullscrean == False :
                    size = width, height = 800, 600
                    screen = pygame.display.set_mode(size)
                    #获取图像位置
                    position = turtle.get_rect()
                    #如果恢复原始屏幕大小的时候超出界面,那么复位
                    if position.right > width or position.bottom > height :
                        position  = position0

                    # 放大、缩小小乌龟(=\-),空格键恢复原始尺寸
            if event.key == pygame.K_EQUALS or event.key == pygame.K_MINUS or event.key == pygame.K_SPACE:
                #如果按下的是=键,方法
                if event.key == pygame.K_EQUALS and multiple < 2:
                    multiple += 0.1
                #如果按下的是-键,缩小
                if event.key == pygame.K_MINUS and multiple > 0.5:
                    multiple -= 0.1
                #如果按下的是空格键,恢复原状
                if event.key == pygame.K_SPACE:
                    multiple = 1.0
                turtle = pygame.transform.smoothscale(turtle0, \
                                             (int(turtle0_rect.width * multiple), \
                                             int(turtle0_rect.height * multiple)))
                turn_left = turtle
                turn_right = pygame.transform.flip(turtle, True, False)
                # 获得小猪缩放后的新尺寸
                turtle_rect = turtle.get_rect()
            position.width, position.height = turtle_rect.width, turtle_rect.height
            
        #如果事件类型中出现了调节窗口大小的事件
        if event.type == pygame.VIDEORESIZE:
            #这个事件有SIZE,W,H这三个参数,可以调用
            size = width,height =  event.size
            screen = pygame.display.set_mode(size,pygame.RESIZABLE)

 
    # 移动图像
    position = position.move(speed)
    #触碰到边界
    if position.left < 0 or position.right > width:
        # 翻转图像
        turtle = pygame.transform.flip(turtle, True, False) #水平翻转,垂直不翻转
        # 反方向移动
        speed[0] = -speed[0]
 
    if position.top < 0 or position.bottom > height:
        speed[1] = -speed[1]
 
    # 填充背景
    screen.fill(bg)
    # 更新图像
    screen.blit(turtle, position)
    # 更新界面
    pygame.display.flip()
    # 延迟10毫秒
    #pygame.time.delay(10)
    #设置帧率
    clock.tick(200)

这样,即使在缩放的过程中按下方向键,也可以正常保持现有尺寸调头。

第二个Bug就是缩放后的小猪无法找到正确的边界。这是因为小蛇在缩放后,程序使用的位置矩阵还是原始大小的位置矩阵,我们该如何相应的改变位置矩阵呢?

解决方案就是: 相应的修改 小猪的位置矩阵的宽度和高度

import pygame
import copy
import sys
 
# 初始化Pygame
pygame.init()
 
size = width, height = 800, 600
speed = [-2, 1]
bg = (255, 255, 255) # RGB
 
#实例化Pygame 的time 模块的 Clock 对象
clock = pygame.time.Clock()
#设置放大倍数,初始为1.0
multiple = 1.0
# 创建指定大小的窗口 Surface
screen = pygame.display.set_mode(size,pygame.RESIZABLE)
# 设置窗口标题
pygame.display.set_caption("初次见面,请大家多多关照!")
#设置全屏模式
fullscrean = False
# 加载图片
turtle0 = pygame.image.load(r"D:\Code\Python\3.png")
turtle = turtle0
turtle0_rect = turtle0.get_rect()
position = turtle_rect = turtle0_rect
# 获得图像的位置矩形
position0 = turtle.get_rect()
position = copy.deepcopy(position0)
#左转
turn_left = turtle
#右转
turn_right = pygame.transform.flip(turtle, True, False) #水平翻转,垂直不翻转
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        #如果事件类型是按下某个键
        if event.type == pygame.KEYDOWN:
            #如果按下的是左键
            if event.key == pygame.K_LEFT:
                #使小猪翻转
                turtle = turn_left
                speed = [-1,0]
            #如果按下的是右键
            if event.key == pygame.K_RIGHT:
                turtle = turn_right
                speed = [1,0]
            #如果按下的是上键
            if event.key == pygame.K_UP:
                speed = [0,-1]
            #如果按下的是下键
            if event.key == pygame.K_DOWN:
                speed = [0,1]
            #如果按下的是esc,退出人工控制模式
            if event.key == pygame.K_ESCAPE:
                speed = [-2, 1]
                # 移动图像
                position = position.move(speed)
                #触碰到边界
                if position.left < 0 or position.right > width:
                    # 翻转图像
                    turtle = pygame.transform.flip(turtle, True, False) #水平翻转,垂直不翻转
                    # 反方向移动
                    speed[0] = -speed[0]
                if position.top < 0 or position.bottom > height:
                    speed[1] = -speed[1]
                
            #如果按下的是F11键,那么全屏
            if event.key == pygame.K_F11 :
                fullscrean = not fullscrean
                size = width, height = pygame.display.list_modes()[1]
                screen = pygame.display.set_mode(size,pygame.FULLSCREEN | pygame.HWSURFACE)
                #点击两次F11后,回复原始界面大小
                if fullscrean == False :
                    size = width, height = 800, 600
                    screen = pygame.display.set_mode(size)
                    #获取图像位置
                    position = turtle.get_rect()
                    #如果恢复原始屏幕大小的时候超出界面,那么复位
                    if position.right > width or position.bottom > height :
                        position  = position0

                    # 放大、缩小小乌龟(=\-),空格键恢复原始尺寸
            if event.key == pygame.K_EQUALS or event.key == pygame.K_MINUS or event.key == pygame.K_SPACE:
                #如果按下的是=键,方法
                if event.key == pygame.K_EQUALS and multiple < 2:
                    multiple += 0.1
                #如果按下的是-键,缩小
                if event.key == pygame.K_MINUS and multiple > 0.5:
                    multiple -= 0.1
                #如果按下的是空格键,恢复原状
                if event.key == pygame.K_SPACE:
                    multiple = 1.0
                turtle = pygame.transform.smoothscale(turtle0, \
                                             (int(turtle0_rect.width * multiple), \
                                             int(turtle0_rect.height * multiple)))
                # 相应修改龟头两个朝向的 Surface 对象,否则一单击移动就打回原形 
                turn_left = turtle
                turn_right = pygame.transform.flip(turtle, True, False)
                # 获得小猪缩放后的新尺寸
                turtle_rect = turtle.get_rect()
                position.width, position.height = turtle_rect.width, turtle_rect.height
 
                #把当前 的 小猪 赋值给  r_head 或者 l_head 
                if speed[0] < 0:#如果向左走
                    l_head = turtle
                    r_head = pygame.transform.flip(turtle, True, False)                    
                else:#如果向右走
                    r_head = turtle
                    l_head = pygame.transform.flip(turtle, True, False)
            
        #如果事件类型中出现了调节窗口大小的事件
        if event.type == pygame.VIDEORESIZE:
            #这个事件有SIZE,W,H这三个参数,可以调用
            size = width,height =  event.size
            screen = pygame.display.set_mode(size,pygame.RESIZABLE)

 
    # 移动图像
    position = position.move(speed)
    #触碰到边界
    if position.left < 0 or position.right > width:
        # 翻转图像
        turtle = pygame.transform.flip(turtle, True, False) #水平翻转,垂直不翻转
        # 反方向移动
        speed[0] = -speed[0]
 
    if position.top < 0 or position.bottom > height:
        speed[1] = -speed[1]
 
    # 填充背景
    screen.fill(bg)
    # 更新图像
    screen.blit(turtle, position)
    # 更新界面
    pygame.display.flip()
    # 延迟10毫秒
    #pygame.time.delay(10)
    #设置帧率
    clock.tick(200)

接下来讲一个新知识,我们希望通过 rotate() 来旋转图像,让小蛇蛇贴边爬行,头要一直向前。

import pygame
import sys
 
# 初始化Pygame
pygame.init()
 
size = width, height = 600, 400
bg = (255, 255, 255) # RGB
 
fullscreen = False
 
# 创建指定大小的窗口 Surface
screen = pygame.display.set_mode(size)
# 设置窗口标题
pygame.display.set_caption("初次见面,请大家多多关照!")
 
# 加载图片
turtle = pygame.image.load(r"D:\Code\Python\3.png")
# 获得图像的位置矩形
position = turtle.get_rect()
 
speed = [5, 0]
turtle_right = pygame.transform.rotate(turtle, 90)
turtle_top = pygame.transform.rotate(turtle, 180)
turtle_left = pygame.transform.rotate(turtle, 270)
turtle_bottom = turtle
turtle = turtle_top #初始从上边开始
 
l_head = turtle
r_head = pygame.transform.flip(turtle, True, False)
 
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
 
        if event.type == pygame.KEYDOWN:
            # 全屏(F11)
            if event.key == pygame.K_F11:
                fullscreen = not fullscreen
                if fullscreen:
                    screen = pygame.display.set_mode((1920, 1080), pygame.FULLSCREEN | pygame.HWSURFACE)
                    width , height = 1920, 1080
                else:
                    screen = pygame.display.set_mode((600, 400))
                    width, height = 600, 400
 
    # 移动图像
    position = position.move(speed)
 
    if position.right > width:
        turtle = turtle_right
        position = turtle_rect = turtle.get_rect()
        position.left = width - turtle_rect.width
        speed = [0, 5]
 
    if position.bottom > height:
        turtle = turtle_bottom
        position = turtle_rect = turtle.get_rect()
        position.left = width - turtle_rect.width
        position.top = height - turtle_rect.height
        speed = [-5, 0]
 
    if position.left < 0:
        turtle = turtle_left
        position = turtle_rect = turtle.get_rect()
        position.top = height - turtle_rect.height
        speed = [0, -5]
 
    if position.top < 0:
        turtle = turtle_top
        position = turtle_rect = turtle.get_rect()
        speed = [5, 0]
 
    # 填充背景
    screen.fill(bg)
    # 更新图像
    screen.blit(turtle, position)
    # 更新界面
    pygame.display.flip()
    # 延迟10毫秒
    pygame.time.delay(10)

这节课内容比较多,大家好好消化。主要是锻炼大家消除Bug的能力。加油_

猜你喜欢

转载自blog.csdn.net/qq_38970783/article/details/89088555