Iniciar sesión

Ver la versión completa : Duda: diferencias entre usar SDL_PollEvent y SDL_GetKeyState



miq01
20/03/2006, 19:09
Hola.

Estaba leyendo esto (http://lazyfooproductions.com/SDL_tutorials/lesson20/index.php) donde habla de una manera alternativa de detectar pulsaciones de teclado (y quien dice teclado, dice joystick).

En lugar de utilizar eventos para detectar pulsaciones de teclado utiliza "keystates". Eso lo tengo claro, pero a efectos prácticos, ¿qué diferencia hay entre usar uno y otro? ¿Alguno es más óptimo que el otro?

Arcnor
20/03/2006, 19:32
Hombre, teniendo en cuenta mi "basta" (si, con B [wei5]) expeciencia, te diré que no me hagas mucho caso. Pero vamos, la diferencia es obvia: con el GetKeyState obtienes un array y lo analizas tú "a mano" (como se hacía antiguamente) y con el PollEvent te dice únicamente la tecla pulsada cada vez, evento por evento.

Yo creo que es mejor usar los eventos, pero el array podría servirte para el caso en el que pases de los eventos y quieras saber que tecla se pulsa sólo una vez cada 3,14 segundos, o solo en alguna parte de tu código, etc... Como siempre, las aplicaciones prácticas dependen del caso en el que lo apliques

Disculpa la longitud de la respuesta y si he dicho muchas tonterías [Ahhh]

Eskema
20/03/2006, 19:32
Que yo sepa es debido a q algunos sistemas no estan preparados para el sistema de colas(eventos) con lo cual has de hacerlo a base de keystates.
Si el sistema sobre el q trabajas soporta los eventos, es una mera cuestion de gustos supongo. Yo tengo partes con eventos y partes con keystates directos.

miq01
20/03/2006, 19:57
Gracias a los dos.

Arcnor, es que yo siempre he tirado de SDL_PollEvent y luego lleno un array (o lo menos óptimo del mundo: booleanos que me indican si la tecla está pulsada o no). Vamos, que por lo que veo, hago exactamente lo mismo que con GetKeyState, pero con mis estructuras de datos.

Lo que pasa es que la consola, desde le punto de vista de SDL, no va con teclas sino con joystick y el equivalente a GetKeyState (que como bien dice Arcnor devuelve un array) no existe para joystick, o no lo encuentro. Lo más cercano es SDL_JoystickGetButton, que te dice si UN botón está o no pulsado.

Uncanny
20/03/2006, 19:58
Te diré su utilidad bajo mi punto de vista, digamos Miq que el optar usar uno u otro es por la "complejidad" de lo que quieras hacer.

Si usas SDL_GetKeyState() te servirá solo para saber que y si se ha pulsado una tecla, pues esa función devuelve un puntero con valor 1 o 0 que nosotros lo usamos para controlar luego en alguna estructura condicional si una determinada tecla se ha pulsado para que haga algo, como incremeentar o decrementar una variable que corresponda al movimiento del personaje simplemente.

Luego está el tema de los eventos. SDL controla la cola de eventos y esta cola pilla casi todos los eventos que se produzcan en el sistema, pudiendo controlar el tipo de evento ante el que queremos reaccionar de una manera determinada. Aquí se usan varias estructuras, por ejemplo con el teclado está SDL_KeyboardEvent que almacena el "estado" de la tecla (por cierto, por duplicado) que a su vez hace uso de la estructura SDL_keysym que es la que da la información real de que tecla se presionó el caracter o simbolo al que representa.

Al grano, la diferencia principal está en el "estado" de la tecla o botón, con SDL_GetKeyState() solo podrás si se ha pulsado una tecla y que tecla es, ni más ni menos, es util y rapido si no quieres controlar nada más, es hacer lo mismo que con un bucle que contenga una estructura de control condicional, tipo switch, usando scanf() o cin para que haga algo cuando se pulse una determinada tecla. Si por el contrario controlas los eventos de teclado (por ejemplo), tienes más información para controlar y usar como te de la gana, pues además de saber que tecla se ha pulsado también puedes saber su estado actual, si está presionada ahora mismo (SDL_KEYDOWN) o si se ha dejado de pulsar (SDL_KEYUP) en este instante, ¿para que puede ser util? pues imagina que tu personaje con el boton X dispara solo MIENTRAS la tecla X se deja de pulsar rapidamente (SDL_KEYDOWN durante menos de un segundo y al ver que se produce un SDL_KEYUP en este periodo de tiempo realiza el disparo simple), pero que si está pulsada durante más de un segundo el personaje acumula energía en el cañón protonico (se me va la pinza xDD) y al levantarla dispara un rayo del copon que frie a to diox en la pantalla... ¿util los eventos no? :D

Arcnor
20/03/2006, 20:28
Si por el contrario controlas los eventos de teclado (por ejemplo), tienes más información para controlar y usar como te de la gana, pues además de saber que tecla se ha pulsado también puedes saber su estado actual, si está presionada ahora mismo (SDL_KEYDOWN) o si se ha dejado de pulsar (SDL_KEYUP) en este instante, ¿para que puede ser util? pues imagina que tu personaje con el boton X dispara solo MIENTRAS la tecla X se deja de pulsar rapidamente (SDL_KEYDOWN durante menos de un segundo y al ver que se produce un SDL_KEYUP en este periodo de tiempo realiza el disparo simple), pero que si está pulsada durante más de un segundo el personaje acumula energía en el cañón protonico (se me va la pinza xDD) y al levantarla dispara un rayo del copon que frie a to diox en la pantalla... ¿util los eventos no? :D

Cierto, maestro ;) Se me olvidaba también la utilidad obvia de saber el momento de la pulsación y "depulsación" (OLÉ :[wei5]). Es que esto de responder desde el trabajo me frie un poco las neuronas :confused: Aquí solo tengo hueco para pensar en GTK, SQL y Delphi, y me estoy volviendo un poco :loco: :D

miq01
20/03/2006, 21:09
Gracias Uncanny.


imagina que tu personaje con el boton X dispara solo MIENTRAS la tecla X se deja de pulsar rapidamente (SDL_KEYDOWN durante menos de un segundo y al ver que se produce un SDL_KEYUP en este periodo de tiempo realiza el disparo simple), pero que si está pulsada durante más de un segundo el personaje acumula energía en el cañón protonico (se me va la pinza xDD) y al levantarla dispara un rayo del copon que frie a to diox en la pantalla... ¿util los eventos no? :D
Pero eso se puede hacer también leyendo el estado, ¿no? Supongamos que tenemos una variable que nos dice si la tecla X está pulsada (1) o no (0), resultado de una llamada a SDL_KeyState, y que cada vez que se empieza a pulsar (no siempre, sólo la primera vez después de un 0) se almacenan los milisegundos. Entonces, si después de tener unos cuantos 1s pasamos a tener un 0, basta con saber cual es la distancia temporal, y decidir si se dispara "normal" o con el supercañón de protones arrasa-con-todo. :)

Vaya, que por lo que veo con SDL_KEYDOWN y SDL_KEYUP te ahorras el detectar si es la primera vez o la decimocuarta.

Arcnor
20/03/2006, 21:15
Gracias Uncanny.


Pero eso se puede hacer también leyendo el estado, ¿no? Supongamos que tenemos una variable que nos dice si la tecla X está pulsada (1) o no (0), resultado de una llamada a SDL_KeyState, y que cada vez que se empieza a pulsar (no siempre, sólo la primera vez después de un 0) se almacenan los milisegundos. Entonces, si después de tener unos cuantos 1s pasamos a tener un 0, basta con saber cual es la distancia temporal, y decidir si se dispara "normal" o con el supercañón de protones arrasa-con-todo. :)

Vaya, que por lo que veo con SDL_KEYDOWN y SDL_KEYUP te ahorras el detectar si es la primera vez o la decimocuarta.

Y además para saber si es la primera vez después de un 0 deberás tener el estado actual y el estado anterior, con lo que tendrías 2 arrays y el consiguiente gasto de memoria / velocidad / tiempo / neuronas / etc [wei5] (Bueno, o comprobar que es un 1 y que aún no se ha empezado a contar. Vale, aceptamos barco, pero aún así es un coñazo :D)

Uncanny
20/03/2006, 22:25
Gracias Uncanny.


Pero eso se puede hacer también leyendo el estado, ¿no? Supongamos que tenemos una variable que nos dice si la tecla X está pulsada (1) o no (0), resultado de una llamada a SDL_KeyState, y que cada vez que se empieza a pulsar (no siempre, sólo la primera vez después de un 0) se almacenan los milisegundos. Entonces, si después de tener unos cuantos 1s pasamos a tener un 0, basta con saber cual es la distancia temporal, y decidir si se dispara "normal" o con el supercañón de protones arrasa-con-todo. :)

Vaya, que por lo que veo con SDL_KEYDOWN y SDL_KEYUP te ahorras el detectar si es la primera vez o la decimocuarta.Es como has dicho en el último parrafo y como bien te informa Arcnor :)

De otra forma tendrías que hacer como dices, lo del disparo no tiene misterio, controlando que se pulsa un determinado botón lanzas el disparo normal, pero a la hora de querer dar caña a todo bicho viviente en la pantalla con el cañón protonico, te toca calcular cuando se pulsó una determinada tecla y con una variable que haga las veces de contador temporar, ponerte a controlar y realizar una acción basandose condicionalmente si detectas que el valor de la tecla anteriormente pulsada pulsada (valor 1) ahora se ha dejado de pulsar (valor 0) y el contador ha igualadao o superado el tiempo que estableces para que lo interprete como acumulación de energia para usar disparar el cañón y no un simple disparo [Ahhh]

Visto de esta forma, que hasta me he hecho la picha un lio imaginandolo ¿porque currarse una forma de almacenar los estados y detectarlo si SDL te proporciona los mecanismos, las estructuras y las funciones necesarias para todo ese jaleo? Ley del mínimo esfuerzo y reutilización de código, si existe y funciona pos se usa :D

Arcnor
20/03/2006, 22:34
Tal como dice Uncanny, mejor no liarse cuando ya están los mecanismos y funcionan bien, aunque siempre nos guste rizar el rizo para ver si las cosas son mejorables, eso es bueno ;). Además se me ocurre pensar que si para no usar los 2 arrays usas la comrobación de "tecla pulsada y temporizador a 0, entonces se acaba de pulsar" sólo puedes hacer esto con 1 tecla, por lo que estaría chunga la cosa [wei5].

Bueno, creo que ya le hemos sacado todo el jugo que da de si el tema de los PollEvents. Si queréis empezamos con threading [wei4][Ahhh]:loco::D

miq01
20/03/2006, 22:51
Jeje... Gracias a todos.

SilentSei
20/03/2006, 23:27
Y no sería posible utilizar una combinación de los 2??

Arcnor
20/03/2006, 23:31
Poderse, claro que se puede. La utilidad ya sería otra cosa.

Podrías usar los eventos para detectar la pulsación de la tecla P y cuando esto ocurra, mostrar en pantalla un listado de todas las teclas pulsadas en ese momento usando el array que devuelve GetKeyState...

Ya te digo, todo depende de para qué lo quieras usar. Yo en mi caso siempre he usado los eventos, ya que con esos voy más que servido y me dan más información

SilentSei
21/03/2006, 00:10
Poderse, claro que se puede. La utilidad ya sería otra cosa.

Podrías usar los eventos para detectar la pulsación de la tecla P y cuando esto ocurra, mostrar en pantalla un listado de todas las teclas pulsadas en ese momento usando el array que devuelve GetKeyState...

Ya te digo, todo depende de para qué lo quieras usar. Yo en mi caso siempre he usado los eventos, ya que con esos voy más que servido y me dan más información

Habría que pensar de que manera puede beneficiarnos...pero se puede tessoro, ssse puede!!!