J'essaie de développer un jeu simple fait avec Pygame (bibliothèque Python).
J'ai un sprite
objet qui est le player
et je le déplace à l'aide des touches fléchées. Si je ne déplace pas la souris, l'image-objet se déplace normalement, mais lorsque je déplace la souris, l'image-objet se déplace plus rapidement (comme x2 ou x3). L' player
objet est à l'intérieur de la charsGroup
var.
J'ai exécuté le jeu dans W7 et dans Ubuntu. La même chose se produit dans les deux systèmes d'exploitation.
J'ai plus d'entités qui se déplacent comme des PNJ et des balles mais elles ne sont pas affectées, juste le joueur. Compte tenu de cela, je pense que le problème a peut-être une connexion directe avec le système de déplacement du joueur (touches fléchées).
Voici la update()
méthode de l' player
objet:
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
Et voici la boucle 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()
Je ne sais pas de quoi vous avez besoin pour m'aider, mais tout ce dont vous avez besoin (plus d'informations ou de code), demandez-le!
BULLET_IMAGE = pygame.image.load("bullet.png")
puis plus tardself.bulletsGroup.add(Bullet(BULLET_IMAGE...
Réponses:
tl; dr ne mélangez pas votre boucle d'événement avec votre boucle de jeu .
Lorsque vous déplacez votre souris, le jeu reçoit une charge d'
pygame.MOUSEMOTION
événements. Cependant, vous n'utilisez pas ces événements pour mettre à jour la position de votre souris, vous obtenez l'état actuel de la souris en utilisantpygame.mouse.get_pos()
. C'est inefficace, mais ce n'est pas le problème.Le problème est que vous mettez à jour la position du joueur dans la boucle d'événement !
C'est ce qui est censé se produire:
Voici ce que fait votre code:
Lorsque vous déplacez votre souris, la boucle d'événements s'exécute plusieurs fois par image. Mais lorsque vous vérifiez avec quelles touches vous appuyez
pygame.key.get_pressed()
, elles restent enfoncées jusqu'à ce que vous les relâchiez, quelque temps après. Ainsi, pendant que votre boucle d'événement passe à travers les événements de déplacement de la souris, elle réappliquera les mouvements du joueur à plusieurs reprises.La solution est simple: déplacer le joueur hors de la boucle d'événement.
la source
pygame.mouse.get_pos()
c'est inefficace? Quelles alternatives ai-je?pygame.mouse.get_pos()
obtient la dernière position de la souris, quelle que soit la file d'attente des événements, il n'est donc pas nécessaire de la placer dans la boucle d'événements. L'alternative serait de traiter toutpygame.MOUSEMOTION
vous-même, mais à moins que vous n'ayez besoin de chaque événement (par exemple, vous écrivez un programme de peinture), la dernière position fera l'affaire.Voici quelques réflexions supplémentaires pour compléter la réponse existante .
Gaffer On Games a un excellent article sur les boucles de jeu qui a été référencé partout.
Votre boucle de jeu doit avoir différentes étapes indépendantes: entrée, mise à jour, rendu.
Vous pouvez par exemple lire les entrées 30 fois par seconde (ou en temps réel pour une meilleure réactivité), faire 30 mises à jour par seconde et afficher 60 images par seconde, ou toutes les valeurs qui fonctionnent bien pour votre jeu.
la source