Problema con intento de car

Losersjuegos cuenta con una secciones de ejemplos en su web. Utilice esta sección para consultar o proponer ideas acerca de ellos.

Problema con intento de car

Notapor endaramiz » Vie Ago 31, 2007 10:39 am

Antes de nada como es mi primer mensaje querría felicitaros por esta gran web.
Soy novato y con problemas de ingles pero después de leer documentación de python y algo sobre pygame (entre ellos el ejemplo de car que encontré en esta misma web) quise hace la prueba de un coche que se moviese por la pantalla, bueno en realidad algo como un tanque por que quería que girase sobre si mismo. He conseguido hacer que avance y gire pero tengo básicamente dos problemas:
-La imagen solo gira en el momento de pulsar la tecla y no si se mantiene pulsada
-Si se pulsa la tecla de avance (K_UP) comienza a moverse pero si se cambia el ángulo de la imagen la dirección no se actualiza asta que se suelta la tecla "K_UP"

Probé de poner los eventos de teclado como en el ejemplo de car pero con eso no se por que no me reconoce que pulso las teclas. Y al cambiarlos de sitio me hace el mismo efecto. Gracias de antemano y disculpen las molestias, solo decir que valoro vuestro tiempo pero llevo horas encallado sin encontrar solución.

aquí va el código:
Código: Seleccionar todo
import pygame
from pygame.locals import *
from math import sin, cos, radians


class coche (pygame.sprite.Sprite):
   
   def __init__ (self, startpos):
      pygame.sprite.Sprite.__init__(self)
      self.image_original = pygame.image.load ("coche.png")
      self.image = self.image_original.copy()
      self.rect = self.image.get_rect()
      self.rect.center = startpos
      self.angle = 0
      self.vel = [0,0]


   def update (self):
   #   *ESTA PARTE NO ME RESPONDE
   
   #   key = pygame.key.get_pressed()
   #   if key == [K_LEFT]:
   #      self.angle -= 10
   #   elif key == [K_RIGHT]:
   #      self.angle += 10
   #   
   #   if key == [K_UP]:
   #      angle = radians(self.angle)
   #      self.vel[0] = cos(angle) * 7
   #      self.vel[1] = sin(angle) * 7
   #   else:
   #      self.vel = [0,0]

      # *ESTA PARTE NO FUNCIONA COMO QUIERO
      for event in pygame.event.get():
         if event.type == QUIT:
            sys.exit()
         elif event.type == KEYDOWN:
            if event.key == K_LEFT:
               self.angle -= 10
            elif event.key == K_RIGHT:
               self.angle += 10
            if event.key == K_UP:
               angle = radians(self.angle)
               self.vel[0] = cos(angle) * 7
               self.vel[1] = sin(angle) * 7
         elif event.type == KEYUP:
            if event.key == K_UP:
               self.vel[0] = 0
               self.vel[1] = 0
            elif event.key == K_LEFT:
               pass
      
      self.rect.move_ip (self.vel)
      self.updaterot()
      
   def updaterot (self):
      self.oldCenter = self.rect.center
      self.image = pygame.transform.rotate ( self.image_original, - self.angle)
      self.rect = self.image.get_rect()
      self.rect.center = self.oldCenter


def main():
   pygame.init()
   screen = pygame.display.set_mode((1000,1000))
   clock = pygame.time.Clock()
   cochesprite = pygame.sprite.RenderClear()
   cochei = coche((500, 500))
   cochesprite.add (cochei)

   while 1:
      # *AUNQUE LO PONGA AQUI NO FUNCIONA COMO QUIERO
      
      #for event in pygame.event.get():
      #   if event.type == QUIT:
      #      sys.exit()
      #   if event.type == KEYDOWN:
      #      if event.key == K_LEFT:
      #         cochei.angle -= 10
      #         
      #      elif event.key == K_RIGHT:
      #         cochei.angle += 10
               
      
      # *ESTA PARTE NO RESPONDE A LAS TECLAS
      
      #key = pygame.key.get_pressed()
      #if key[K_LEFT]:
      #   cochei.angle += 10
      #elif key[K_RIGHT]:
      #   cochei.angle -= 10
            
      cochesprite.update()
      
      screen.fill((0, 0, 0))
      cochesprite.draw (screen)
      pygame.display.update()
      clock.tick(60)

if __name__ == '__main__': main()
Última edición por endaramiz el Vie Ago 31, 2007 2:53 pm, editado 1 vez en total
Avatar de Usuario
endaramiz
 
