Implementando el enemy engine

This commit is contained in:
2022-08-27 18:42:59 +02:00
parent 0e71bc97b3
commit 8a79737520
12 changed files with 418 additions and 48 deletions

73
data/map/01.ene Normal file
View File

@@ -0,0 +1,73 @@
tileset_img=surface.png
bgColor1=234,171,159
bgColor2=144,225,231
room_up=0
room_down=0
room_left=0
room_right=02.map
[tilemap]
01.tmx
[/tilemap]
[actors]
[moving platform]
tileset=moving_platform.png
animation=moving_platform.ani
width=16
height=8
x=9
y=11
vx=0.3
vy=0
x1=9
y1=11
x2=15
y2=11
[/moving platform]
[moving platform]
tileset=moving_platform.png
animation=moving_platform.ani
width=16
height=8
x=20
y=14
vx=0
vy=0.3
x1=20
y1=14
x2=20
y2=21
[/moving platform]
[diamond]
tileset=diamond.png
animation=diamond.ani
width=16
height=16
x=1
y=10
[/diamond]
[diamond]
tileset=diamond.png
animation=diamond.ani
width=16
height=16
x=24
y=10
[/diamond]
[diamond]
tileset=diamond.png
animation=diamond.ani
width=16
height=16
x=25
y=12
[/diamond]
[/actors]

View File

