[Python-Pygame]无中生有开发自己的2D动作游戏

这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战

在开始人物移动之前,先优化一下背景,免得调试时伤眼(・∀・(・∀・(・∀・*)。

def update(self):
    self.draw_background()

    self.screen.blit(self.player.image, self.player.rect)

    self.player.update()
    self.display.update()
复制代码

首先,将背景的生成统统丢到self.draw_background()中,保持update函数的清洁,之后可能还有很多的物体需要在update函数内进行刷新,无关紧要的代码还是放到一边比较好看:

def draw_background(self):
    self.screen.fill(THECOLORS['white'])
    for i in range(6):
        self.screen.blit(self.tree, [150 * i, 0])
    for i in range(18):
        self.screen.blit(self.road, [50 * i, 300])
        self.screen.blit(self.dirt, [50 * i, 350])
复制代码

而在背景绘制函数中,我们把资源加载的语句也统统摘了出去(放在了__init__里面)作为Game的一个属性,这样一来,我们仅需读取一次,就能从内存中直接获得各类资源,不需要反复读取文件,导致运行速度下降。(项目做大了也要及时清理不必要的资源,以防发生OOM)

image.png

这是优化过后的背景图片(素材还是隔壁项目拉过来的(~ ̄▽ ̄)~)。

一、监听按键

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.display.quit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_a:
                print("按下了a键")
            elif event.key == pygame.K_d:
                print("按下了d键")
        elif event.type == pygame.KEYUP:
            print("按键松开")
复制代码

按键监听和之前的关闭监听都是pygame事件监听的一部分,所以只需要在之前的while循环的事件监听下中添加按键监听。

通过event.key,我们就可以查看被按下的键代码(整型),通过与pygame的常量想对应,使用一堆if语句,就能监听到我们想要的按键,并可以针对不同按键做出不同的应答。

二、实现人物移动

在上篇文章中,我们通过给人物一个起始速度,在进行游戏帧更新的时候,使用update函数根据速度对人物的坐标进行了修改,实现了人物的平移操作。

那么每当移动按键按下后,我们就给人物一个水平速度,按键松开后将速度清零,不就能实现人物的移动了吗?

  • print("按下了a键") -> self.player.speed = -5
  • print("按下了d键") -> self.player.speed = 5
  • print("按键松开") -> self.player.speed = 0

将上述代码进行以下替换,启动程序:
1628170417750 00_00_00-00_00_30.gif

三、移动动作

只是简单的平移,那也未免过于单调了一些,给人物一连串的动作能够让游戏生动起来。

首先,先加载所有的图片,使用数组的方式存储,既能方便我们后面循环调用,又可以较为方便的进行导入:

image.png
然后为Player添加index字段,用于记录人物的动作到了哪一张图像。

def update(self):
    if self.speed:
        self.rect.left += self.speed
        self.index = (self.index + 1) % len(self.walk_images)
    else:
        self.index = 0
    self.image = self.walk_images[self.index]
复制代码

将Player的update函数进行修改,保持人物横坐标随速度更新的代码不变,对于人物行走动画进行一个循环(对数组加一并取余数组长度,实现了循环,同时保持数组不越界)。

图像索引会在速度为0的时候置为0,在画面上就表现为,松开移动键后,人物原地站立。

实现效果如下图:

1628171366688 00_00_00-00_00_30.gif