Anuncios

Bienvenidos sean a este post, hoy veremos otra forma de controlar al Jugador.

Anuncios

Hasta el post anterior completamos como controlar un objeto de nuestro juego con un mando, tanto con los sticks como los botones pero ahora veremos como hacerlo con el mouse.

Anuncios

A diferencia de como sucedio con el joystick no es necesario iniciar al mouse, tambien asumiremos que solo hay un mouse conectado por equipo por lo que no deberemos manejar varios dispositivos. Con esto aclarado pasemos a ver los evento que tenemos en SDL:

EventoProposito
SDL_MouseButtonEventDetecta si se presiono un boton o no
SDL_MouseMotionEventDetecta si se movio el mouse
SDL_MouseWheelEventDetecta si se movio la rueda del mouse
Anuncios

Al igual que sucedia con el joystick cada evento tiene un valor asignado, los cuales veremos en la siguiente tabla:

EventoValor
SDL_MouseButtonEventSDL_EVENT_MOUSE_BUTTON_DOWN o SDL_EVENT_MOUSE_BUTTON_UP
SDL_MouseMotionEventSDL_EVENT_MOUSE_MOTION
SDL_MouseWheelEventSDL_EVENT_MOUSE_WHEEL
Anuncios
Anuncios

En nuestro caso de los tres eventos el que no usaremos sera el de la rueda porque es el menos utilizado pero en algunos tipos de juegos se utiliza. Por ejemplo, en un FPS (First Person Shooter) se lo puede usar para pasar por todo el inventario de armas. Continuando con nuestro tema vamos a ver como manejar los eventos de los botones. Como se podran imaginar manejar los botones en mouse es mucho mas simple que con el joystick porque solo tenemos tres, y como dijimos antes no tendremos mas de un dispositivo. Para poder trabajar en este post, necesitaremos el proyecto que venimos utilizando. Sino lo poseen les dejo un link para descargarlo:

Proyecto Juego

Anuncios

Descarguen el archivo y extraigan el contenido en el PC. Lo unico que deben hacer es revincular a SDL y SDL_Image. Para ello, les recomiendo este post donde comento como hacerlo para SDL y este otro post donde hago lo mismo para SDL_Image. Una vez que este todo funcionando correctamente, podemos continuar. Nuestro primer paso sera ir a ManejarEntradas.h y en la parte privada agregaremos la siguiente variable:

std::vector<bool> m_estadoBotonMouse;
Anuncios

En este array almacenaremos el estado por cada boton. En la parte publica agregaremos al siguiente prototipo:

bool getEstadoBotonMouse(int);
Anuncios

Este nos servira para obtener el estado de los botones del mouse. Hablando de ello, lo siguiente sera agregar este enum por encima de la clase:

enum botones_mouse {
	IZQUIERDO = 0,
	MEDIO = 1,
	DERECHO = 2
};
Anuncios
Anuncios

Este enum debemos ponerlo por fuera de la clase para poder ser accedido por todos las clases que incluyan al archivo de encabezado, a este enum lo usaremos para indicar cual valor corresponde a cada boton del mouse. Como pueden ver es simple, esto gracias a que no tenemos dispositivos tan distintos y no debemos preocuparnos tanto. Aunque deben tener en cuenta a los mouses de tipo Gamer que pueden poseer mas botones pero en el ambito general seran siempre tres. Nuestra siguiente modificacion sera en la definicion del constructor de ManejarEntradas, la cual modificaremos de la siguiente manera:

ManejarEntradas::ManejarEntradas() {
	for (int i=0; i < 3; i++)
		m_estadoBotonMouse.push_back(false);
}
Anuncios

Como en este caso no tenemos una funcion para iniciar a nuestro dispositivo debemos hacerlo en el constructor, para que de manera predeterminada todos los valores del array que guarda los estados de los botones sean false. Esto equivale a decir que no estan presionados. Para nuestra ultima modificacion, debemos definir la funcion que agregamos en la parte publica de la clase:

bool ManejarEntradas::getEstadoBotonMouse(int numBoton) {
	return m_estadoBotonMouse[numBoton];
}
Anuncios

Esta funcion lo unico que hara sera devolver el valor del estado del boton que pasemos mediante el argumento de la misma. Con esto comentado, vayamos a la funcion actualizar que se encarga de monitorear los eventos debemos agregar los siguientes case en el switch de los eventos:

		case SDL_EVENT_MOUSE_BUTTON_DOWN:
			switch (evento.button.button) {
			case SDL_BUTTON_LEFT:
				m_estadoBotonMouse[IZQUIERDO] = true;
			case SDL_BUTTON_MIDDLE:
				m_estadoBotonMouse[MEDIO] = true;
			case SDL_BUTTON_RIGHT:
				m_estadoBotonMouse[DERECHO] = true;
			}
			break;

		case SDL_EVENT_MOUSE_BUTTON_UP:
			switch (evento.button.button) {
			case SDL_BUTTON_LEFT:
				m_estadoBotonMouse[IZQUIERDO] = false;
			case SDL_BUTTON_MIDDLE:
				m_estadoBotonMouse[MEDIO] = false;
			case SDL_BUTTON_RIGHT:
				m_estadoBotonMouse[DERECHO] = false;
			}
			break;
Anuncios

