我們接下來談談圖像的變化。
想要給我們的程序加特技,那麼你的圖像還必須支持一定的變換,例如我們演示過的左右翻轉,還有按角度轉動、放大、縮小。
Pygame 有一個模塊是可以支持的,就是transform 模塊,下面列舉了該模塊幾個常用的方法:

我們來給大家講幾個,其實tranform 的這些方法事實上玩的都是像素的小把戲,事實上就是將像素進行相應的轉換,位置更改,大多數變換之後難免會有一些精度的遺失,只有flip () 方法不會,因此,我們不建議對變換後的Surface 對象進行再變換,因為這樣幾輪之後,圖像就會慘不忍睹了。
前面的代碼,我們使用flip() 方法使得小蛇撞牆之後翻轉,下面我們修改代碼,使得小蛇可以實現縮放,分別響應我們鍵盤上的等於號("=",放大),減號(“- ”,縮小),空格就恢復到原來大小。
-
import pygame
-
import sys
-
-
# 初始化Pygame
-
pygame.init()
-
-
size = width, height = 600, 400
-
speed = [-2, 1]
-
bg = (255, 255, 255) # RGB
-
-
fullscreen = False #设置一个决定全屏的变量
-
-
#实例化Pygame 的time 模块的 Clock 对象
-
clock = pygame.time.Clock()
-
-
# 创建指定大小的窗口 Surface
-
screen = pygame.display.set_mode(size, pygame.RESIZABLE)
-
# 设置窗口标题
-
pygame.display.set_caption("初次见面,请大家多多关照!")
-
-
#设置放大缩小的比例
-
ratio = 1.0
-
-
# 加载图片
-
oturtle = pygame.image.load("python.png") #保存原始图像
-
turtle = oturtle
-
-
# 获得图像的位置矩形
-
position = position_0 = oturtle.get_rect() #position_0记录起始位置
-
-
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:
-
if event.key == pygame.K_LEFT: #按下方向键左键
-
turtle = l_head #调头
-
speed = [-1, 0]
-
if event.key == pygame.K_RIGHT:
-
turtle = r_head #调头
-
speed = [1, 0]
-
if event.key == pygame.K_UP:
-
speed = [0, -1]
-
if event.key == pygame.K_DOWN:
-
speed = [0, 1]
-
-
#全屏(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
-
if position.right > width or position.bottom > height:#如果在边界外时恢复原始尺寸,就复位
-
position = turtle.get_rect()
-
-
-
#放大、缩小 小蛇(=、-),空格键恢复原始尺寸
-
if event.key == pygame.K_EQUALS or event.key == pygame.K_MINUS or event.key == pygame.K_SPACE:
-
#最大只能放大一倍,缩小50%
-
if event.key == pygame.K_EQUALS and ratio < 2:
-
ratio += 0.1
-
if event.key == pygame.K_MINUS and ratio > 0.5:
-
ratio -= 0.1
-
if event.key == pygame.K_SPACE:
-
ratio = 1.0
-
-
turtle = pygame.transform.smoothscale(oturtle, (int(position_0.width*ratio), int(position_0.height*ratio)))
-
-
-
#用户调整窗口尺寸
-
if event.type == pygame.VIDEORESIZE:
-
size = event.size
-
width, height = size
-
screen = pygame.display.set_mode(size, pygame.RESIZABLE)
-
if position.right > width or position.bottom > height:#如果缩小尺寸使得小蛇蛇出界了,就复位
-
position = turtle.get_rect()#获取当前大小的位置矩形
-
-
# 移动图像
-
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 sys
-
-
# 初始化Pygame
-
pygame.init()
-
-
size = width, height = 600, 400
-
speed = [-2, 1]
-
bg = (255, 255, 255) # RGB
-
-
fullscreen = False #设置一个决定全屏的变量
-
-
#实例化Pygame 的time 模块的 Clock 对象
-
clock = pygame.time.Clock()
-
-
# 创建指定大小的窗口 Surface
-
screen = pygame.display.set_mode(size, pygame.RESIZABLE)
-
# 设置窗口标题
-
pygame.display.set_caption("初次见面,请大家多多关照!")
-
-
#设置放大缩小的比例
-
ratio = 1.0
-
-
# 加载图片
-
oturtle = pygame.image.load("python.png") #保存原始图像
-
turtle = oturtle
-
-
# 获得图像的位置矩形
-
position = position_0 = oturtle.get_rect() #position_0记录起始位置
-
-
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:
-
if event.key == pygame.K_LEFT: #按下方向键左键
-
turtle = l_head #调头
-
speed = [-1, 0]
-
if event.key == pygame.K_RIGHT:
-
turtle = r_head #调头
-
speed = [1, 0]
-
if event.key == pygame.K_UP:
-
speed = [0, -1]
-
if event.key == pygame.K_DOWN:
-
speed = [0, 1]
-
-
#全屏(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
-
if position.right > width or position.bottom > height:#如果在边界外时恢复原始尺寸,就复位
-
position = turtle.get_rect()
-
-
-
#放大、缩小 小蛇(=、-),空格键恢复原始尺寸
-
if event.key == pygame.K_EQUALS or event.key == pygame.K_MINUS or event.key == pygame.K_SPACE:
-
#最大只能放大一倍,缩小50%
-
if event.key == pygame.K_EQUALS and ratio < 2:
-
ratio += 0.1
-
if event.key == pygame.K_MINUS and ratio > 0.5:
-
ratio -= 0.1
-
if event.key == pygame.K_SPACE:
-
ratio = 1.0
-
-
turtle = pygame.transform.smoothscale(oturtle, (int(position_0.width*ratio), int(position_0.height*ratio)))
-
-
#把当前 的 小蛇 赋值给 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 = event.size
-
width, height = size
-
screen = pygame.display.set_mode(size, pygame.RESIZABLE)
-
if position.right > width or position.bottom > height:#如果缩小尺寸使得小蛇蛇出界了,就复位
-
position = turtle.get_rect()#获取当前大小的位置矩形
-
-
# 移动图像
-
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 = 600, 400
-
speed = [-2, 1]
-
bg = (255, 255, 255) # RGB
-
-
fullscreen = False #设置一个决定全屏的变量
-
-
#实例化Pygame 的time 模块的 Clock 对象
-
clock = pygame.time.Clock()
-
-
# 创建指定大小的窗口 Surface
-
screen = pygame.display.set_mode(size, pygame.RESIZABLE)
-
# 设置窗口标题
-
pygame.display.set_caption("初次见面,请大家多多关照!")
-
-
#设置放大缩小的比例
-
ratio = 1.0
-
-
# 加载图片
-
oturtle = pygame.image.load("python.png") #保存原始图像
-
turtle = oturtle
-
-
# 获得图像的位置矩形
-
position = position_0 = oturtle.get_rect() #position_0记录起始位置
-
-
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:
-
if event.key == pygame.K_LEFT: #按下方向键左键
-
turtle = l_head #调头
-
speed = [-1, 0]
-
if event.key == pygame.K_RIGHT:
-
turtle = r_head #调头
-
speed = [1, 0]
-
if event.key == pygame.K_UP:
-
speed = [0, -1]
-
if event.key == pygame.K_DOWN:
-
speed = [0, 1]
-
-
#全屏(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
-
if position.right > width or position.bottom > height:#如果在边界外时恢复原始尺寸,就复位
-
position = turtle.get_rect()#获取当前大小的位置矩形并回到原点
-
-
-
#放大、缩小 小蛇(=、-),空格键恢复原始尺寸
-
if event.key == pygame.K_EQUALS or event.key == pygame.K_MINUS or event.key == pygame.K_SPACE:
-
#最大只能放大一倍,缩小50%
-
if event.key == pygame.K_EQUALS and ratio < 2:
-
ratio += 0.1
-
if event.key == pygame.K_MINUS and ratio > 0.5:
-
ratio -= 0.1
-
if event.key == pygame.K_SPACE:
-
ratio = 1.0
-
-
turtle = pygame.transform.smoothscale(oturtle, (int(position_0.width*ratio), int(position_0.height*ratio)))
-
-
# 相应的修改 小蛇的位置矩阵的宽度和高度
-
position.height = int(position_0.height*ratio)
-
position.width = int(position_0.width*ratio)
-
-
#把当前 的 小蛇 赋值给 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 = event.size
-
width, height = size
-
screen = pygame.display.set_mode(size, pygame.RESIZABLE)
-
if position.right > width or position.bottom > height:#如果缩小尺寸使得小蛇蛇出界了,就复位
-
position = turtle.get_rect()#获取当前大小的位置矩形并回到原点
-
-
# 移动图像
-
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("python.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的能力。加油^_^
0 留言:
發佈留言