Bug en controles [Pygame]

Agrupa todas las consultas sobre los lenguajes de programacion como C, C++, Python, Java ...

Bug en controles [Pygame]

Notapor Garolard » Jue Oct 15, 2009 7:49 pm

Hola a todos.

Bueno en mi primer mensaje quería preguntar una duda sobre un ligero "fallo" en un pequeño juego que estoy haciendo con python y pygame. He buscado alguna solución por internet pero no veo nada que me ayude.
El problema es el siguiente: Tengo una navecita, que solo se desplaza lateralmente usando las teclas de dirección. Se mueve bien y responde correctamente a los controles, pero el problema llega al querer hacer un cambio de dirección brusco.
Resulta que si, por ejemplo, pulso la tecla derecha -> se mueve a la derecha. Sin soltar dicha tecla, pulso la izquierda -> se mueve a la izquierda. Y de nuevo sin soltar la derecha, suelto la izquierda -> la nave se queda parada hasta que se vuelve a pulsar alguna tecla.

Dicho así es como para pensar "hay que ser muy lerdo para hacer eso mientras se juega", pero la verdad es que es posible, aunque solo sea cuando pulsas ambas teclas rápidamente para hacer un cambio de dirección como ya he dicho. Pasa muchas veces y puede llegar a molestar. Y bueno, pos al final me decidí a registrarme y pedir ayuda a ver si a alguien se le ocurre algo para ayudarme con este problemilla.

Gracias de antemano al que pueda responderme.

PD: Código donde están los controles de la nave:
Código: Seleccionar todo
while True:
        CLOCK.tick(60)
       
        for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit(0)
            elif event.type == KEYDOWN:
                if event.key == K_RIGHT:
                    ship.vel[0] = 3
                elif event.key == K_LEFT:
                    ship.vel[0] = -3
                elif event.key == K_SPACE:
                    laserSprite.add(Shoot(ship.rect.midtop))
            elif event.type == KEYUP:
                if event.key == K_RIGHT or event.key == K_LEFT:
                    ship.vel[0] = 0
               
       
        shipSprite.update()
        laserSprite.update()
        enemySprite.update()
        enemyLaserSprite.update()
Garolard
 
Mensajes: 6
Registrado: Jue Oct 15, 2009 7:39 pm

Notapor Juanxo » Vie Oct 16, 2009 12:53 am

Buenas Garolard:

Lo primero darte la bienvenida a LosersJuegos.

Lo segundo, decirte que el motivo de que te ocurra esto que comentas se debe a lo siguiente:
En tu bucle, compruebas si los eventos que has creado son del tipo KEYDOWN. El problema radica en el hecho de que cuando pulsas la tecla derecha, se crea un evento KEYDOWN de esa tecla. Lo mismo pasa cuando pulsas la tecla izquierda. Pero cuando levantas la tecla izquierda, no se genera ningun evento keydown, puesto que solo se generan en el momento de la pulsacion, por lo que la velocidad se queda a 0.

Un método algo guarrillo quizas, sería el siguiente:

Código: Seleccionar todo

teclado = pygame.key.get_pressed()

for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit(0)
            elif event.type == KEYDOWN:
                if event.key == K_RIGHT:
                    ship.vel[0] = 3
                elif event.key == K_LEFT:
                    ship.vel[0] = -3
                elif event.key == K_SPACE:
                    laserSprite.add(Shoot(ship.rect.midtop))
            elif event.type == KEYUP:
                if event.key == K_RIGHT and teclado[K_LEFT]:
                    ship.vel[0] = -3
                elif event.key == K_LEFT and teclado[K_RIGHT]:
                    ship.vel[0] = 3
                elif event.key == K_RIGHT or event.key == K_LEFT:
                    ship.vel[0] = 0


No lo he probado, pero en teoría así debería de funcionar

Hasta otra!!
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor hugoruscitti » Vie Oct 16, 2009 1:29 am

Recuerda que pygame tiene nos modos para gestionar
el teclado, y generalmente los eventos no son el
modo preferido...

Intenta lo siguiente, tal vez así resulte mas sencillo
resolver la simultaneidad de teclas: pygame tiene una
función llamada "get_pressed()" que obtiene todo el
mapa de teclado de una sola vez.

Así, el algoritmo de pulsación de teclas quedaría de
la siguiente manera:


