利用pygame开发一款游戏:「跳跳兔」(二)

792 阅读5分钟

简介

本节来看一下如何创建一个玩家对象并让其在游戏框中运动。

玩家类

从简到难,先通过一个简单的方块来表示一个玩家。

在pygame中,所有的对象都称为元素,玩家是一个元素,游戏中的怪物也是一个元素,而所有的元素都要通过pygame.sprite.Sprite来控制,下面就来创建一个简单的玩家类。

class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.Surface((50, 50)) # self.image表示元素本身
        self.image.fill(GREEN) # 元素本身填充为绿色
        self.rect = self.image.get_rect() # 获得该元素对应的方块
        self.rect.center = (WIDTH /2, HEIGHT / 2) # 将该元素放置在窗口中间(方块代表这元素)

    # 更新角色 - 移动
    def update(self):
        self.rect.x += 5
        if self.rect.left > WIDTH:
            self.rect.right = 0

我们定义了Player类,它继承于pygame.sprite.Sprite,在__init__()初始化方法中,调用了pygame.sprite.Sprite中的初始化方法,完成基本的初始化。

随后,调用了pygame.Surface()方法创建了一个50x50的正方形,然后将其填充为绿色。最后就是将Player类这个绿色的方法放在游戏框的正中间。

除了定义__init__()方法,Player类中还定义了update()方法,该方法就是让绿色方块沿x轴平移,当绿色方块的left超出游戏框时,就将right置为0,这样就会达到走马灯的效果。

让玩家运动起来

光定义玩家类是无法让玩家元素平移运动的,回顾一下第一篇pygame文章,游戏本质就是循环,每次循环都要处理相应的逻辑,循环中逻辑的不同,造成了不同的游戏,所以为了让玩家元素可以移动,还需要实现这个循环。

首先,依旧是初始化相关的对象。

pygame.init() # pygame初始化
pygame.mixer.init() # mixer在pygame中用于处理一切音频相关的东西
screen = pygame.display.set_mode((WIDTH, HEIGHT)) # 初始化窗口
pygame.display.set_caption('My Game') # 标题名
clock = pygame.time.Clock() # 计时器,主要用于控制界面刷新的频率

# 在一个游戏中,通过一个元素组来表示该游戏中所有的角色
all_sprites = pygame.sprite.Group()
player = Player()
all_sprites.add(player) # 添加到元素组中

与此前不同,因为多了玩家元素,所以需要初始化pygame.sprite.Group(),然后将玩家对象添加到元素组中,pygame要求我们通过元素组的方式来操作不同的元素。

初始化完成后,直接一个无限循环,代码如下

# 所有游戏都是一个循环, 循环中通常由三个部分组成,事件输入、元素状态更新、绘制
running = True
while running:
    # 帧率
    clock.tick(FPS)
    # 处理事件输入
    for event in pygame.event.get():
        if event.type == pygame.QUIT: #如果点击 x 按钮,游戏推出,即跳出循环
            running = False
    all_sprites.update() # 更新角色
    # 绘制与渲染(依旧是黑色背景)
    screen.fill(BLACK)
    all_sprites.draw(screen) #绘制所有元素到界面中
    # 翻转绘画板,更新界面,绘制任何内容,都需要这个步骤,不然绘制的内容在背面,玩家是不可见的
    pygame.display.flip()

为了方便大家理解,代码中我依旧给出了详细的注释,唯一不同就是多了事件输入的处理逻辑以及角色更新的逻辑。

通过pygame.event.get()可以获得pygame可以接收到的所有事件,在这个循环中,判断了事件类型,如果点击了窗口关闭按钮,就将running设置为False,结束无限循环。

此外,调用了元素组中的update()方法,对所有元素的状态进行更新,而当下元素组中只有玩家对象,所有玩家对象的状态被更新了,简单而言,玩家此时沿x轴移动了5个像素。随后的代码都与第一篇相同,不再赘述。

此时运行整个完整的代码,绿色方块就会在游戏屏幕中移动,实现跑马灯效果了。

更进一步

玩家类是一个绿色方块显得太过简陋,这里将其替换为一张图片,此外让玩家可以上下跳动,修改后,玩家类代码如下:

class Player(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        # pygame加载图像元素时,记得要使用convert()方法将图像转为pygame容易操控的对象,否则整个游戏加载会变慢
        self.image = pygame.image.load(os.path.join(img_folder, 'p1_jump.png')).convert()
        self.image.set_colorkey(BLACK) # 将图像矩阵中除图像外周围的元素都设置为透明的
        self.rect = self.image.get_rect() # 获得该元素对应的方块
        self.rect.center = (WIDTH /2, HEIGHT / 2) # 将该元素放置在窗口中间(方块代表这元素)
        self.y_speed = 5

    # 更新玩家状态
    def update(self):
        self.rect.x += 5
        self.rect.y += self.y_speed
        if self.rect.bottom > HEIGHT - 200:
            self.y_speed = -5
        if self.rect.top < 200:
            self.y_speed = 5
        if self.rect.left > WIDTH:
            self.rect.right = 0

上述代码中,利用pygame.image.load()方法实现图像元素的加载,需要注意,加载完后,一定要使用convert()方法将其转为pygame容易操作的对象(这是个Ticks),接着还需要使用set_colorkey()方法将图像元素外的其他元素都设置为透明,不然显示在pygame游戏框中就会是一个正方形,正方形中有张图片,非常的丑。

此外,update()方法也走了一些逻辑修改,让玩家元素除了在x轴移动外,还实现其在y轴移动,移动的方式是上下跳动的形式,最终效果如下。

本节介绍了pygame怎么样去管理元素,在下一节中,将介绍pygame如何控制元素移动,即通过键盘控制游戏框中元素的移动。

如果文章对你有所帮助,请点「在看」给作者一点鼓励,叩谢豪恩。