|
|
Artículo realizado por
Juan Antonio Medina "mICRO"
Como programar multiples controles y respuestas para varios jugadores simultaneos
Muchas veces en nuestros juegos deberemos de controlar simultáneamente el control de varios jugadores que pueden a la vez usar varios medios, por ejemplo un jugador podría usar teclas + joystick y otro solo teclas, en algunos casos esto se puede volver demasiado complicado, para clarificar este tema este articulo usara el método del CONTROL y la RESPUESTA que nos permitirá fácilmente tener el control de varios jugadores y los medios que usen además también nos permitirá un fácil control de lo que quiere hacer en jugador sin importar que lo haga con teclado o con Joystick. Este articulo es a nivel básico y solo quiere ser una aclaración en el tema, se recomienda al lector del mismo que implemente su propio sistema de control y respuesta mas adecuado para su juego ya que este puede que sea un poco básico.
CONTROL
En control es donde definiremos como va el jugador a controlar la acción en el juego, indicaremos si va a usar joystick o teclado o las teclas que usara entre otras cosas, esta información será necesaria para luego generar una respuesta acorde con el control dado.
Para ello introduciremos la información en un struct de c:
// PRINCIPIO DE CODIGO EN C
// Estructura para alojar la definicion del control de un Jugador
typedef struct {
} ___control;
//FIN DE CODIGO EN C
Un ejemplo podría ser este en el que se asignan los valores para dos controles:
//PRINCIPIO DE CODIGO EN C
___control control1;
___control control2;
control1.joystick = 1; // Primer Joystick que este conectado en el sistema
control1.teclado = 1; // Tambien usaremos el teclado
control1.ar = VK_UP; // Tecla de arriba (WIN 32 VK_KEYCODES)
control1.ab = VK_DOWN; // Tecla de abajo (WIN 32 VK_KEYCODES)
control1.iz = VK_LEFT; // Tecla de izquierda (WIN 32 VK_KEYCODES)
control1.de = VK_RIGHT; // Tecla de derecha (WIN 32 VK_KEYCODES)
control1.f1 = VK_ALT; // Tecla para el Boton 1 (WIN 32 VK_KEYCODES)
control1.f2 = VK_RSHIFT; // Tecla para el Boton 2 (WIN 32 VK_KEYCODES)
control2.joystick = 0; // No usaremos Joystick
control2.teclado = 1; // Usaremos el teclado
control2.ar = VK_W; // Tecla de arriba (WIN 32 VK_KEYCODES)
control2.ab = VK_S; // Tecla de abajo (WIN 32 VK_KEYCODES)
control2.iz = VK_A; // Tecla de izquierda (WIN 32 VK_KEYCODES)
control2.de = VK_D; // Tecla de derecha (WIN 32 VK_KEYCODES)
control2.f1 = VK_F; // Tecla para el Boton 1 (WIN 32 VK_KEYCODES)
control2.f2 = VK_G; // Tecla para el Boton 2 (WIN 32 VK_KEYCODES)
//FIN DE CODIGO EN C
RESPUESTA
La respuesta es el resultado de procesar el control del jugador, en ella reflejaremos que es lo que el jugador quiere hacer independientemente de con que lo haga, es lo que tendremos que mirar para reflejar en el juego, de esta manera conseguiremos que el control del juego sea igual con teclado o joystick por ejemplo, para esto también usaremos un struct de c:
//PRINCIPIO DE CODIGO EN C
//Estructura para reflejar la respuesta segun el control
typedef struct {
Diferencias entre f1,f2 y act1,act2:
f1 y f2 reflejan simplemente cuando esta el botón pulsado o sea, cuando el jugador lo pulsa, seguirá valiendo distinto de 0 hasta que lo suelte, en cambio act1 y act2 valdrán distinto de 0 solo una vez cuando se pulse el botón y luego valdrá 0 hasta que el jugador lo suelte y lo vuelva a pulsar, para que esto, pues sencillo en algunos juegos, como pueden ser de naves, queremos que el jugador tenga autofire o no, pues en cada caso usaremos una o las otras variables, para que el jugador tenga que dejar pulsado la tecla de fuego o l tenga que ir pulsado y soltando cada vez.
Antes de seguir deberemos saber leer esos controles (teclado y joystick), para ello vamos a usar funciones estándar de WIN 32 y no direct-x para hacerlo a si mas fácil y a la vez para que se puedan usar en cualquier proyecto incluso los que no usan direct-x.
COMO LEER TODO EL TECLADO EN WIN 32
Win 32 provee una fácil manera de leer en cualquier momento todo el estado del teclado, con la función del api:
BOOL GetKeyboardState(PBYTE
lpKeyState);lpKeyState
Puntero a un vector de bytes de 256 de tamaño que recibirá el estado de las teclas para cada una de las "virtual keys".
Devuelve no cero si funciona o cero si no.
Para leer el teclado solamente tendremos que crear un array para contener el resultado de esa función y un par de funciones para usarlo.
//FUNCIONES DE TECLADO WIN-32
//Simplemente inicialza el vector, debe de ser llamada al principio del juego
void InitKey()
{
//Actualiza el vector, debe ser llamada una vez por ciclo de juego
void leeteclas()
{
COMO USAR EL JOYSTICK EN WIN-32
Usar el JOYSTICK en win-32 es casi tan fácil como usar el teclado para ello en el api hay las siguientes estructuras de datos y funciones:
//Estructura definida en el WIN 32 API para sacar info de un joystick
typedef struct joycaps_tag {UINT wPeriodMin; // Intervalos para el Joystick Capturado UINT wPeriodMax; // Intervalos para el Joystick Capturado } JOYCAPS; //Estructura definida en el WIN 32 API para sacar la posicion de un Joystick typedef struct joyinfo_tag {
UINT joyGetNumDevs(VOID);
Esta función devuelve el numero de Joystick conectados al sistema 0 si no hay ninguno
MMRESULT joyGetDevCaps(uJoyID
El ID del joystick que queremos obtener sus capacidades.
pjc
Un puntero a una estructura JOYCAPS que será rellenada por esta función
cbjc
El tamaño del pjc
Esta función devuelve distinto de 0 si funciona y rellena la información pedida en la estructura JOYCAPS dada.
MMRESULT joyGetPos(uJoyID
El ID del Joystic que queremos conocer su posición actual
pji
puntero a una estructura JOYINFO que será rellenada por esta función.
Esta función devuelve la posición de un joystick y valor distinto de 0 si todo va bien.
Para manejar todo esto utilizaremos las siguientes funcione y estructuras:
//COMIENZO DE CODIGO EN C
UINT NJOYSTICKS; //Nº de joysticks conectados o no
UINT NJOYSTICKSPLUG; //Nº de joysticks conectados
JOYCAPS joycaps; //Capacidades del joystick
//Valores para determinar los movimientos del joystick
//Este structura la usaremos para crear un array con los joystick que hay en
//en el sistema independientemente de cuales sea sus ID
typedef struct {
//Array con todos los joystick conectados
//o sea cuando en el control decimos que el joystick es igual a 1
//nos referimos a que es el primero conectado independientemente de su ID
//si decimos que es el 2 es el segundo etc, si desconectamos algun,
//de esta manera es mas facil cuando en juego se quiere usar joystick (el primero)
//sin importar cual sea
#define maxjoys 10
//Aqui miramos la estructura joycaps para calcular los maximos y los
//minimos de los potenciometros, y dividiendo averiguamos a partir
//de que cordenada consideramos que es un movimiento
//que sera cuando la palanca pase la mitad de la distancia de uno de los
//ejes y su maximo o sea, cuando movamos el joystick a la derecha
//se considerarar derecha cuando la palanca pase la mitada entre el
//centro y el maximo a la derecha.
signed int mx=(joycaps.wXmax+joycaps.wXmin)/2;
signed int my=(joycaps.wYmax+joycaps.wYmin)/2;
joyvalue[NJOYSTICKSPLUG+1].JDER=(mx+joycaps.wXmax)/2;
joyvalue[NJOYSTICKSPLUG+1].JIZQ=(mx+joycaps.wXmin)/2;
joyvalue[NJOYSTICKSPLUG+1].JARR=(my+joycaps.wYmin)/2;
joyvalue[NJOYSTICKSPLUG+1].JABA=(my+joycaps.wYmax)/2;
COMO TRANSFORMAR UN CONTROL EN UNA RESPUESTA
La idea es fácil, crearemos una función que se encarga de esa tarea, que procese el teclado y el joystick dado, el joystick que nosotros tengamos asignados en control y que al final rellene la estructura respuesta. La tendremos que llamar para cada control y respuesta que deseemos usar, además antes de usarla tendremos que llamar a las funciones de inicialización de joystick y teclado, también una vez por ciclo a la función de actualización del teclado.
//COMIENZO DE CODIGO EN C
//Esta funcion transforma un control en respuesta y devuelve distinto de 0
//Si usamos joystick y es valido
if( ((control.joystick)!=0)&&(joyvalue[control.joystick].Ajustado==1) ){
//analogico
(respuesta.xmax)=joyvalue[control.joystick].xmax;
(respuesta.xmin)=joyvalue[control.joystick].xmin;
(respuesta.ymax)=joyvalue[control.joystick].ymax;
(respuesta.ymin)=joyvalue[control.joystick].ymin;
(respuesta.xvalue)=joy.wXpos;
(respuesta.yvalue)=joy.wYpos;
//Para retornar Si habia alguna respuesta
if(izqu||dere||arri||abaj||fue1||fue2)
// "act1": se activa al pulsar el boton 1 despues de no haberlo pulsado
// aux1 se usa para saber si antes estaba pulsado o no
(respuesta.act1)=0;
if(fue1==0)
// "act2": se activa al pulsar el boton 2 despues de no haberlo pulsado
// aux2 se usa para saber si antes estaba pulsado o no
(respuesta.act2)=0;
if(fue2==0)
//retornamos si hay respuesta o no
return pulsa;
ÚLTIMA REVISIÓN EN
JULIO
DE
1999
|
|