:: Program till the end ::

Resultados para etiqueta "kbhit"

Publicado: 21:25 04/07/2007 · Etiquetas: tutorial, teclas, programacion, c, c++, getch, kbhit, cosa facil · Categorías: Informática
Dado que me lo pidieron hace tiempo en la entrada sobre mi particular versión del juego de Snake (no confundir con Metal Gear ), que hice tras mi primer año de carrera, pondré un sencillo tutorial para entenderse un poco con la gestión de las teclas en un programa C simple. No es nada complejo ni es la mejor forma de hacer las cosas, pero para quien está empezando o tenga dudas de cómo hacerlo, puede ser útil. Eso sí, debo aclarar que los ejemplos que vamos a ver, son para MS-DOS / Windows. En Linux alguna cosa puede ser diferente.

El punto de partida es: estamos haciendo un programa o juego sencillo con C/C++, y queremos capturar teclas que el usuario pulse. En principio uno pensaría en scanf o cin>>, que sirven para entrada de datos, pero no sirven, dado que éstos, esperan que se escriba algún dato para luego pulsar Enter. Aquí lo que nos interesa es que el programa sepa de inmediato que se ha pulsado una tecla (como puede ser una tecla de dirección), e identificar cuál.

Para casos como este, hay que tener el código ASCII a mano:


Pincha sobre la imagen para verla más grande

Recordad que el código ASCII tiene algunas variantes, por lo que no todos los códigos ASCII que encontréis serán iguales. Pero para usar unos pocos caracteres no suele dar problemas. Los 32 primeros caracteres son no imprimibles... en según qué casos. Se usan como caracteres de control (por ejemplo, salto de línea), aunque también tienen dibujitos asociados y dependiendo del lugar donde se usen, se pintará el dibujo o se realizará la acción asociada.

Otra particularidad es que hay teclas que comparten el código... como es el caso de las teclas de dirección. Éstas no están señaladas en ninguna tabla ASCII que haya visto. Hay que averiguar cómo referirse a estas teclas (para las teclas imprimibles, como la letra a, basta con usar la propia letra con comillas simples: 'a').

Trabajando con una buena librería o herramienta de gestión de eventos, no sería necesario preocuparse por el código ASCII, porque en esos casos normalmente toda tecla o carácter tiene su correspondiente etiqueta asociada (por ejemplo, KEY_LEFT para referirse a la tecla de dirección izquierda). Suponiendo que no es así, que estamos con C/C++ "a pelo" y sin ningún tipo de ayuda como la comentada, tendremos que definir nosotros mismos esas etiquetas. Pasamos a la acción.

1- Cómo averiguar empíricamente el código de una tecla

Para ello podemos hacer un programa sencillo que nos permita averiguarlo:

------------------------------------------------

#include <conio.h> //Para getch
#include <stdio.h> //Para printf

int main(){
char tecla;

printf("Pulsa la tecla de la que quieres conocer su codigo: ");
tecla = getch();

printf("\nEl codigo de la tecla pulsada es: %d\n",tecla);

return 0;
}

------------------------------------------------

Explicación: getch captura una tecla y la devuelve, pudiendo almacenar el código en una variable, como hacemos en este programa. Después, interpretamos como una variable entera a tecla usando el código %d para imprimirla, de modo que vemos su código numérico que es lo que nos interesa.

A continuación lo compilamos. Si el archivo es ascii.c, podemos hacer:

gcc -Wall ascii.c -o ascii.exe

si tenemos gcc, o del modo que sea si usamos otra herramienta.

Cuando lo ejecutemos, y pulsemos por ejemplo la tecla de dirección izquierda, es posible que obtengamos esta salida:

Pulsa la tecla de la que quieres conocer su codigo:
El codigo de la tecla pulsada es: 0


Eso NO quiere decir que el código de la tecla sea 0. El problema es que getch coge caracteres del buffer de teclado y a veces (particularmente cuando la tecla pulsada es una de dirección), se cuela alguno que no debe, por decirlo de forma más o menos sencilla . Pero si lo volvemos a ejecutar obtenemos la salida correcta. Tras algunas ejecuciones, vemos que los códigos son como sigue:

- Tecla de dirección arriba: 72
- Tecla de dirección izquierda: 75
- Tecla de dirección derecha: 77
- Tecla de dirección abajo: 80

Con lo que en el programa que estamos haciendo, podemos añadir al principio estas líneas:

#define KEY_UP 72
#define KEY_LEFT 75
#define KEY_RIGHT 77
#define KEY_DOWN 80

Y ya podemos usar estas etiquetas en lugar de los códigos ASCII en el resto del programa.

2- Captura de teclas en programas dinámicos