@@ -2,6 +2,11 @@
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
// Constructor
Enemy::Enemy()
{
}
// Constructor // Constructor
Enemy::Enemy(enemy_t enemy) Enemy::Enemy(enemy_t enemy)
{ {
@@ -15,18 +20,15 @@ Enemy::Enemy(enemy_t enemy)
sprite = new AnimatedSprite(texture, renderer, asset->get(enemy.animation)); sprite = new AnimatedSprite(texture, renderer, asset->get(enemy.animation));
// Obten el resto de valores // Obten el resto de valores
p1 = enemy.p1;
p2 = enemy.p2;
sprite->setPosX(enemy.x); sprite->setPosX(enemy.x);
sprite->setPosY(enemy.y); sprite->setPosY(enemy.y);
sprite->setVelX(enemy.vx);
sprite->setVelY(enemy.vy);
// Inicializa el sprite con el resto de parametros comunes
sprite->setWidth(enemy.w); sprite->setWidth(enemy.w);
sprite->setHeight(enemy.h); sprite->setHeight(enemy.h);
sprite->setCurrentAnimation("walk");
sprite->setFlip(enemy.vx>0?SDL_FLIP_NONE:SDL_FLIP_HORIZONTAL); sprite->setVelX(enemy.vx);
sprite->setVelY(enemy.vy);
sprite->setCurrentAnimation();
sprite->setFlip(enemy.vx > 0 ? SDL_FLIP_NONE : SDL_FLIP_HORIZONTAL);
collider = getRect(); collider = getRect();
} }
@@ -53,28 +55,9 @@ void Enemy::update()
{ {
sprite->update(); sprite->update();
sprite->animate(); sprite->animate();
checkPath();
collider = getRect(); collider = getRect();
} }
// Comprueba si ha llegado al limite del recorrido para darse media vuelta
void Enemy::checkPath()
{
// Comprueba los límites horizontales
if (sprite->getPosX() > p2.x || sprite->getPosX() < p1.x)
{
sprite->setVelX(sprite->getVelX() * (-1));
sprite->flip();
}
// Comprueba los límites verticales
if (sprite->getPosY() > p2.y || sprite->getPosY() < p1.y)
{
sprite->setVelY(sprite->getVelY() * (-1));
sprite->flip();
}
}
// Devuelve el rectangulo que contiene al enemigo // Devuelve el rectangulo que contiene al enemigo
SDL_Rect Enemy::getRect() SDL_Rect Enemy::getRect()
{ {

View File

@@ -22,37 +22,31 @@ struct enemy_t
float y; // Posición inicial en el eje Y float y; // Posición inicial en el eje Y
float vx; // Velocidad en el eje X float vx; // Velocidad en el eje X
float vy; // Velocidad en el eje Y float vy; // Velocidad en el eje Y
SDL_Point p1; // Punto 1 (inicial) de la ruta
SDL_Point p2; // Punto 2 (final) de la ruta
}; };
// Clase Enemy // Clase Enemy
class Enemy class Enemy
{ {
private: protected:
SDL_Renderer *renderer; // El renderizador de la ventana SDL_Renderer *renderer; // El renderizador de la ventana
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
LTexture *texture; // Textura con los graficos del enemigo LTexture *texture; // Textura con los graficos del enemigo
AnimatedSprite *sprite; // Sprite del enemigo AnimatedSprite *sprite; // Sprite del enemigo
SDL_Point p1; // Punto 1 (inicial) de la ruta
SDL_Point p2; // Punto 2 (final) de la ruta
SDL_Rect collider; // Caja de colisión SDL_Rect collider; // Caja de colisión
// Comprueba si ha llegado al limite del recorrido para darse media vuelta
void checkPath();
public: public:
// Constructor // Constructor
Enemy();
Enemy(enemy_t enemy); Enemy(enemy_t enemy);
// Destructor // Destructor
~Enemy(); virtual ~Enemy();
// Pinta el enemigo en pantalla // Pinta el enemigo en pantalla
void render(); void render();
// Actualiza las variables del objeto // Actualiza las variables del objeto
void update(); virtual void update();
// Devuelve el rectangulo que contiene al enemigo // Devuelve el rectangulo que contiene al enemigo
SDL_Rect getRect(); SDL_Rect getRect();

196
source/enemy_engine.cpp Normal file
View File

@@ -0,0 +1,196 @@
#include "enemy_engine.h"
#include <fstream>
#include <sstream>
// Constructor
EnemyEngine::EnemyEngine(SDL_Renderer *renderer, Asset *asset, Player *player, Map *map)
{
this->renderer = renderer;
this->asset = asset;
this->player = player;
this->map = map;
}
// Destructor
EnemyEngine::~EnemyEngine()
{
}
// Pinta los enemigos en pantalla
void EnemyEngine::render()
{
for (auto enemy : enemies)
{
enemy->render();
}
}
// Actualiza las variables del objeto
void EnemyEngine::update()
{
for (auto enemy : enemies)
{
enemy->update();
}
}
// Carga las variables desde un fichero
bool EnemyEngine::load(std::string file_path)
{
// Indicador de éxito en la carga
bool success = true;
std::string filename = file_path.substr(file_path.find_last_of("\\/") + 1);
std::string line;
std::ifstream file(file_path);
// El fichero se puede abrir
if (file.good())
{
// Procesa el fichero linea a linea
printf("Reading file %s\n", filename.c_str());
while (std::getline(file, line))
{
// Si la linea contiene el texto [tilemap] se realiza el proceso de carga del fichero tmx
if (line == "[tilemap]")
{
do
{
std::getline(file, line);
if (line.find(".tmx") != std::string::npos)
{
std::ifstream file2(asset->get(line)); // Abre el fichero tmx
if (file2.good())
{
bool data_read = false;
while (std::getline(file2, line)) // Lee el fichero linea a linea
{
if (!data_read)
{ // Lee lineas hasta que encuentre donde empiezan los datos del mapa
int pos = 0;
do
{
std::getline(file2, line);
pos = line.find("data encoding");
} while (pos == std::string::npos);
do
{ // Se introducen los valores separados por comas en un vector
data_read = true;
std::getline(file2, line);
if (line != "</data>")
{
std::stringstream ss(line);
std::string tmp;
while (getline(ss, tmp, ','))
{
tilemap.push_back(std::stoi(tmp));
}
}
} while (line != "</data>");
}
}
}
}
} while (line != "[/tilemap]");
}
// Si la linea contiene el texto [actor] se realiza el proceso de carga de los actores
else if (line == "[actors]")
{
do
{
std::getline(file, line);
if (line == "[moving platform]")
{
actor_t actor;
actor.asset = asset;
actor.renderer = renderer;
actor.name = a_moving_platform;
SDL_Point p1, p2;
do
{
std::getline(file, line);
// Encuentra la posición del caracter '='
int pos = line.find("=");
// Procesa las dos subcadenas
if (!setActor(&actor, &p1, &p2, line.substr(0, pos), line.substr(pos + 1, line.length())))
{
printf("Warning: file %s\n, unknown parameter \"%s\"\n", filename.c_str(), line.substr(0, pos).c_str());
success = false;
}
} while (line != "[/moving platform]");
printf("** actor moving platform loaded\n\n");
actors.push_back(new ActorMovingPlatform(actor, p1, p2));
}
if (line == "[diamond]")
{
actor_t actor;
actor.asset = asset;
actor.renderer = renderer;
actor.name = a_diamond;
actor.vx = 0.0f;
actor.vy = 0.0f;
SDL_Point p1, p2;
do
{
std::getline(file, line);
// Encuentra la posición del caracter '='
int pos = line.find("=");
// Procesa las dos subcadenas
if (!setActor(&actor, &p1, &p2, line.substr(0, pos), line.substr(pos + 1, line.length())))
{
printf("Warning: file %s\n, unknown parameter \"%s\"\n", filename.c_str(), line.substr(0, pos).c_str());
success = false;
}
} while (line != "[/diamond]");
// Comprueba si el actor no ha sido recogido previamente
if (!itemTracker->hasBeenPicked(name, {(int)actor.x, (int)actor.y}))
{
printf("** actor diamond loaded\n\n");
actors.push_back(new ActorDiamond(actor));
}
}
} while (line != "[/actors]");
}
// En caso contrario se parsea el fichero para buscar las variables y los valores
else
{
// Encuentra la posición del caracter '='
int pos = line.find("=");
// Procesa las dos subcadenas
if (!setVars(line.substr(0, pos), line.substr(pos + 1, line.length())))
{
printf("Warning: file %s, unknown parameter \"%s\"\n", filename.c_str(), line.substr(0, pos).c_str());
success = false;
}
}
}
// Cierra el fichero
printf("Closing file %s\n\n", filename.c_str());
file.close();
}
// El fichero no se puede abrir
else
{
printf("Warning: Unable to open %s file\n", filename.c_str());
success = false;
}
return success;
}

43
source/enemy_engine.h Normal file
View File

@@ -0,0 +1,43 @@
#pragma once
#include <SDL2/SDL.h>
#include "utils.h"
#include "asset.h"
#include "enemy.h"
#include "enemy_path.h"
#include "map.h"
#include "player.h"
#include <string>
#include <vector>
#ifndef ENEMY_ENGINE_H
#define ENEMY_ENGINE_H
// Clase EnemyEngine
class EnemyEngine
{
private:
SDL_Renderer *renderer; // El renderizador de la ventana
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
Map *map; // Mapa con la información de la habitación
Player *player; // Puntero con el jugador
std::vector<Enemy *> enemies; // Vector con la lista de enemigos
// Carga las variables desde un fichero
bool load(std::string file_path);
public:
// Constructor
EnemyEngine(SDL_Renderer *renderer, Asset *asset, Player *player, Map *map);
// Destructor
~EnemyEngine();
// Pinta los enemigos en pantalla
void render();
// Actualiza las variables del objeto
void update();
};
#endif

43
source/enemy_path.cpp Normal file
View File

@@ -0,0 +1,43 @@
#include "enemy_path.h"
#include <fstream>
#include <sstream>
// Constructor
EnemyPath::EnemyPath(enemy_t enemy, SDL_Point p1, SDL_Point p2) : Enemy(enemy)
{
// Obten el resto de valores
this->p1 = p1;
this->p2 = p2;
}
// Destructor
EnemyPath::~EnemyPath()
{
}
// Actualiza las variables del objeto
void EnemyPath::update()
{
sprite->update();
sprite->animate();
checkPath();
collider = getRect();
}
// Comprueba si ha llegado al limite del recorrido para darse media vuelta
void EnemyPath::checkPath()
{
// Comprueba los límites horizontales
if (sprite->getPosX() > p2.x || sprite->getPosX() < p1.x)
{
sprite->setVelX(sprite->getVelX() * (-1));
sprite->flip();
}
// Comprueba los límites verticales
if (sprite->getPosY() > p2.y || sprite->getPosY() < p1.y)
{
sprite->setVelY(sprite->getVelY() * (-1));
sprite->flip();
}
}

33
source/enemy_path.h Normal file
View File

@@ -0,0 +1,33 @@
#pragma once
#include <SDL2/SDL.h>
#include "enemy.h"
#include <string>
#ifndef ENEMY_PATH_H
#define ENEMY_PATH_H
// Clase EnemyPath
class EnemyPath : public Enemy
{
private:
SDL_Point p1; // Punto 1 (inicial) de la ruta
SDL_Point p2; // Punto 2 (final) de la ruta
// Comprueba si ha llegado al limite del recorrido para darse media vuelta
void checkPath();
public:
// Constructor
EnemyPath(enemy_t enemy, SDL_Point p1, SDL_Point p2);
// Destructor
~EnemyPath();
// Actualiza las variables del objeto
void update();
};
#endif

View File

@@ -11,9 +11,10 @@ Game::Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input)
// Reserva memoria para los objetos // Reserva memoria para los objetos
eventHandler = new SDL_Event(); eventHandler = new SDL_Event();
itemTracker = new Item_tracker(); itemTracker = new ItemTracker();
map = new Map(asset->get("01.map"), renderer, asset, itemTracker); map = new Map(asset->get("01.map"), renderer, asset, itemTracker);
player = new Player(renderer, asset, input, map); player = new Player(renderer, asset, input, map);
enemyEngine = new EnemyEngine(renderer, asset, player, map);
debugText = new Text(asset->get("debug.png"), asset->get("debug.txt"), renderer); debugText = new Text(asset->get("debug.png"), asset->get("debug.txt"), renderer);
music = JA_LoadMusic(asset->get("music_surface.ogg").c_str()); music = JA_LoadMusic(asset->get("music_surface.ogg").c_str());
@@ -36,6 +37,7 @@ Game::~Game()
delete itemTracker; delete itemTracker;
delete map; delete map;
delete player; delete player;
delete enemyEngine;
delete debugText; delete debugText;
JA_DeleteMusic(music); JA_DeleteMusic(music);
} }

View File

@@ -8,6 +8,7 @@
#include "map.h" #include "map.h"
#include "player.h" #include "player.h"
#include "item_tracker.h" #include "item_tracker.h"
#include "enemy_engine.h"
#include "text.h" #include "text.h"
#ifndef GAME_H #ifndef GAME_H
@@ -25,7 +26,8 @@ private:
Text *debugText; // Objeto para escribir texto con información de debug Text *debugText; // Objeto para escribir texto con información de debug
Map *map; // Objeto encargado de gestionar el mapeado del juego Map *map; // Objeto encargado de gestionar el mapeado del juego
Player *player; // Objeto para gestionar el jugador Player *player; // Objeto para gestionar el jugador
Item_tracker *itemTracker; // Objeto para gestionar los items recogidos ItemTracker *itemTracker; // Objeto para gestionar los items recogidos
EnemyEngine *enemyEngine; // Objeto encargado de gestionar los enemigos
section_t section; // Seccion actual dentro del programa section_t section; // Seccion actual dentro del programa
int ticks; // Contador de ticks para ajustar la velocidad del programa int ticks; // Contador de ticks para ajustar la velocidad del programa
int ticksSpeed; // Velocidad a la que se repiten los bucles del programa int ticksSpeed; // Velocidad a la que se repiten los bucles del programa