El primer case verifica si se esta presionando alguno de los botones del mouse. Si es verdad tendra un switch donde verifica por medio de evento.button.button los tres valores que puede obtener:

  • SDL_BUTTON_LEFT, valor para el boton izquierdo
  • SDL_BUTTON_MIDDLE, valor para el boton del medio
  • SDL_BUTTON_RIGHT, valor para el boton derecho
Anuncios

En cualquiera de los tres casos usara los valores del enum que creamos anteriormente, y con este como indice lo usara en el array de los estados de los botones para pasar el valor a true e indicar que esta siendo presionado. El siguiente case trabaja de la misma forma pero hace lo opuesto, este verifica si se solto el boton y procede a modificar el estado de boton como false. Con esto podemos dar por finalizado el codigo para manejar los eventos de los botones, pero nos falta una modificacion para probarlo. Para ello, debemos ir a la funcion manejaEntrada de Jugador.cpp y agregaremos el siguiente segmento de codigo:

if (Controles::instanciar()->getEstadoBotonMouse(DERECHO)) 
	m_velocidad.setX(1);
Anuncios

Este condicional debe estar por fuera del condicional que verifica si se inicio el joystick pero dentro de la funcion, en este caso verifica si pulsamos el boton derecho del mouse y si es verdad procede a movilizar el sprite hacia la derecha, compilemos y probemos como funciona mediante el siguiente video

Anuncios

En el video podemos ver como se logro el desplazamiento mediante el boton derecho del mouse, a continuacion trataremos el movimiento del mouse.

Anuncios

Si bien nosotros los juegos que veremos son de tipo 2D, no utilizaremos el mouse pero si es un dispositivo muy utilizado para los FPS en 3D. Aunque esto no quita que pueda haber juegos donde nuestro personaje tenga una mira para apuntar en un plataformero de accion en 2D, o una aventura grafica donde debamos mover un cursor, o un juego de tipo puzzle donde debamos mover objetos por la pantalla. Afortunadamente, para todas estas situcaciones tenemos acciones muy simples para resolverlas. Para esto vovleremos a ManejarEntradas.h y en la parte privada declararemos la siguiente variable:

Vector2D* m_posicionMouse;
Anuncios

Este objeto/variable sera para almacenar los ejes X e Y del lugar donde se encuentra el mouse pero esto es solo una declaracion. En la parte publica de la clase agregaremos al siguiente prototipo:

Vector2D* getPosicionMouse();
Anuncios

Con esto agregado, lo siguiente sera ir a ManejarEntradas.cpp donde haremos algunas modificaciones. Lo primero que haremos es agregar esta linea dentro del constructor:

m_posicionMouse = new Vector2D(0, 0);
Anuncios

Esta linea sera para definir e iniciar a nuestro al objeto que declaramos anteriormente, esto debemos hacerlo porque en algunas circunstancias puede no iniciarse y al ejecutar el juego puede devolver un error por intentar manejar valores nulos. Nuestra siguiente modificacion sera en la parte publica y agregaremos la funcion para obtener dicho valor y para ello agregaremos este bloque:

Vector2D* ManejarEntradas::getPosicionMouse() {
	return m_posicionMouse;
}
Anuncios

Como dijimos esta funcion solamente devuelve el objeto llamado m_posicionMouse con los valores de X e Y almacenados en el mismo. La siguiente modificacion sera en la funcion actualizar donde realizamos la verificacion de los evento de nuestros dispositivos. En dicha funcion agregaremos el siguiente case en el switch:

case SDL_EVENT_MOUSE_MOTION:
	m_posicionMouse->setX(evento.motion.x);
	m_posicionMouse->setY(evento.motion.y);
	break;
Anuncios

Este case verifica si estamos moviendo el mouse, en caso de ser cierto (no importa el tipo de movimiento) procede a actualizar los ejes X e Y del objeto que creamos (m_posicionMouse) mediaante evento.motion con el eje que corresponda. Nuestra ultima modificacion sera en Jugador.cpp donde iremos a la funcion manejaEntrada y agregaremos las siguientes lineas:

	Vector2D* v = Controles::instanciar()->getPosicionMouse();
	m_velocidad = (*v - m_posicion) / 100;
Anuncios

La primera crea un objeto de tipo de Vector2D el cual recibira el valor de la posicion actual de nuestro cursor, o por lo menos el iniciado cuando definimos a m_posicionMouse mediante getPosicionMouse. La siguiente linea establecera a m_velocidad, el valor en v menos el de m_posicion, y a este valor lo dividiremos por 100 para generar un pequeño retardo y nuestro sprite se desplazara detras de el evitando que este pegado a nuestro cursor. Compilemos y veamos que sucede mediante el siguiente video

Anuncios

Podemos ver como se mueve nuestro objeto detras del mouse, a continuacion les dejo un ejemplo de como es sin la division por 100 de la ultima formula mediante el siguiente video

Anuncios

Con esto ya hemos contemplado todas las posibilidades con el mouse, solo nos resta un tema mas que lo veremos en el siguiente post.

En resumen, hoy hemos visto como se manejan los eventos del mouse, cuales son los disponibles, hemos creado un evento para manejar los botones, otro para manejar el movimiento, hemos hecho una accion para que persiga a nuestro cursor y hemos creado otro para que este junto al cursor. Espero les haya sido de utilidad y les dejo un link a GitHub donde estan los codigos creados hoy:

Ahora toca el mouse / GitHub

Les dejo algunas de mis redes sociales para seguirme o recibir una notificacion cada vez que subo un nuevo post:

Anuncios
pp258

Donación

Es para mantenimento del sitio, gracias!

$1.50