pygame游戏使用不分割大图像做背景的方法
Posted geng_zhaoying
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了pygame游戏使用不分割大图像做背景的方法相关的知识,希望对你有一定的参考价值。
一些2维游戏,角色不动,背景连续移动。例如驾驶汽车2维游戏,汽车固定在某位置,只能沿x轴左右移动避开障碍物,道路沿y轴汽车行进相反方向连续移动,感觉汽车在前进。这里道路实际上是背景。传统方法把做背景的道路图像分割为2部分,称为道路1和道路2,1前1后移进游戏窗体,然后顺序移出游戏窗体,当道路1移出游戏窗体,道路2还在游戏窗体中,道路1将被放到道路2后边,当道路2移出游戏窗体,道路1还在游戏窗体中,道路2将被放到道路1后边,依此无限循环使用道路1和道路2,实现背景连续移动。
这里介绍的方法不分割图像做背景来完成背景连续移动。先看pygame.surface.blit方法,其将一个图像(Surface实例)绘制到另一个图像(Surface实例)上。如screen是一个Surface实例,方法blit具体使用方法如下:
rect=screen.blit(source,dest,area=None,special_flags=0)
如screen是游戏窗口,source是一个很宽的背景图像,area是一个Rect对象,表示从背景图像(source)的area区域取出图像绘制到游戏窗口上。见下面代码,将背景一部分显示到游戏窗口。不能运行,只是说明问题。
size = width, height = 400,300 #指定游戏窗口宽和高
screen=pygame.display.set_mode(size)#创建指定宽和高游戏窗口(Surface实例)
bg_img = pygame.image.load("长背景.png").convert() #背景图像高=height
rect = pygame.Rect(x,y,width,height) #可修改(x,y),从bg_img不同位置取图像
screen.blit(bg_img,(0,0),rect)
注意rect的宽和高和游戏窗口宽和高相同,blit()方法将从长背景图像(bg_img)从坐标(x,y)处取出和游戏窗口宽和高相同的部分背景在游戏窗口坐标(0,0)处显示作为背景。修改rect的x,y值,可从背景不同位置取出不同部分背景图像。如每帧自动增加rect的x值,y值不变,将看到背景自动沿x轴移动,同理也可使背景自动沿y轴移动。
下边是完整背景自动移动程序。拷贝源程序后,从网上找一个背景图像,景物沿x轴排列(如下边两个图像),其宽要大于2倍游戏窗口宽,保险取3倍,高等于游戏窗口高,修改名称为(“长背景.png”,保存到该源程序所在文件夹中,即可运行。很容易改为沿y轴移动。
import pygame
pygame.init()
size = width, height = 400,300 #创建游戏窗口大小
screen = pygame.display.set_mode(size)
pygame.display.set_caption("pygame游戏使用无分割大背景") #设置窗口标题
bg_img = pygame.image.load("长背景1.png").convert() #背景图像
bg_width=bg_img.get_rect().width
p=pygame.image.load("b.png").convert_alpha()
fclock = pygame.time.Clock() #创建控制频率的clock
fps = 4 #定义刷新频率
running = True #程序是否结束,初始运行
rect = pygame.Rect(0,0,400,300) #blit方法第3个参数
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT: #处理退出事件
running = False #程序结束
screen.blit(bg_img,(0,0),rect) #绘制背景
rect.x+=5
if bg_width-rect.x<width: #如果长背景右侧沿x轴所剩宽度小于游戏窗口宽度
rect.x=0
screen.blit(p, (200, 270)) #在屏幕指定位置绘制图形
pygame.display.flip() #刷新游戏场景
fclock.tick(fps) #fps是每秒多少帧,减去程序运行时间,为实现fps,还需延迟时间
pygame.quit()
本例使用的2个长背景见下面图像。当使用第一个图形作为背景时,当长背景右侧沿x轴所剩宽度小于游戏窗口宽度(程序第21句),重新从长背景最左侧开始取背景(即从retc.x=0开始),这时将会使背景产生一个突变,不是平滑移动。为克服这点,可采用第二个图像,和第一个图像区别是,该图像前边400点(400是游戏窗口宽度)和最后的400点图像完全相同,再试一下,整个过程背景都能平滑移动。
2维躲避障碍物的小游戏,沿x轴前进或后退,遇到障碍物要跳起躲避,通过后又会遇到新障碍物,一直往前,将遇到很多障碍物。这类游戏也可用上边方法通过背景沿x轴某方向移动,使角色看起来向相反方向移动。一般是通过键盘左右键使背景沿x轴前进或后退,达到角色沿相反方向移动效果。下边是实现的完整演示程序。
import pygame
pygame.init()
size = width, height = 400,300 #创建游戏窗口大小
screen = pygame.display.set_mode(size)
pygame.display.set_caption("pygame游戏使用无分割大背景") #设置窗口标题
bg_img = pygame.image.load("长背景.png").convert() #背景图像
bg_width=bg_img.get_rect().width
p=pygame.image.load("b.png").convert_alpha()
fclock = pygame.time.Clock() #创建控制频率的clock
fps = 10 #使用键盘,刷新频率为4使计算机反应慢
running = True #程序是否结束,初始运行
rect = pygame.Rect(0,0,width,height) #blit方法第3个参数
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT: #处理退出事件
running = False #程序结束
if event.type == pygame.KEYDOWN: #按键后按下事件,避免长按键不抬起
if event.key==pygame.K_RIGHT: #使球向右,背景向左
rect.x+=5
if bg_width-rect.x<width:
rect.x=5 #等于0,有抖动
elif event.key==pygame.K_LEFT: #使球向左,背景向右
rect.x-=5
if rect.x<0:
rect.x=bg_width-width-5 #不减5,有抖动
screen.blit(bg_img,(0,0),rect) #绘制背景
screen.blit(p, (200, 270)) #在屏幕指定位置绘制图形
pygame.display.flip() #刷新游戏场景
fclock.tick(fps) #fps是每秒多少帧,减去程序运行时间,为实现fps,还需延迟时间
pygame.quit()
还有些2维游戏,单纯地扩大背景,使游戏具有更好的观赏性。例如,小蝌蚪吃蚊子幼虫,大鱼吃小鱼等。下边的例子,背景是4个游戏窗口大,即背景的宽和高都是游戏窗口的宽和高的两倍,用鼠标控制小球使其能移到背景的任意位置,即小球移到游戏窗口左(或右、上和下)边界,同时也移到大背景左(或右、上和下)边界。下边是实现该设想的完整程序。注意程序中,用键盘控制小球移动,背景也要反向移动,两者速度相同。
import pygame
pygame.init()
size = width, height = 480,360 #创建游戏窗口大小
screen = pygame.display.set_mode(size)
pygame.display.set_caption("pygame游戏使用无分割大背景") #设置窗口标题
bg_img = pygame.image.load("背景.jpeg").convert() #背景图像
p=pygame.image.load("b.png").convert_alpha()
fclock = pygame.time.Clock() #创建控制频率的clock
fps = 10 #刷新频率
running = True #程序是否结束,初始运行
x,y=240,180
rect = pygame.Rect(240,180,480,360) #blit方法第3个参数
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT: #处理退出事件
running = False #程序结束
if event.type == pygame.KEYDOWN:
if event.key==pygame.K_LEFT:
x-=10
rect.x-=10
if x<0:
x=0
rect.x=0
elif event.key==pygame.K_RIGHT:
x+=10
rect.x+=10
if x>445:
x=445
rect.x=445
elif event.key==pygame.K_UP:
y-=10
rect.y-=10
if y<0:
y=0
rect.y=0
elif event.key==pygame.K_DOWN:
y+=10
rect.y+=10
if y>325:
y=325
rect.y=325
screen.blit(bg_img,(0,0),rect) #绘制背景
screen.blit(p, (x, y)) #在屏幕指定位置绘制图形
pygame.display.flip() #刷新游戏场景
fclock.tick(fps) #fps是每秒多少帧,减去程序运行时间,为实现fps,还需延迟时间
pygame.quit()
如果背景是9个游戏窗口大,即背景的宽和高都是游戏窗口的宽和高的3倍,则背景移动速度是小球的2倍。下面用两个图形说明具体原因,图中黑框是游戏窗口,多个红框是背景,1处是小球位置,其移到游戏窗口左边界(2号位置)距离,两图相同,为游戏窗口宽的1半,在小球移到游戏窗口左边界同时,背景左边界要必须(从3到2)右移,要同时移到游戏窗口左边界,但背景左边界移到游戏窗口左边界距离,是不同的,图1是游戏窗口宽的1半,图2是游戏窗口宽,所以速度应是小球速度的2倍。由此可推断,背景的宽和高是游戏窗口的宽和高的n倍,背景移动速度是小球的n-1倍。
效果图如下:
以上是关于pygame游戏使用不分割大图像做背景的方法的主要内容,如果未能解决你的问题,请参考以下文章
pygame障碍游戏将障碍直接画在背景中,实现用mask侦测背景中障碍和用颜色区分不同障碍的方法
pygame障碍游戏将障碍直接画在背景中,实现用mask侦测背景中障碍和用颜色区分不同障碍的方法
pygame障碍游戏将障碍直接画在背景中,实现用mask侦测背景中障碍和用颜色区分不同障碍的方法
超人游戏_将障碍画在背景中用pygame.mask.from_threshold实现超人和不同颜色障碍精准碰撞检测