Mensajes: 283
Registrado: Vie Ago 31, 2007 9:25 am
Ubicación: Barcelona

error de presentación

Notapor endaramiz » Vie Ago 31, 2007 10:43 am

no se que ha pasado pero al enviar el mensaje no me ha reconocido la tabulación. :?
He visto cosas escritas en recuadros de esa manera se vería bien? En caso afirmativo alguien me podria decir como se hace?

Saludos.
Avatar de Usuario
endaramiz
 
Mensajes: 283
Registrado: Vie Ago 31, 2007 9:25 am
Ubicación: Barcelona

Re: error de presentación

Notapor hugoruscitti » Vie Ago 31, 2007 2:16 pm

dvd escribió:no se que ha pasado pero al enviar el mensaje no me ha reconocido la tabulación. :?
He visto cosas escritas en recuadros de esa manera se vería bien? En caso afirmativo alguien me podria decir como se hace?

Saludos.


Puedes escribir el código fuente de tus programas en el
foro utilizando la etiqueta "code". Es decir, debes colocar
tu código entre dos etiquetas "code". Con respecto a tu
inquietud, intentaré responder esta tarde. ¿Podrías editar
el código para observarlo tabulado? (en python tabular es
parte de la sintaxis).

Gracias.
Avatar de Usuario
hugoruscitti
Site Admin
 
Mensajes: 1242
Registrado: Dom Jul 30, 2006 3:57 am
Ubicación: Buenos Aires, Argentina

Notapor endaramiz » Vie Ago 31, 2007 3:02 pm

Ya he editado el otro mensaje, ha sustituido el tabulado por una distancia menor pero se puede leer igualmente. Gracias por la información :D (no estoy muy acostumbrado a eso de escribir en los foros, yo soy mas de leer)

Saludos.
Avatar de Usuario
endaramiz
 
Mensajes: 283
Registrado: Vie Ago 31, 2007 9:25 am
Ubicación: Barcelona

Notapor hugoruscitti » Sab Sep 01, 2007 4:54 am

Saludos. Te comento que pude ver del programa que has publicado y
econtré donde se puede hacer una modificación para corregir el
detalle que mencionas.

Existen dos formas interpretar la pulsación de teclas en pygame: mediante
eventos y mediante la función "pygame.key.get()"

Si utilizas eventos, la función "pygame.event.get()" reportará la
pulsación de teclas en el mismo instante que ocurren, pero sin
señalar repeticiones. Por ejemplo, si dejas pulsada una
tecla durante 3 segundos y luego la sueltas, "pygame.event.get()"
reportará el evento "KEYDOWN" una sola vez y luego de 3 segundos
el evento "KEYUP" (cuando sueltes la tecla).

Generalmente en los juegos de acción este comportamiento no resulta
muy útil, en el caso de tu juego sería ideal que al pulsar una
tecla como "izquierda" el tanque se mantenga en rotación
constante (como si pulsaras y soltaras la tecla muchas veces y muy
rápido).

Para estos se puede utilizar la función "pygame.key.get_pressed()",
que devuelve una lista con el estado de cada tecla en el instante
actual.

Nota que la forma correcta de utilizar esta función consiste en capturar
la lista que retorna y luego consultar alguna de sus posiciones:

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

if teclas[K_LEFT]:
    girar(-1)
elif teclas[K_RIGHT]:
    girar(+1)


Creo que tu código anterior no funciona como esperabas a causa de esto,
recuerda que la función "get_pressed()" retorna una lista. Veamos el
código:

Código: Seleccionar todo
def update (self):
#   *ESTA PARTE NO ME RESPONDE
#   key = pygame.key.get_pressed()
#   if key == [K_LEFT]:
#      self.angle -= 10
# ...


Nota que la linea "if key == [K_LEFT]:" estaría comparando una lista
completa con una lista constante que solo tiene al elemento K_LEFT.

Intenta cambiar esa parte del código por lo siguiente:

Código: Seleccionar todo
def update (self):
   key = pygame.key.get_pressed()

   if key[K_LEFT]:
      self.angle -= 10
   elif key[K_RIGHT]:
      self.angle += 10
   
   if key[K_UP]:
      angle = radians(self.angle)
      self.vel[0] = cos(angle) * 7
      self.vel[1] = sin(angle) * 7
   else:
      self.vel = [0,0]


Probé lo anterior y me funcionó como querías, no necesité cambiar nada
mas. Ahora se pude mover el 'tanque' mientras uno avanza, o simplemente
dar giros en el mismo lugar. Al parecer el inconveniente solo estaba ahí.

Ante cualquier otra inquietud esperamos tu mensaje, desde
aquí también valoramos mucho tu tiempo.

¡Saludos y buena suerte el juego!
Avatar de Usuario
hugoruscitti
Site Admin
 
Mensajes: 1242
Registrado: Dom Jul 30, 2006 3:57 am
Ubicación: Buenos Aires, Argentina

solucionado!!

Notapor endaramiz » Sab Sep 01, 2007 6:00 pm

:D muchas gracias por tus explicaciones, me han sido de gran utilidad para comprender un poquito mas el funcionamiento de pygame.
El caso es que utilizando la función pygame.key.get_pressed() de la manera que me has comentado seguía sin funcionarme. A sido un momento muy duro para mi pero he decidido seguir investigando y he puesto "print key" debajo de la linea "key = pygame.key.get_pressed()" (en el codigo sin comillas) y he comprobado que al pulsar las teclas no cambiaba "key", solo salia un 1 en la posición que he descubierto que era del "bloq mayus" y "bloq num" las cuales estaban activadas al iniciar el programa. Me puesto a comparar con el ejemplo "car" y se me ha ocurrido hacer una especie de engine y si que ha funcionado. la diferencia está en que en el engine he puesto un gestor (no se si la palabra es correcta) de evento para la tecla salir.

Para que funcione de la manera que deseaba el código de antes, a parte de quitar los "==" que has comentado, solo hace falta quitar los 3 primeros "#" después del comentario de debajo del "while 1:"
Código: Seleccionar todo
   while 1:
      for event in pygame.event.get():
         if event.type == QUIT:
            sys.exit()

No se como funciona exactamente pero es como si gracias al "for event in pygame.event.get()" se actualizase el "key = pygame.key.get_pressed()" :?

En los momentos de alegría después de verlo funcionar me acordé de las palabras que me dijo un profesor: el mirarse unos ejercicios y entenderlos no es de gran ayuda cuando mas se aprende es cuando haces un ejercicio, te sale mal, buscas el error y lo resuelves.
Aunque haya resuelto la duda seguiré pasando por esta web que me ha parecido muy interesante y espero que algún día yo también pueda resolver dudas.

gracias!
Avatar de Usuario
endaramiz
 
Mensajes: 283
Registrado: Vie Ago 31, 2007 9:25 am
Ubicación: Barcelona

Re: solucionado!!

Notapor hugoruscitti » Sab Sep 01, 2007 7:06 pm

dvd escribió:No se como funciona exactamente pero es como si gracias al "for event in pygame.event.get()" se actualizase el "key = pygame.key.get_pressed()" :?


Es cierto, no lo había notado. Al parecer, por los comentarios
que aparecen en la documentación de pygame:

http://www.pygame.org/docs/ref/key.html ... et_pressed
(pulsar en el botón verde que indica "comments")

la función "pygame.key.get_pressed()" solo devuelve el mapa de
teclado completo que se actualiza llamando a "event.get()" o
"event.pump()". Si se llama muchas veces a "key.get_update()" sin
actualizar la cola de eventos se obtendrá siempre la misma lista. Que
bueno, no lo sabía y con tu mensaje aprendí algo nuevo...

dvd escribió:En los momentos de alegría después de verlo funcionar me acordé de las palabras que me dijo un profesor: el mirarse unos ejercicios y entenderlos no es de gran ayuda cuando mas se aprende es cuando haces un ejercicio, te sale mal, buscas el error y lo resuelves.


Es cierto, tiene mucha razón. Es la mejor forma de aprender.

dvd escribió:Aunque haya resuelto la duda seguiré pasando por esta web que me ha parecido muy interesante y espero que algún día yo también pueda resolver dudas.


Copado, las consultas también ayudan mucho, en este caso pudimos
investigar un poco mas sobre el manejo de teclas en pygame.

Gracias a tí, que tengas buena suerte. Un saludo.
Avatar de Usuario
hugoruscitti
Site Admin
 
Mensajes: 1242
Registrado: Dom Jul 30, 2006 3:57 am
Ubicación: Buenos Aires, Argentina


Volver a Ejemplos

¿Quién está conectado?

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