Ya hemos visto cómo capturar una tecla en un caso en el que el programa espera a que se pulse alguna, pero ¿y si queremos que el programa esté procesando o haciendo cualquier actividad aunque no se pulsen teclas? Por ejemplo en el juego de la serpiente: las serpientes se mueven aunque ningún usuario pulse ninguna tecla. Necesitamos algo que nos diga cuándo se pulsa una tecla. No se puede ejecutar getch() salvo que sepamos que el usuario ha pulsado una tecla y por lo tanto el programa no va a quedarse bloqueado. La solución (en MS-DOS / Windows) es la función kbhit(), también incluida en conio.h. Esta función se usa del siguiente modo:

------------------------------------------------

...

#define KEY_ESC 27
...

tecla = KEY_RIGHT; //Inicializamos

do{

...
//Procesamos
...

if(kbhit())
tecla = getch();
} while(tecla != KEY_ESC);

------------------------------------------------

Explicación: se suponen definidas las etiquetas para las teclas. En este código, se inicializa la tecla a "derecha", como si el usuario hubiese pulsado ya "derecha". A continuación itera en función de esa variable y posiblemente otros datos hasta que el usuario pulse Esc (el código de la tecla Esc es 27, lo podéis comprobar con el programa que vimos antes). La función kbhit devuelve true si el usuario ha pulsado una tecla, o false en caso contrario. Lo que quiere decir, que el programa seguirá iterando sin ejecutar getch hasta que el usuario pulse alguna tecla, que será capturada de inmediato (cuando termine la iteración en curso).

Debo indicar que kbhit en según qué implementaciones (compilador usado) puede no funcionar del todo bien y, por ejemplo, provocar un ligero parón, haciendo que se ralentice el programa por un instante en el momento en que el usuario ha pulsado una tecla. Como digo, depende del compilador usado.

En cualquier caso, esta forma de implementar no es la más elegante ni la más recomendable. Por ejemplo, no funcionará bien si se pulsan varias teclas a la vez, o se mantiene pulsada alguna. Es más recomendable disponer de algún mecanismo de gestión de eventos, de forma que el programa trabaje "a su bola" y cuando se pulse alguna tecla, simplemente se le avise para que atienda la pulsación, sin tener que hacer continuas comprobaciones. Pero en casos sencillos (como el juego que puse aquí), puede valer.

Quien tenga alguna duda sobre lo expuesto o cualquier otra cosa, que me lo haga saber con un comentario .


:: Program till the end ::

Blog de maxter2001
I program till the end, for my purposes. What about you? [Blog de OK-River (maxter2001 en Vandal)]

Posts destacados por el autor:
· "Hola, mundo!" con Qt
· Odisea en busca de una PS3 de 60 GB, finalizada
· [Proyecto Fin de Carrera] Vídeo demostración + Capturas + Info
· Ingeniería Informática acabada
· [Proyecto Fin de Carrera] Capturas e info
· Programación: Tutorial para manejo de teclas
· The Legend Of Zelda: Twilight Princess terminado: impresiones/análisis
· Final Fantasy X - To Zanarkand (directo)
· Dichosas comparaciones atenuantes
· Juego para descargar: La Bicha 2.0
· Metal Gear Online "impresionado"
· Estreno



Vídeos:
· Música orquestada
· Variados
· Música variada
· El Informal
· Juegos
· Humoristas españoles



Blogs amigos:
alw
ArKiTo
Arxel
Boddhai
Clone
ComIkari
Cornell
De-mon
delojo
EASMO
erizoazul
Ferr
GeRoxx
Granlutz
HWY2HELL
Isnard
Jimmytrius
Kanevsky
Kiriyama
Modo_7
nach
Naruto
NeoYoshimitsu
NoPLo
Resident Hill
RojoRedRouge
Shino-Kun
Sonny Chiba
Sr.A
suzumiya haruhi
vacajinjo
xispax_
Zeroshcr
ZZGRST
_-Sheik-_


Categorías:
Chorradillas
Hablar con propiedad no cuesta un puto duro
Informática
Manga/Anime/Dorama
Música
Personal
Regalos pal hocico
Tutoriales
Varios
Videojuegos


Archivo:
Octubre 2009
Septiembre 2009
Enero 2009
Septiembre 2008
Agosto 2008
Junio 2008
Mayo 2008
Abril 2008
Marzo 2008
Febrero 2008
Enero 2008
Diciembre 2007
Noviembre 2007
Octubre 2007
Septiembre 2007
Agosto 2007
Julio 2007
Junio 2007
Mayo 2007
Abril 2007
Marzo 2007
Febrero 2007
Enero 2007
Diciembre 2006
Noviembre 2006
Octubre 2006


Vandal Online:
Portada
Blogs
Foro

Blogs en Vandal · Contacto · Denunciar Contenido