Implementando el enemy engine
This commit is contained in:
73
data/map/01.ene
Normal file
73
data/map/01.ene
Normal 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]
|
||||
@@ -2,6 +2,11 @@
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
// Constructor
|
||||
Enemy::Enemy()
|
||||
{
|
||||
}
|
||||
|
||||
// Constructor
|
||||
Enemy::Enemy(enemy_t enemy)
|
||||
{
|
||||
@@ -15,18 +20,15 @@ Enemy::Enemy(enemy_t enemy)
|
||||
sprite = new AnimatedSprite(texture, renderer, asset->get(enemy.animation));
|
||||
|
||||
// Obten el resto de valores
|
||||
p1 = enemy.p1;
|
||||
p2 = enemy.p2;
|
||||
sprite->setPosX(enemy.x);
|
||||
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->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();
|
||||
}
|
||||
@@ -53,28 +55,9 @@ void Enemy::update()
|
||||
{
|
||||
sprite->update();
|
||||
sprite->animate();
|
||||
checkPath();
|
||||
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
|
||||
SDL_Rect Enemy::getRect()
|
||||
{
|
||||
|
||||
@@ -22,37 +22,31 @@ struct enemy_t
|
||||
float y; // Posición inicial en el eje Y
|
||||
float vx; // Velocidad en el eje X
|
||||
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
|
||||
class Enemy
|
||||
{
|
||||
private:
|
||||
protected:
|
||||
SDL_Renderer *renderer; // El renderizador de la ventana
|
||||
Asset *asset; // Objeto con la ruta a todos los ficheros de recursos
|
||||
LTexture *texture; // Textura con los graficos 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
|
||||
|
||||
// Comprueba si ha llegado al limite del recorrido para darse media vuelta
|
||||
void checkPath();
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
Enemy();
|
||||
Enemy(enemy_t enemy);
|
||||
|
||||
// Destructor
|
||||
~Enemy();
|
||||
virtual ~Enemy();
|
||||
|
||||
// Pinta el enemigo en pantalla
|
||||
void render();
|
||||
|
||||
// Actualiza las variables del objeto
|
||||
void update();
|
||||
virtual void update();
|
||||
|
||||
// Devuelve el rectangulo que contiene al enemigo
|
||||
SDL_Rect getRect();
|
||||
|
||||
196
source/enemy_engine.cpp
Normal file
196
source/enemy_engine.cpp
Normal 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
43
source/enemy_engine.h
Normal 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
43
source/enemy_path.cpp
Normal 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
33
source/enemy_path.h
Normal 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
|
||||
@@ -11,9 +11,10 @@ Game::Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input)
|
||||
|
||||
// Reserva memoria para los objetos
|
||||
eventHandler = new SDL_Event();
|
||||
itemTracker = new Item_tracker();
|
||||
itemTracker = new ItemTracker();
|
||||
map = new Map(asset->get("01.map"), renderer, asset, itemTracker);
|
||||
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);
|
||||
music = JA_LoadMusic(asset->get("music_surface.ogg").c_str());
|
||||
|
||||
@@ -36,6 +37,7 @@ Game::~Game()
|
||||
delete itemTracker;
|
||||
delete map;
|
||||
delete player;
|
||||
delete enemyEngine;
|
||||
delete debugText;
|
||||
JA_DeleteMusic(music);
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "map.h"
|
||||
#include "player.h"
|
||||
#include "item_tracker.h"
|
||||
#include "enemy_engine.h"
|
||||
#include "text.h"
|
||||
|
||||
#ifndef GAME_H
|
||||
@@ -25,7 +26,8 @@ private:
|
||||
Text *debugText; // Objeto para escribir texto con información de debug
|
||||
Map *map; // Objeto encargado de gestionar el mapeado del juego
|
||||
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
|
||||
int ticks; // Contador de ticks para ajustar la velocidad del programa
|
||||
int ticksSpeed; // Velocidad a la que se repiten los bucles del programa
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
#include "item_tracker.h"
|
||||
|
||||
// Constructor
|
||||
Item_tracker::Item_tracker()
|
||||
ItemTracker::ItemTracker()
|
||||
{
|
||||
}
|
||||
|
||||
// Destructor
|
||||
Item_tracker::~Item_tracker()
|
||||
ItemTracker::~ItemTracker()
|
||||
{
|
||||
list.clear();
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
@@ -31,7 +31,7 @@ bool Item_tracker::hasBeenPicked(std::string name, SDL_Point pos)
|
||||
}
|
||||
|
||||
// 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
|
||||
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
|
||||
int Item_tracker::findByName(std::string name)
|
||||
int ItemTracker::findByName(std::string name)
|
||||
{
|
||||
const int c = -1;
|
||||
|
||||
@@ -71,7 +71,7 @@ int Item_tracker::findByName(std::string name)
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ struct item_tracker_t
|
||||
};
|
||||
|
||||
// Clase Item_tracker
|
||||
class Item_tracker
|
||||
class ItemTracker
|
||||
{
|
||||
private:
|
||||
std::vector<item_tracker_t> list; // Lista con todos los objetos recogidos
|
||||
@@ -28,10 +28,10 @@ private:
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
Item_tracker();
|
||||
ItemTracker();
|
||||
|
||||
// Destructor
|
||||
~Item_tracker();
|
||||
~ItemTracker();
|
||||
|
||||
// Comprueba si el objeto ya ha sido cogido
|
||||
bool hasBeenPicked(std::string name, SDL_Point pos);
|
||||
|
||||
@@ -140,6 +140,7 @@ bool Prog::setFileList()
|
||||
// Ficheros del mapa
|
||||
asset->add("/data/map/01.map", 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.tmx", data);
|
||||
asset->add("/data/map/03.map", data);
|
||||
|
||||
Reference in New Issue
Block a user