一些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点图像完全相同,再试一下,整个过程背景都能平滑移动。

python中screen是什么 pygame中screen.blit_python中screen是什么


python中screen是什么 pygame中screen.blit_窗口大小_02


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倍。

python中screen是什么 pygame中screen.blit_背景图_03


效果图如下:

python中screen是什么 pygame中screen.blit_无分割大背景_04