Files
jaildoctors_dilemma/source/room.cpp

297 lines
7.2 KiB
C++

#include "room.h"
#include <iostream>
#include <fstream>
#include <sstream>
// Constructor
Room::Room(std::string _file_path, SDL_Renderer *_renderer, Asset *_asset)
{
texture = new LTexture();
asset = _asset;
renderer = _renderer;
load(_file_path);
loadTextureFromFile(texture, asset->get(tileset), renderer);
// Crea la textura para el mapa de tiles de la habitación
map_texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT);
if (map_texture == NULL)
printf("Error: map_texture could not be created!\nSDL Error: %s\n", SDL_GetError());
// Pinta el mapa de la habitación en la textura
fillMapTexture();
}
// Destructor
Room::~Room()
{
// Reclama la memoria utilizada por los objetos
texture->unload();
delete texture;
texture = nullptr;
SDL_DestroyTexture(map_texture);
map_texture = nullptr;
for (auto enemy : enemy_list)
{
delete enemy;
}
enemy_list.clear();
}
// Carga las variables desde un fichero
bool Room::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 [enemy] se realiza un proceso distinto
if (line == "[enemy]")
{
enemy_t enemy;
enemy.asset = asset;
enemy.renderer = renderer;
do
{
std::getline(file, line);
// Encuentra la posición del caracter '='
int pos = line.find("=");
// Procesa las dos subcadenas
if (!setEnemy(&enemy, 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 != "[enemy-end]");
// Añade el enemigo al vector de enemigos
enemy_list.push_back(new Enemy(enemy));
}
// 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", 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;
}
// Asigna variables a partir de dos cadenas
bool Room::setVars(std::string _var, std::string _value)
{
// Indicador de éxito en la asignación
bool success = true;
if (_var == "id")
{
id = _value;
}
else if (_var == "name")
{
name = _value;
}
else if (_var == "bg_color")
{
bg_color = stringToColor(_value);
}
else if (_var == "tileset")
{
tileset = _value;
}
else if (_var == "room_up")
{
room_up = _value;
}
else if (_var == "room_down")
{
room_down = _value;
}
else if (_var == "room_left")
{
room_left = _value;
}
else if (_var == "room_right")
{
room_right = _value;
}
else if (_var == "tilemap")
{
// Se introducen los valores separados por comas en un vector
std::stringstream ss(_value);
std::string tmp;
while (getline(ss, tmp, ','))
{
tilemap.push_back(std::stoi(tmp));
}
}
else
{
success = false;
}
return success;
}
// Asigna variables a una estructura enemy_t
bool Room::setEnemy(enemy_t *enemy, std::string _var, std::string _value)
{
// Indicador de éxito en la asignación
bool success = true;
if (_var == "tileset")
{
enemy->tileset = _value;
}
else if (_var == "x")
{
enemy->x = std::stof(_value);
}
else if (_var == "y")
{
enemy->y = std::stof(_value);
}
else if (_var == "vx")
{
enemy->vx = std::stof(_value);
}
else if (_var == "vy")
{
enemy->vy = std::stof(_value);
}
else if (_var == "x1")
{
enemy->x1 = std::stoi(_value);
}
else if (_var == "x2")
{
enemy->x2 = std::stoi(_value);
}
else if (_var == "y1")
{
enemy->y1 = std::stoi(_value);
}
else if (_var == "y2")
{
enemy->y2 = std::stoi(_value);
}
else if (_var == "color")
{
enemy->color = stringToColor(_value);
}
else
{
success = false;
}
return success;
}
// Devuelve el nombre de la habitación
std::string Room::getName()
{
return name;
}
// Devuelve el color de la habitación
color_t Room::getBGColor()
{
return bg_color;
}
// Crea la textura con el mapeado de la habitación
void Room::fillMapTexture()
{
SDL_SetRenderTarget(renderer, map_texture);
SDL_SetTextureBlendMode(map_texture, SDL_BLENDMODE_BLEND);
SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0x00);
SDL_RenderClear(renderer);
// Los tilesets son de 20x20 tiles. El primer tile es el 1. Cuentan hacia la derecha y hacia abajo
// printf("Filling map\n");
SDL_Rect clip = {0, 0, 8, 8};
for (int y = 0; y < 16; y++)
for (int x = 0; x < 32; x++)
{
clip.x = ((tilemap[(y * 32) + x] - 1) % 20) * 8;
clip.y = ((tilemap[(y * 32) + x] - 1) / 20) * 8;
// printf("tilemap [%i] = %i | x = %i | y = %i\n", ((y * 32) + x), tilemap[(y * 32) + x], clip.x, clip.y);
texture->render(renderer, x * 8, y * 8, &clip);
}
SDL_SetRenderTarget(renderer, nullptr);
}
// Dibuja el mapa en pantalla
void Room::drawMap()
{
SDL_Rect rect = {0, 0, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT};
// Dibuja la textura con el mapa en pantalla
SDL_RenderCopy(renderer, map_texture, &rect, NULL);
}
// Dibuja los enemigos en pantalla
void Room::drawEnemies()
{
for (auto enemy : enemy_list)
{
//enemy->draw();
}
}
// Devuelve el valor de la variable
std::string Room::getRoomUp()
{
return room_up;
}
// Devuelve el valor de la variable
std::string Room::getRoomDown()
{
return room_down;
}
// Devuelve el valor de la variable
std::string Room::getRoomLeft()
{
return room_left;
}
// Devuelve el valor de la variable
std::string Room::getRoomRight()
{
return room_right;
}