Estoy tratando de desarrollar un juego simple hecho con Pygame (biblioteca de Python).
Tengo un sprite
objeto que es el player
y lo muevo usando las teclas de flecha. Si no muevo el mouse, el sprite se mueve normalmente, pero cuando muevo el mouse, el sprite se mueve más rápido (como x2 o x3). El player
objeto está dentro de la charsGroup
var.
Ejecuté el juego en W7 y en Ubuntu. Lo mismo sucede en ambos sistemas operativos.
Tengo más entidades que se mueven como NPC y balas, pero no se ven afectadas, solo el jugador. Dado esto, creo que el problema puede tener una conexión directa con el sistema de movimiento del jugador (teclas de flecha).
Aquí está el update()
método del player
objeto:
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
Y aquí está el ciclo 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()
No sé qué más puede necesitar para ayudarme, pero cualquier cosa que necesite (más información o código) ¡solo pídala!
BULLET_IMAGE = pygame.image.load("bullet.png")
y luegoself.bulletsGroup.add(Bullet(BULLET_IMAGE...
Respuestas:
tl; dr no mezcle su bucle de eventos con su bucle de juego .
Cuando mueves el mouse, el juego recibe una gran cantidad de
pygame.MOUSEMOTION
eventos. Sin embargo, en realidad no utiliza estos eventos para actualizar la posición del mouse, está obteniendo el estado actual del mousepygame.mouse.get_pos()
. Eso es ineficiente, pero no es el problema.¡El problema es que estás actualizando la posición del jugador dentro del bucle de eventos !
Esto es lo que se supone que debe suceder:
Esto es lo que hace tu código:
Cuando mueve el mouse, el bucle de eventos se ejecutará muchas veces por cuadro. Pero cuando verifica con qué teclas se presionan
pygame.key.get_pressed()
, permanecen presionadas hasta que lo suelta, algún tiempo después. Entonces, a medida que su ciclo de eventos se agita a través de los eventos de movimiento del mouse, volverá a aplicar los movimientos del jugador repetidamente.La solución es simple: mover al jugador fuera del ciclo de eventos.
fuente
pygame.mouse.get_pos()
es ineficiente? ¿Qué alternativas tengo?pygame.mouse.get_pos()
obtiene la última posición del mouse, independientemente de la cola del evento, por lo que no es necesario ponerlo dentro del bucle de eventos. La alternativa sería procesar cadapygame.MOUSEMOTION
uno usted mismo, pero a menos que necesite cada evento (por ejemplo, si está escribiendo un programa de pintura), la última posición lo hará.Aquí hay algunos pensamientos más para complementar la respuesta existente .
Gaffer On Games tiene un gran artículo sobre bucles de juegos que se ha mencionado en todas partes.
Su ciclo de juego debe tener diferentes etapas independientes: Entrada, Actualización, Render.
Podría, por ejemplo, leer entradas 30 veces por segundo (o en tiempo real para una mejor capacidad de respuesta), hacer 30 actualizaciones por segundo y renderizar 60 cuadros por segundo, o cualquier valor que funcione bien para su juego.
fuente