Anuncios

Bienvenidos sean a este post, hoy comenzaremos la travesia de agregar el nivel.

Anuncios

En el post anterior vimos como crear nuestro escenario o nivel mediante Tiled. Hoy nos centraremos en como implementarlo en nuestro proyecto Juego. 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.

Anuncios

Debemos crear una clase encargada de manejar a los niveles pero antes crearemos una clase llamada Capa. Una vez creada, agregaremos el siguiente codigo en su archivo de encabezado:

Capa.h
#pragma once
#ifndef __Capa__
#define __Capa__

class Capa
{
public:
	virtual void renderizar() = 0;
	virtual void actualizar() = 0;

protected:
	virtual ~Capa();
};

#endif // !__Capa__
Anuncios

Esta sera la clase base para las distintas capas que usaremos en los niveles, pero eso lo veremos en un momento. Como va a ser nuestra clase base, declaramos dos funciones abstractas que definiremos en los distintos herederos. En la parte protegida, declaramos a nuestro destructor predeterminado. Lo siguiente sera definir a esta ultima funcion en su archivo .cpp:

Capa.cpp
#include "Capa.h"

Capa::~Capa() {}
Anuncios

La definiremos en blanco porque no necesitaremos mas, por que definimos esta y las otras no? Porrque como mencionamos, las publicas son abstractas y se definen en los herederos. Esta al no ser abstracta debe tener su definicion. Podriamos haberlo definido en el archivo de encabezado, pero por un tema de prolijidad y respetar como trabajamos lo hacemos asi.

Anuncios

Nuestro siguiente paso sera crear la clase encargada de los niveles. Para ello, crean una nueva con el nombre de Nivel. Van al archivo de encabezado y agregan el siguiente codigo:

Nivel.h
#pragma once
#ifndef __Nivel__
#define __Nivel__
#include "Capa.h"
#include <string>
#include <vector>

struct ConjuntoPatron {
	int primerCuadric;
	int anchoPatron;
	int altoPatron;
	int espaciado;
	int margen;
	int ancho;
	int alto;
	int numColumnas;
	std::string nombre;
};

class Nivel
{
public:
	Nivel();
	~Nivel();
	void actualizar();
	void renderizar();
	std::vector<ConjuntoPatron>* getConjPatron();
	std::vector<Capa*>* getCapas();

private:
	std::vector<ConjuntoPatron> m_conjPatrones;
	std::vector<Capa*> m_capas;
};

#endif // !__Nivel__
Anuncios
Anuncios

Una de las librerias que usaremos es la creada anteriormente, pero es solamente por un tema de compatibilidad que veremos en un momento. Luego tenemos un struct que sera para representar los datos del conjunto de patrones, tileset, y sus patrones o imagenes internas. Estos datos son el alto, ancho de las imagenes, del conjunto, etc. En la clase tenemos no solamente al constructor y destructor sino tambien las funciones para actualizar y renderizar. Asi como tambien dos funciones para obtener los valores almacenados en la parte privada. En la parte privada, tenemos dos colecciones para almacenar todos los conjunto de patrones (m_conjPatrones) y capas (m_capas).

Anuncios

Pasemos a definir los prototipos de las funciones, para ello iremos a Nivel.cpp y agregaremos el siguiente codigo:

Nivel.cpp
#include "Nivel.h"

Nivel::Nivel() {}
Nivel::~Nivel() {}

std::vector<ConjuntoPatron>* Nivel::getConjPatron() {
	return &m_conjPatrones;
}

std::vector<Capa*>* Nivel::getCapas() {
	return &m_capas;
}

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

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

Definimos al constructor y destructor en blanco porque no necesitaremos ninguna tarea. La siguiente funcion es la encargada de devolvernos la coleccion con todos los conjuntos de patrones que hayamos ingresado. Para la funcion de renderizar y actualizar usaremos el mismo procedimiento, donde usaremos un bucle que pasara por todas las capas y en cada funcion llamaremos a la funcion actualizar y renderizar de cada objeto.

Anuncios

Ya tenemos la base para el nivel y para las capas, pasemos a crear la primer clase heredera de Capa. La crearemos conn el nombre de CapaPatron. Una vez creada, agreguemos el siguiente codigo en el archivo encabezado:

CapaPatron.h
#pragma once
#ifndef __CapaPatron__
#define __CapaPatron__

#include "Capa.h"
#include <vector>
#include "Nivel.h"
#include "Vector2D.h"

class CapaPatron : public Capa
{
public:
	CapaPatron(int, const std::vector<ConjuntoPatron>&);
	virtual void actualizar();
	virtual void renderizar();
	void setIdPatron(const std::vector<std::vector<int>>&);
	void setTamPatron(int);
	ConjuntoPatron getConjuntoPorId(int);

private:
	int m_numColumnas;
	int m_numFilas;
	int m_tamPatron;
	Vector2D m_posicion;
	Vector2D m_velocidad;
	const std::vector<ConjuntoPatron>& m_conjuntos;
	std::vector<std::vector<int>> m_idPatron;
};

#endif // !__CapaPatron__
Anuncios
Anuncios

No solo implementaremos las dos clases creadas anteriormente sino que agregaremos a nuestra clase de vector para el movimiento. Hablemos primero de la parte privada, en ella tenemos las tres primeras variables que se ese encargan de las caracteristicas del conjunto de patron. Luego tenemos dos para manejar la posicion de los elementos en esta, asi como la velocidad para los que se muevan. Para terminar con dos colecciones donde almacenaremos los conjuntos de patron y los id de cada patron respectivamente. En la parte publica, declaramos las distintas funciones que usaremos. Tenemos un constructor para iniciar dos valores de la parte privada. Luego la definicion de las funciones heredadas de Capa. Una para establecer el id para un patron, otra para establecer un nuevo tamaño para nuestros patrones y una ultima para obtener un conjunto de patron mediante el id de esta.

Anuncios

Al ser solo prototipos, nos resta definir a los mismos y para ello deben ir al archivo .cpp y agregar el siguiente codigo:

CapaPatron.cpp
#include "CapaPatron.h"

CapaPatron::CapaPatron(int tamPatron, 
	const std::vector<ConjuntoPatron> &conjuntos):
	m_tamPatron(tamPatron),m_conjuntos(conjuntos) {}

void CapaPatron::actualizar(){}
void CapaPatron::renderizar(){}
void CapaPatron::setIdPatron(const std::vector < std::vector<int>> &datos) {
	m_idPatron = datos;
}
void CapaPatron::setTamPatron(int tamPatron) {
	m_tamPatron = tamPatron;
}

ConjuntoPatron CapaPatron::getConjuntoPorId(int id) {}
Anuncios

Como comentamos anteriormennte, el constructor recibe dos valores que seran para iniciar a m_tamPatron y m_conjuntos de la parte privada. Por el momento, dejaremos en blanco a actualizar, renderizar y getConjuntoPorId. Y si definimos a setIdPatron y setTamPatron, para poder establecer nuevos valores en estas variables. Hasta aca tenemos la base para poder manipular nuestros niveles y sus elementos o capas, en los proximos posts iremos desarrollandos los elementos faltantes que haran toda la magia por nosotros.

Anuncios
Nota:
Si lo compilan ahora mismo, les devolvera un error pero pronto lo solucionaremos.
Anuncios

En resumen, hoy hemos visto como comenzar a trabajar con los tile map, establecemos las clases bases para la manipulacion, asi como otros temas pero de los cuales nos adentraremos mas en los proximos posts. Espero les haya sido de utilidad y les dejo un link a GitHub donde estan los codigos creados hoy:

Empecemos a trabajar con el tile map / 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