Código: Seleccionar todo
while True:
        CLOCK.tick(60)

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

        keys = pygame.key.get_pressed()

        # realiza movimientos.

        if keys[K_RIGHT]:
            ship.vel[0] = 3

        if keys[K_LEFT]:
            ship.vel[0] = -3


        # detiene el movimiento.
        if ship.vel[0] > 0:      # si esta llendo hacia la derecha.
            if not keys[K_RIGHT]:
                ship.vel[0] = 0
        elif ship.vel[0] < 0:
            if not keys[K_LEFT]:
                ship.vel[0] = 0

        shipSprite.update()
        laserSprite.update()
        enemySprite.update()
        enemyLaserSprite.update()



Si, en principio es mas código, pero resulta mas sencillo de adaptar
a nuevas situaciones y no tendrás problemas de sincronización. Al menos
a mí me parece una solución que te pueda resultar.

PD: no, yo tampoco probé el código...
Avatar de Usuario
hugoruscitti
Site Admin
 
Mensajes: 1242
Registrado: Dom Jul 30, 2006 3:57 am
Ubicación: Buenos Aires, Argentina

Notapor Garolard » Vie Oct 16, 2009 2:31 pm

Que maestros! :D muchas gracias por la explicación a ambos, al final me ha quedado bastante claro que estaba fallando. Al final he seguido vuestros consejos y ahora los controles van fijos como la seda! :D
Muchísimas gracias a los dos, espero segiur pasándome mucho por aquí para aprender más cosas (a parte de esta xD) sobre la programación de videojuegos.

En un futuro espero pasar a usar C++ y entonces seguramente me pase el día por aquí preguntando dudas xD.

Saludos y de nuevo muchas gracias.
Garolard
 
Mensajes: 6
Registrado: Jue Oct 15, 2009 7:39 pm

Notapor shackra » Sab Nov 14, 2009 8:05 pm

quien es mas ordenado a la hora de escribir codigo?, hugoruscitti ó Juanxo:


hugoruscitti
Código: Seleccionar todo
while True:
        CLOCK.tick(60)

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

        keys = pygame.key.get_pressed()

        # realiza movimientos.

        if keys[K_RIGHT]:
            ship.vel[0] = 3

        if keys[K_LEFT]:
            ship.vel[0] = -3


        # detiene el movimiento.
        if ship.vel[0] > 0:      # si esta llendo hacia la derecha.
            if not keys[K_RIGHT]:
                ship.vel[0] = 0
        elif ship.vel[0] < 0:
            if not keys[K_LEFT]:
                ship.vel[0] = 0

        shipSprite.update()
        laserSprite.update()
        enemySprite.update()
        enemyLaserSprite.update()


Juanxo
Código: Seleccionar todo
teclado = pygame.key.get_pressed()

for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit(0)
            elif event.type == KEYDOWN:
                if event.key == K_RIGHT:
                    ship.vel[0] = 3
                elif event.key == K_LEFT:
                    ship.vel[0] = -3
                elif event.key == K_SPACE:
                    laserSprite.add(Shoot(ship.rect.midtop))
            elif event.type == KEYUP:
                if event.key == K_RIGHT and teclado[K_LEFT]:
                    ship.vel[0] = -3
                elif event.key == K_LEFT and teclado[K_RIGHT]:
                    ship.vel[0] = 3
                elif event.key == K_RIGHT or event.key == K_LEFT:
                    ship.vel[0] = 0


sin duda, hugoruscitti xD.
perfiles vemos, estilos no sabemos!
Avatar de Usuario
shackra
 
Mensajes: 308
Registrado: Lun Jun 15, 2009 4:10 pm
Ubicación: Costa Rica

Notapor Juanxo » Dom Nov 15, 2009 1:12 am

vale, jooo, voy a saltar desde un quinto ahora vuelvo!!

si, es cierto que la solución de hugo es mejor, principalmente por lo que ha dicho, demostrando una cierta vision de futuro (será la experiencia), pero ten en cuenta la diferencia de experiencia y de conocimiento de uno y de otro.

de ahora en adelante cuidaré más mis exposiciones.

gracias por el comentario shackra, mejor saber que permanecer ignorante de mis errores.
Avatar de Usuario
Juanxo
 
Mensajes: 437
Registrado: Sab Ene 31, 2009 2:34 am
Ubicación: Madrid(España)

Notapor hugoruscitti » Dom Nov 15, 2009 3:12 am

A mi me gustan las dos versiones, y si tengo que
elegir solo una me quedo con la versión de Juanxo.
Avatar de Usuario
hugoruscitti
Site Admin
 
Mensajes: 1242
Registrado: Dom Jul 30, 2006 3:57 am
Ubicación: Buenos Aires, Argentina


Volver a Sobre lenguajes de programación

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado