Anuncios

Bienvenidos sean a este post, hoy veremos otro estado.

Anuncios

Hasta el post anterior creamos un juego mas completo, porque ya tenemos varios estados disponibles. Asi como tambien un objeto para representar al jugador y lo podemos mover. Pero hoy nos centraremos en agregar la opcion de pausa para el juego. Para ello, necesitaremos del codigo que vimos anteriormente. 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 bien funcionando correctamente, podemos continuar.

Anuncios

Antes de comenzar debemos descargar el siguiente archivo porque contiene las imagenes que usaremos para crear nuestro nuevo menu:

Anuncios

Una vez descargado, extraigan los dos archivos en la carpeta assets de nuestro proyecto. Con esto realizado, vamos a trabajar con el codigo donde crearemos una nueva clase llamada EstadoPausa. Una vez creada la nueva clase iremos al archivo de encabezado y agregaremos el siguiente codigo:

EstadoPausa.h
#pragma once
#ifndef __EstadoPausa__
#define __EstadoPausa__
#include "EstadoJuego.h"
#include "ObjetoJuego.h"
#include "ManejarTexturas.h"
#include <vector>
#include "Juego.h"

class EstadoPausa : public EstadoJuego
{
public:
	virtual void actualizar();
	virtual void renderizar();
	virtual bool enIngreso();
	virtual bool enSalida();
	virtual std::string getIdEstado() const;

private:
	static void e_volverMenu();
	static void e_retomarJuego();
	static const std::string e_idpausa;
	std::vector<ObjetoJuego*> m_objetosJuego;
};

#endif // !__EstadoPausa__
Anuncios

Si observamos es muy similar a las clases que vimos anteriormente pero sus funciones con otros nombres para diferenciarlos, como la constante, o las funciones para las acciones de callback, pero tecnicamente es similar a lo visto en los posts anteriores, donde representamos varias conductas y parametros del estado. Pasemos al archivo .cpp y agregaremos el siguiente codigo:

EstadoPausa.cpp

#include "EstadoPausa.h"
#include <Windows.h>

const std::string EstadoPausa::e_idpausa = "PAUSA";

void EstadoPausa::e_volverMenu() {
	Eljuego::instanciar()->getEstadoMaquina()->cambiaEstado(new EstadoMenu());
}

void EstadoPausa::e_retomarJuego() {
	Eljuego::instanciar()->getEstadoMaquina()->popEstado();
}

void EstadoPausa::actualizar() {
	for (int i = 0; i < m_objetosJuego.size(); i++)
		m_objetosJuego[i]->actualizar();
}

void EstadoPausa::renderizar() {
	for (int i = 0; i < m_objetosJuego.size(); i++)
		m_objetosJuego[i]->dibujar();
}

bool EstadoPausa::enIngreso() {
	if (!Elmanejador::instanciar()->cargar("assets/retomar.png",
		"botonretomar",Eljuego::instanciar()->getRenderer())) {
		return false;
	}
	if (!Elmanejador::instanciar()->cargar("assets/volver.png",
		"botonvolver", Eljuego::instanciar()->getRenderer())) {
		return false;
	}
	ObjetoJuego* boton1 = new BotonMenu(new CargadorParams(100, 100,
		400, 100, "botonvolver"), e_volverMenu);
	ObjetoJuego* boton2 = new BotonMenu(new CargadorParams(100, 300,
		400, 100, "botonretomar"), e_retomarJuego);
	m_objetosJuego.push_back(boton1);
	m_objetosJuego.push_back(boton2);

	OutputDebugStringA("Entrando en estado Pausa\n");
	return true;
}

bool EstadoPausa::enSalida() {
	for (int i = 0; i < m_objetosJuego.size(); i++)
		m_objetosJuego[i]->limpiar();
	m_objetosJuego.clear();
	Elmanejador::instanciar()->limpiaMapaTexturas("botonretomar");
	Elmanejador::instanciar()->limpiaMapaTexturas("botonvolver");
	Controles::instanciar()->limpiar();

	OutputDebugStringA("Saliendo del estado Pausa\n");
	return true;
}

std::string EstadoPausa::getIdEstado() const { return e_idpausa; }
Anuncios
Anuncios

Este es una clase similar a lo visto en EstadoMenu porque tendremos las funciones para cuando interactuemos con los «botones». La funcion e_volverMenu hara un cambio de estado y volvera al menu de inicio, en cambio la funcion e_retomarJuego llamara a la funcion popEstado. Las funciones actualizar y renderizar llamara a sus respectivas funciones en los objetos almacenados. Por ultimo, las funciones enIngreso y enSalida son muy similares a las vistas en EstadoMenu, donde en la primera funcion chequeamos si se crearon correctamente las imagenes de lo contrario salimos de la funcion y despues las ubicamos y agregamos a m_objetosJuego, y enSalida se encarga de eliminar todos los objetos cargados en memoria. Con esto ya tenemos nuestra clase de EstadoPausa completa, pasemos a nuestra siguiente modificacion.

Anuncios

Nuestra ultima modificacion es en la clase EstadoJugar. Lo primero que haremos es ir a EstadoJugar.h y agregaremos esta linea:

#include "EstadoPausa.h"
Anuncios

Esta agregara a la libreria que creamos anteriormente. Lo siguiente es ir a EstadoJugar.cpp, y modificaremos a la funcion actualizar de la siguiente manera:

void EstadoJugar::actualizar() {
	for (int i = 0; i < m_objetosJuego.size(); i++)
		m_objetosJuego[i]->actualizar();
	if (Controles::instanciar()->teclaPresionada(SDL_SCANCODE_ESCAPE))
		Eljuego::instanciar()->getEstadoMaquina()->
		pushEstado(new EstadoPausa());
}
Anuncios

Este condicional verifica si se presiono la tecla ESC o Escape para llamar a nuestro nuevo estado que sera Pausa. Antes de probar como funciona debemos hacer un cambio mas, para ello vamos a la funcion popEstado en MaquinaEstadoJuego.cpp y la modificaremos de la siguiente manera:

void MaquinaEstadoJuego::popEstado() {
	if (!m_estadoJuego.empty()) {
		if (m_estadoJuego.back()->enSalida()) {
			delete m_estadoJuego.back();
			m_estadoJuego.pop_back();
		}
	}
}
Anuncios

Revisando el codigo, note que habia un error cuando volviamos de la pausa. En la linea resaltada, habia un negador que impedia que se elimine el estado en cuestion del vector, el resto de la funcion sigue siendo la misma. Con esto realizado, pasemos a compilar nuestro juego y ver como funciona mediante el siguiente video

Anuncios

En el video podemos ver como creamos un menu de pausa que se activa con la tecla Escape, podemos ver el menu y como al presionar la opcion de Retomar volvemos al juego. Y si presionamos la opcion de Menu principal, nos lleva al inicio.

Anuncios

En resumen, hoy hemos creado el estado de pausa, hemos hecho la clase y todos los pasos necesarios para generar dicho estado en FSM, lo hemos implementado para activarlo cuando presionemos la tecla Escape, tambien lo hemos probado y vimos como funciona. Espero les haya sido de utilidad y les dejo un link a GitHub donde estan los codigos creados hoy:

Pausando el juego / 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