View File

@@ -1,18 +1,18 @@
#include "item_tracker.h" #include "item_tracker.h"
// Constructor // Constructor
Item_tracker::Item_tracker() ItemTracker::ItemTracker()
{ {
} }
// Destructor // Destructor
Item_tracker::~Item_tracker() ItemTracker::~ItemTracker()
{ {
list.clear(); list.clear();
} }
// Comprueba si el objeto ya ha sido cogido // Comprueba si el objeto ya ha sido cogido
bool Item_tracker::hasBeenPicked(std::string name, SDL_Point pos) bool ItemTracker::hasBeenPicked(std::string name, SDL_Point pos)
{ {
bool success = false; bool success = false;
@@ -31,7 +31,7 @@ bool Item_tracker::hasBeenPicked(std::string name, SDL_Point pos)
} }
// Añade el objeto a la lista de objetos cogidos // Añade el objeto a la lista de objetos cogidos
void Item_tracker::addItem(std::string name, SDL_Point pos) void ItemTracker::addItem(std::string name, SDL_Point pos)
{ {
// Comprueba si el objeto no ha sido recogido con anterioridad // Comprueba si el objeto no ha sido recogido con anterioridad
if (!hasBeenPicked(name, pos)) if (!hasBeenPicked(name, pos))
@@ -55,7 +55,7 @@ void Item_tracker::addItem(std::string name, SDL_Point pos)
} }
// Busca una entrada en la lista por nombre // Busca una entrada en la lista por nombre
int Item_tracker::findByName(std::string name) int ItemTracker::findByName(std::string name)
{ {
const int c = -1; const int c = -1;
@@ -71,7 +71,7 @@ int Item_tracker::findByName(std::string name)
} }
// Busca una entrada en la lista por posición // Busca una entrada en la lista por posición
int Item_tracker::findByPos(int index, SDL_Point pos) int ItemTracker::findByPos(int index, SDL_Point pos)
{ {
const int c = -1; const int c = -1;

View File

@@ -15,7 +15,7 @@ struct item_tracker_t
}; };
// Clase Item_tracker // Clase Item_tracker
class Item_tracker class ItemTracker
{ {
private: private:
std::vector<item_tracker_t> list; // Lista con todos los objetos recogidos std::vector<item_tracker_t> list; // Lista con todos los objetos recogidos
@@ -28,10 +28,10 @@ private:
public: public:
// Constructor // Constructor
Item_tracker(); ItemTracker();
// Destructor // Destructor
~Item_tracker(); ~ItemTracker();
// Comprueba si el objeto ya ha sido cogido // Comprueba si el objeto ya ha sido cogido
bool hasBeenPicked(std::string name, SDL_Point pos); bool hasBeenPicked(std::string name, SDL_Point pos);

View File

@@ -140,6 +140,7 @@ bool Prog::setFileList()
// Ficheros del mapa // Ficheros del mapa
asset->add("/data/map/01.map", data); asset->add("/data/map/01.map", data);
asset->add("/data/map/01.tmx", data); asset->add("/data/map/01.tmx", data);
asset->add("/data/map/01.ene", data);
asset->add("/data/map/02.map", data); asset->add("/data/map/02.map", data);
asset->add("/data/map/02.tmx", data); asset->add("/data/map/02.tmx", data);
asset->add("/data/map/03.map", data); asset->add("/data/map/03.map", data);