为什么移动鼠标时我的精灵播放器移动得更快?


17

我正在尝试开发一个使用Pygame(Python库)制作的简单游戏。

我有一个sprite物体,player然后使用箭头键将其移动。如果我不移动鼠标,则精灵会正常移动,但是当我移动鼠标时,精灵会移动得更快(例如x2或x3)。该player对象位于charsGroupvar 内部。

我已经在W7和Ubuntu中运行了该游戏。两种操作系统都发生相同的情况。

我有更多的实体会像NPC和子弹一样移动,但它们不会受到影响,只是玩家。鉴于此,我认为问题可能与玩家移动系统(箭头键)直接相关。

这是对象的update()方法player

def update(self):

    for event in pygame.event.get():
        key = pygame.key.get_pressed()
        mouseX, mouseY = pygame.mouse.get_pos()
        if event.type == pygame.MOUSEBUTTONDOWN:
            self.bulletsGroup.add(Bullet(pygame.image.load("bullet.png"),
                                          self.rect.x + (self.image.get_width()/2),
                                           self.rect.y + (self.image.get_height()/2),
                                            mouseX, mouseY, 50, 50))

        if key[pygame.K_RIGHT]:
            if not self.checkCollision():
                self.rect.x += 10
            else:
                self.rect.x -= 10
        if key[pygame.K_LEFT]:
            if not self.checkCollision():
                self.rect.x -= 10
            else:
                self.rect.x += 10
        if key[pygame.K_UP]:
            if not self.checkCollision():
                self.rect.y -= 10
            else:
                self.rect.y += 10
        if key[pygame.K_DOWN]:
            if not self.checkCollision():
                self.rect.y += 10
            else:
                self.rect.y -= 10

这是while循环:

while True:

    if PLAYER.healthBase <= 0:
        GAMEOVER = True

    if not GAMEOVER:
        mapTilesGroup.draw(SCREEN)
        charsGroup.update()
        charsGroup.draw(SCREEN)
        npcsGroup.update()
        npcsGroup.draw(SCREEN)
        drawBullets()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()

    if GAMEOVER:
        myfont = pygame.font.SysFont("monospace", 30)
        label = myfont.render("GAME OVER!", 1, (255, 255, 0))
        SCREEN.blit(label, (400, 300))

    freq.tick(0)

    pygame.display.flip() 

我不知道您还需要什么帮助我,但是您需要的任何东西(更多信息或代码)都可以要求!


5
您的确切错误实际上存在于许多应用程序中。尝试在大文档中拖动选择,然后将光标移到边缘之外。通常,程序的边缘滚动将插入并缓慢选择更多文档。如果左右移动鼠标,则滚动速度通常会更快,因为它们的滚动速度与事件循环相关,并且X动作会反复唤醒事件循环。
本杰克逊

2
@BenJackson当滚动开始时非常缓慢时,我发现这是个有用的错误。
user253751 2015年

1
这与您的错误无关,但是我建议一次加载图像,并将其存储在对象中。BULLET_IMAGE = pygame.image.load("bullet.png")再后来self.bulletsGroup.add(Bullet(BULLET_IMAGE...
DJMcMayhem

@DJMcMayhem您完全正确,我已经用其余图像完成了此操作,但是我错过了使用此功能..谢谢!:)
Drumnbass 2015年

Answers:


42

tl; dr不要将事件循环游戏循环混在一起

当您移动鼠标时,游戏会收到大量pygame.MOUSEMOTION事件。您实际上并没有使用这些事件来更新鼠标位置,而是使用以下命令获取了鼠标的当前状态pygame.mouse.get_pos()。效率低下,但这不是问题。

问题是您正在更新事件循环内的玩家位置

这是应该发生的事情:

game loop:
    event loop # get key presses, mouse moves etc.)
    if key pressed in the event loop:
        move the player

这是您的代码的作用:

game loop:
    event loop:
        if key pressed:
            move the player

当您移动鼠标时,事件循环将每帧执行多次。但是当您检查按下了哪些键时pygame.key.get_pressed(),它们会一直保持按下状态,直到您放开一段时间。因此,当您的事件循环通过鼠标移动事件进行搅动时,它将重新应用播放器的重复移动。

解决方案很简单:将播放器移出事件循环。


1
谢谢!现在它可以完美运行,可能我从未意识到发生了什么!顺便说一句,你为什么说那pygame.mouse.get_pos()效率低下?我有什么选择?
Drumnbass,2015年

嗨@congusbongus,你能解释一下吗?谢谢。
Drumnbass,2015年

pygame.mouse.get_pos()无论事件队列如何,@ Drumnbass 都会获取鼠标的最新位置,因此无需将其放在事件循环中。另一种方法是pygame.MOUSEMOTION自己动手,但除非您需要每一个事件(例如,您正在编写绘画程序),否则都会使用最新职位。
congusbongus

3

这里还有一些补充现有答案的想法。

Gaffer On Games上一篇很棒的关于游戏循环的文章到处都有引用。

您的游戏循环应具有不同的独立阶段:输入,更新,渲染。

例如,您可以每秒读取30次输入(或实时读取输入以提高响应速度),每秒进行30次更新并每秒渲染60帧,或者任何适合您游戏的值。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.