毋庸置疑,在这个出门看脸的时代,高颜值的界面会给你的游戏带来更多的眼球。这两节课我们就来谈谈如何提高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的能力。加油_