这是系列教程“使用 Pygame 进行游戏开发”的第 2 部分。它适用于对游戏开发和提高 Python 编码技能感兴趣的小朋友。 第一部分在此。
什么是精灵?
sprite 是计算机图形学术语,表示屏幕上可以移动的任何对象。 当您玩任何 2D 游戏时,您在屏幕上看到的所有对象都是精灵。 Sprites 可以是动画的,它们可以由玩家控制,它们甚至可以相互交互。
我们将在游戏循环的 UPDATE 和 DRAW 部分更新和绘制精灵。 但是你可以想象,如果你的游戏有大量的精灵,那么你的游戏循环的这些部分可能会变得非常长和复杂。 幸运的是,Pygame提供了一个很好的解决方案:精灵组(SpriteGroup)。
精灵组是可以同时操作的精灵的集合。 让我们创建一个精灵组来保存我们游戏中的所有精灵:
clock = pygame.time.Clock()
all_sprites = pygame.sprite.Group()
我们可以通过在循环中添加以下内容来利用该精灵组:
# Update
all_sprites.update()
# Draw / render
screen.fill(BLACK)
all_sprites.draw(screen)
现在,对于我们创建的每个精灵,我们只需确保将其添加到all_sprites 精灵组,它会自动绘制在屏幕上,并在每次循环中更新。
创建一个精灵
现在我们准备制作我们的第一个精灵。 在 Pygame 中,精灵是对象。 如果您以前没有在 Python 中使用过对象,那么它们是一种将数据和代码分组到单个实体中的便捷方式。 一开始可能有点混乱,但幸运的是,Pygame 精灵是练习对象并习惯它们工作方式的好方法。
我们首先定义我们的新精灵:
class Player(pygame.sprite.Sprite):
pass
class是定义类的关键字,告诉 Python 我们正在定义一个新对象,它将成为表示玩家(Player)的sprite,它的父类型是 pygame.sprite.Sprite,这意味着它继承 Pygame 的预定义 Sprite 类。
我们在类定义中需要的第一段代码是特殊的 init() 函数,它定义了每当创建这种类型的新对象时将运行的代码。 每个 Pygame 精灵还必须具有两个属性:image和rect:
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((50, 50))
self.image.fill(GREEN)
self.rect = self.image.get_rect()
我们来解读一下这个类的的定义:
第一行 pygame.sprite.Sprite.init(self) 是 Pygame 所必需的——它运行内置的 Sprite 类初始化程序。 接下来,我们定义sprite的image属性——在本例中,我们只是创建一个简单的 50 x 50 正方形并用绿色填充它。 稍后我们将学习如何使使用真正的图片来使得精灵变得更漂亮,比如角色或宇宙飞船,但现在一个实心正方形就足够了。
接下来,我们必须定义精灵的rect属性,它是“矩形(rectangle)”的缩写。 Pygame 中到处都使用矩形来跟踪对象的坐标。 get_rect() 命令只是查看图像并计算包围它的矩形。
我们可以使用 rect 将精灵放在屏幕上任何我们想要的位置。 让我们从中心的精灵开始:
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((50, 50))
self.image.fill(GREEN)
self.rect = self.image.get_rect()
self.rect.center = (WIDTH / 2, HEIGHT / 2)
现在我们已经定义了 Player sprite,我们需要通过创建 Player 类的实例来“生成”它(即创建“Player对象”)。 我们还需要确保将精灵添加到 all_sprites 组:
all_sprites = pygame.sprite.Group()
player = Player()
all_sprites.add(player)
现在,如果运行这个程序,你会看到屏幕中央的绿色方块。 继续并增加程序的 WIDTH 和 HEIGHT 设置,以便有足够的空间让精灵在下一步中四处移动。
精灵的运动
请记住,在游戏循环中,我们有 all_sprites.update()。 这意味着对于组中的每个精灵,Pygame 将寻找各自的 update() 函数并运行它。 所以为了让我们的精灵动起来,我们只需要定义它的更新规则:
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((50, 50))
self.image.fill(GREEN)
self.rect = self.image.get_rect()
self.rect.center = (WIDTH / 2, HEIGHT / 2)
def update(self):
self.rect.x += 5
这意味着每次通过游戏循环,我们将精灵的 x 坐标增加 5 个像素。 再次运行它,你会看到精灵正在朝右移动并消失在屏幕右侧之外:
让我们通过让精灵环绕来解决这个问题——只要它到达屏幕的右侧,我们就会将它移动到左侧。 我们可以通过使用精灵矩形上的一个方便的“句柄”轻松做到这一点:
因此,如果矩形的左边缘离开屏幕,我们将右边缘设置为 0:
class Player(pygame.sprite.Sprite):
def __init__(self):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface((50, 50))
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
现在我们可以看到精灵会环绕屏幕:
本篇内容到这里就结束了。另外,请注意,在 sprite 的 update() 方法中放入的任何内容都会在每一帧发生。 尝试让精灵上下移动(改变 y 坐标)或让它从墙上反弹(当矩形到达边缘时反转方向)。
可以点击此处查看完整代码。
在下一个教程中,我们将向您展示如何为您的精灵使用图片 - 将它从一个普通的正方形变成一个动画角色。