Anuncios

Bienvenidos sean a este post, hoy completaremos un poco mas lo creado en el post anterior.

Anuncios
Anuncios

Si bien hasta ahora nuestros botones reaccionan con nuestro mouse, no hacen nada cuando hacemos click encima de ellos. Salvo, mostrarnos el frame correspondiente pero como lograremos que se ejecute una accion con nuestro boton? Aca entra en vigencia un tipo de accion muy particular como son los punteros a funciones, y es literal como su nombre lo indica. Por el momento vamos a utilizar el estilo clasico de C porque no necesitamos pasar argumentos y siempre tiene un tipo de retorno como void. Antes de continuar veamos como es la sintaxis de estos punteros:

tipoRetorno (*nombreFuncion)(parametros)();
Anuncios

Si necesitan saber mas sobre esto, les recomiendo el siguiente post:

Anuncios

Necesitaremos del codigo que vinimos trabajando hasta el post anterior sino lo poseen les dejo un link para descargarlo:

SDL / Implementando el menu

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. Vamos al archivo de encabezado de BotonMenu y en su parte privada agregaremos el siguiente codigo:

void (*m_callback)();
bool m_bLiberado;
Anuncios

La primer declaracion sera el puntero de funciones que usaremos. Lo siguiente es la variable que sera utilizada para cuando dejamos de pulsar el boton de nuestro mouse. Es de tipo bool para saber por medio de true o false cuando se dejo de presionar. Con esto terminamos la parte privada pasemos a la parte publica y modifiquemos el prototipo del constructor de la siguiente manera:

BotonMenu(const CargadorParams*, void (*)());
Anuncios

Agregamos como parametro el puntero de funciones en conjuncion con los parametros del CargadorParams permitiendo pasarlo como parametro. Con esto concluimos con el archivo de encabezado pasemos a BotonMenu.cpp para realizar las modificaciones pertinentes. La primera sera en nuestro constructor y lo modificaremos de la siguiente manera:

BotonMenu::BotonMenu(const CargadorParams* pParams, void(*callback)()):
	SDLObjetoJuego(pParams), m_callback(callback) {
	m_frameActual = MOUSE_FUERA;
}
Anuncios

Aca no solamente recibiremos el nuevo parametro que sera la funcion que llamaremos sino tambien que iniciaremos a m_callback mediante el valor recibido en callback. Nuestra siguiente modificacion sera en la funcion actualizar y para ello modificaremos este condicional:

if (Controles::instanciar()->getEstadoBotonMouse(IZQUIERDO)) {
	m_frameActual = CLICKEADO;
}
Anuncios

Y lo reemplazaremos de la siguiente manera:

if (Controles::instanciar()->getEstadoBotonMouse(IZQUIERDO)
	&& m_bLiberado) {
	m_callback();
	m_bLiberado = false;
}
else if (!Controles::instanciar()->getEstadoBotonMouse(IZQUIERDO)) {
	m_bLiberado = true;
	m_frameActual = MOUSE_SOBRE;
}
Anuncios
Anuncios

La primera modificacion fue en la primera condicion donde no solo verificamos si se uso el boton izquierdo del mouse sino tambien si lo soltamos o dejamos de presionar. Si cumple esta condicion, seguimos manteniendo el frame de cuando hacemos click. Luego agregamos el llamado a la funcion almacenado en m_callback, y por ultimo establecemos a m_bLiberado como false pero tambien agregamos otra condicion donde verificamos si no se presiono el boton izquierdo. En caso de ser verdadero establecemos a m_bLiberado como true y en m_frameActual estableceremos el valor de la imagen cuando estamos sobre este. Con esto tenemos las funciones que nos permitiran recibir y procesar las que debemos llamar cuando apretemos los botones. Sigamos con otras modificaciones.

Anuncios

La siguiente modificacion sera en la clase EstadoMenu, primero iremos al archivo de encabezado y en su parte privada agregaremos los siguientes prototipos:

static void e_menuParaJugar();
static void e_salirDelMenu();
Anuncios

Estas seran las funciones para cuando apretemos los botones. Ahora pasemos a definirlas en EstadoMenu.cpp, y para ello agreguemos el siguiente codigo:

