pygame 精灵图和绘制方法未按预期工作

pygame sprite and draw method not working as expected

如有任何帮助,我们将不胜感激。 我正在用 Pygame 编写游戏,并在创建我需要的所有 类 和方法之后。当我 运行 游戏时,我看到我的游戏的五个外星人角色从屏幕左侧出现并连接在一起,然后我才真正看到我想要我的代码显示的内容(外星人在屏幕上随机移动)。

这是我的代码:

class Alien():
    def __init__(self, image):
        self.x = random.randrange(20,width - 20)
        self.y = random.randrange(-200, -20)
        self.speed = random.randint(1, 5)
        self.image = pygame.image.load(os.path.join("../images", image)).convert_alpha()
        self.rect = self.image.get_rect()

    def move_down(self):
        self.rect.y += self.speed

    def draw(self, screen):
        screen.blit(self.image, self.rect)

其实施

for i in range (20):
    aliens = Alien("alien.png")
    enemies.append(aliens)

done = False
while done == False:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True

    screen.fill(white)

    for i in range(len(enemies)):
        enemies[i].move_down()
        enemies[i].draw(screen)
        enemies[i].check_landed()

    pygame.display.flip()
    clock.tick(30)

注意:为清楚起见,我删除了一些代码。 结果

你把外星人的位置存储在字段self.xself.y中,但要绘制它们,你实际上并没有使用self.xself.y,但是 self.rect.

您通过调用 self.image.get_rect() 创建 self.rect,当您在 Surface 上调用 get_rect() 时,Rect 的位置始终是 (0, 0).

所以x坐标总是0,所以他们都在屏幕的左边。

我建议将您的代码重写为:

class Alien():
    # pass the Surface to the instance instead of the filename
    # this way, you only load the image once, not once for each alien
    def __init__(self, image):
        self.speed = random.randint(1, 5)
        self.image = image
        # since we're going to use a Rect of drawing, let's use the
        # same Rect to store the correct position of the alien
        self.rect = self.image.get_rect(top=random.randrange(-200, -20), left=random.randrange(20,width - 20))

    def move_down(self):
        # the Rect class has a lot of handy functions like move_ip
        self.rect.move_ip(0, self.speed)

    def draw(self, screen):
        screen.blit(self.image, self.rect)

# load the image once. In more complex games, you usually
# want to abstract the loading/storing of images         
alienimage = pygame.image.load(os.path.join("../images", 'alien.png')).convert_alpha()
for _ in range (20):
    aliens = Alien(alienimage)
    enemies.append(aliens)

done = False
while done == False:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True

    screen.fill(white)

    # just use a "regular" for loop to loop through all enemies
    for enemy in enemies:
        enemy.move_down()
        enemy.draw(screen)
        enemy.check_landed()

    pygame.display.flip()
    clock.tick(30)        

您可以更进一步,使用 Sprite- 和 Group-class 进一步概括您的代码,但那是另一个话题了。