diff --git a/data/map/01.ene b/data/map/01.ene new file mode 100644 index 0000000..6e4b13f --- /dev/null +++ b/data/map/01.ene @@ -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] \ No newline at end of file diff --git a/source/enemy.cpp b/source/enemy.cpp index 8c450b2..68d590b 100644 --- a/source/enemy.cpp +++ b/source/enemy.cpp @@ -2,6 +2,11 @@ #include #include +// 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() { diff --git a/source/enemy.h b/source/enemy.h index 61ee167..f500151 100644 --- a/source/enemy.h +++ b/source/enemy.h @@ -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(); diff --git a/source/enemy_engine.cpp b/source/enemy_engine.cpp new file mode 100644 index 0000000..6c1f81d --- /dev/null +++ b/source/enemy_engine.cpp @@ -0,0 +1,196 @@ +#include "enemy_engine.h" +#include +#include + +// 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 != "") + { + std::stringstream ss(line); + std::string tmp; + while (getline(ss, tmp, ',')) + { + tilemap.push_back(std::stoi(tmp)); + } + } + } while (line != ""); + } + } + } + } + } 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; +} diff --git a/source/enemy_engine.h b/source/enemy_engine.h new file mode 100644 index 0000000..1f95b19 --- /dev/null +++ b/source/enemy_engine.h @@ -0,0 +1,43 @@ +#pragma once + +#include +#include "utils.h" +#include "asset.h" +#include "enemy.h" +#include "enemy_path.h" +#include "map.h" +#include "player.h" +#include +#include + +#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 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 diff --git a/source/enemy_path.cpp b/source/enemy_path.cpp new file mode 100644 index 0000000..3dbe04b --- /dev/null +++ b/source/enemy_path.cpp @@ -0,0 +1,43 @@ +#include "enemy_path.h" +#include +#include + +// 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(); + } +} \ No newline at end of file diff --git a/source/enemy_path.h b/source/enemy_path.h new file mode 100644 index 0000000..2a483d1 --- /dev/null +++ b/source/enemy_path.h @@ -0,0 +1,33 @@ +#pragma once + +#include +#include "enemy.h" +#include + +#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 diff --git a/source/game.cpp b/source/game.cpp index 85aec77..7c656da 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -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); } diff --git a/source/game.h b/source/game.h index cd479f7..45ba0d6 100644 --- a/source/game.h +++ b/source/game.h @@ -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 diff --git a/source/item_tracker.cpp b/source/item_tracker.cpp index 2196ea9..ba4072f 100644 --- a/source/item_tracker.cpp +++ b/source/item_tracker.cpp @@ -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; diff --git a/source/item_tracker.h b/source/item_tracker.h index 8f80f58..5e4ee60 100644 --- a/source/item_tracker.h +++ b/source/item_tracker.h @@ -15,7 +15,7 @@ struct item_tracker_t }; // Clase Item_tracker -class Item_tracker +class ItemTracker { private: std::vector 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); diff --git a/source/prog.cpp b/source/prog.cpp index 06013f7..611c912 100644 --- a/source/prog.cpp +++ b/source/prog.cpp @@ -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);