void EstadoMenu::e_menuParaJugar() {
	OutputDebugStringA("Boton de juego apretado\n");
}
void EstadoMenu::e_salirDelMenu() {
	OutputDebugStringA("Boton de salir apretado\n");
}
Anuncios

Solamente haremos que escriban en nuestra salida de depuracion una notificacion cuando se haya trabajado con ellos. Nuestra «ultima» modificacion sera en los objetos que usamos para crear los botones en el mismo archivo dentro de la funcion enIngreso, veamos como estan actualmente:

ObjetoJuego* boton1 = new BotonMenu(new CargadorParams(100, 100, 400, 100,
	"botonJugar"));
ObjetoJuego* boton2 = new BotonMenu(new CargadorParams(100, 300, 400, 100, 
	"botonSalir"));
Anuncios

Y lo modificaremos de la siguiente manera:

ObjetoJuego* boton1 = new BotonMenu(new CargadorParams(100, 100, 400, 100,
	"botonJugar"), e_menuParaJugar);
ObjetoJuego* boton2 = new BotonMenu(new CargadorParams(100, 300, 400, 100,
	"botonSalir"), e_salirDelMenu);
Anuncios

Como pueden observar ajustamos el constructor al nuevo y pasamos las funciones que generamos para cada boton. Si lo compilamos y probamos deberemos tener en la salida de depuracion los mensajes de la accion realizada

Anuncios

Con esto ya tenemos todo creado para manejar nuestro botones pero solo como practica y demostracion. Vamos a modificarlo para que trabaje realmente, para ello iremos a la funcion e_salirDelMenu y lo modificaremos de la siguiente manera:

void EstadoMenu::e_salirDelMenu() {
	OutputDebugStringA("Boton de salir apretado\n");
	Eljuego::instanciar()->limpiar();
}
Anuncios

Seguimos manteniendo el mensaje en la depuracion pero llamamos a la funcion limpiar de la clase Juego para salir de nuestro proyecto. Nuestra siguiente modificacion sera en e_menuParaJugar pero antes debemos hacer una modificacion en la clase Juego. Primero iremos a Juego.h y en la parte publica agregaremos el siguiente prototipo:

MaquinaEstadoJuego* getEstadoMaquina();
Anuncios

Lo siguiente sera definirlo, para ello debemos ir a Juego.cpp y agregaremos el siguiente codigo:

MaquinaEstadoJuego* Juego::getEstadoMaquina() { 
    return m_pMaquinaEstadoJuego; 
}
Anuncios

Esta funcion unicamente devuelve el valor actual de m_pMaquinaEstadoJuego. Con esta funcion agregada pasemos a EstadoMenu.cpp y modifiquemos a e_menuParaJugar de la siguiente manera:

void EstadoMenu::e_menuParaJugar() {
	OutputDebugStringA("Boton de juego apretado\n");
	Eljuego::instanciar()->getEstadoMaquina()->
		cambiaEstado(new EstadoJugar());
}
Anuncios

Seguimos dejando la notificacion en la depuracion y en la nueva linea despues de obtener el estado actual lo cambiamos por medio de cambiaEstado al estado JUGAR pero como esta vacia no sucedera nada sino que solamente lo veremos en la notificacion de la salida de depuracion, compilemos y veamos que sucede mediante el siguiente video

Anuncios

En el video podemos ver como ahora nuestro juego no solamente cambia los frames de los botones sino que tambien podemos cambiar nuestro estado o salir del mismo, no desesperen que falta menos pero vamos por el buen camino.

Anuncios

En resumen, hoy hemos visto como al trabajar con apuntadores de funciones y callbacks pudimos agregar a nuestros estados la capacidad de interaccion para permitirnos ejecutar acciones en base a los eventos que interactuen con ellos, por ejemplo hemos trabajado con el click para que cambie al estado JUGAR o bien para salir del programa. Espero les haya sido de utilidad y les dejo un link a GitHub donde estan los codigos creados hoy:

Puntero a funciones y callbacks / GitHub

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

Anuncios

Donación

Es para mantenimento del sitio, gracias!

$1.50