#include "game.h" // Constructor Game::Game(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, Lang *lang, Input *input) { // Copia los punteros mRenderer = renderer; mAsset = asset; mLang = lang; mInput = input; // Crea los objetos mScreen = new Screen(window, renderer); mRoom = new Room(mAsset->get("01.room"), mRenderer, mAsset); mPlayer = new Player(mAsset->get("player01.png"), mRenderer, mAsset, mInput, mRoom); mEventHandler = new SDL_Event(); mTextureText = new LTexture(); mText = new Text(mAsset->get("smb2.txt"), mTextureText, renderer); mFade = new Fade(renderer); } Game::~Game() { // Borra las referencias a los punteros mRenderer = nullptr; mAsset = nullptr; mLang = nullptr; mInput = nullptr; // Libera la memoria de los objetos delete mEventHandler; mEventHandler = nullptr; mTextureText->unload(); delete mTextureText; mTextureText = nullptr; delete mScreen; mScreen = nullptr; delete mRoom; mRoom = nullptr; delete mRoom; mRoom = nullptr; delete mText; mText = nullptr; delete mFade; mFade = nullptr; } // Inicializa las variables necesarias para la sección 'Game' void Game::init() { // Carga los recursos loadMedia(); mTicks = 0; mTicksSpeed = 15; mSection.name = SECTION_PROG_GAME; mSection.subsection = SECTION_GAME_PLAY; } // Carga los recursos necesarios para la sección 'Game' bool Game::loadMedia() { bool success = true; // Texturas success &= loadTextureFromFile(mTextureText, mAsset->get("smb2.png"), mRenderer); return success; } // Bucle para el juego section_t Game::run() { init(); while (mSection.name == SECTION_PROG_GAME) { // Sección juego jugando if (mSection.subsection == SECTION_GAME_PLAY) { update(); draw(); } } return mSection; } // Actualiza el juego, las variables, comprueba la entrada, etc. void Game::update() { // Comprueba que la diferencia de ticks sea mayor a la velocidad del juego if (SDL_GetTicks() - mTicks > mTicksSpeed) { // Actualiza el contador de ticks mTicks = SDL_GetTicks(); // Comprueba los eventos que hay en la cola while (SDL_PollEvent(mEventHandler) != 0) { // Evento de salida de la aplicación if (mEventHandler->type == SDL_QUIT) { mSection.name = SECTION_PROG_QUIT; break; } } mRoom->update(); mPlayer->update(); checkPlayerAndWalls(); // Debe ir detras del player update, por si se ha metido en algun muro checkPlayerOnBorder(); checkPlayerOnFloor(); } } // Pinta los objetos en pantalla void Game::draw() { // Prepara para dibujar el frame mScreen->start(); mScreen->clean(mRoom->getBGColor()); mRoom->drawMap(); mRoom->drawEnemies(); mPlayer->draw(); // Texto en el centro de la pantalla SDL_Rect rect = {0, 16 * 8, PLAY_AREA_RIGHT, 8}; color_t color = stringToColor("light_black"); SDL_SetRenderDrawColor(mRenderer, color.r, color.g, color.b, 0xFF); SDL_RenderFillRect(mRenderer, &rect); mText->writeCentered(GAMECANVAS_CENTER_X, 16 * 8, mRoom->getName()); // Debug info std::string text; text = "status: " + std::to_string(mPlayer->status); mText->write(0, 17 * 8, text); // Actualiza la pantalla mScreen->blit(); } // Comprueba la entrada /* void Game::checkInput() { if (mInput->checkInput(INPUT_UP, REPEAT_FALSE)) changeRoom(mRoom->getRoomUp()); if (mInput->checkInput(INPUT_DOWN, REPEAT_FALSE)) changeRoom(mRoom->getRoomDown()); if (mInput->checkInput(INPUT_LEFT, REPEAT_FALSE)) changeRoom(mRoom->getRoomLeft()); if (mInput->checkInput(INPUT_RIGHT, REPEAT_FALSE)) changeRoom(mRoom->getRoomRight()); } */ // Cambia de habitación bool Game::changeRoom(std::string file) { bool success = false; // En las habitaciones los limites tienen la cadena del fichero o un 0 en caso de no limitar con nada if (file != "0") // Verifica que exista el fichero que se va a cargar if (mAsset->get(file) != "") { // Elimina la habitación actual delete mRoom; mRoom = nullptr; // Crea un objeto habitación nuevo a partir del fichero mRoom = new Room(mAsset->get(file), mRenderer, mAsset); // Comunica al jugador la nueva referencia para la habitación mPlayer->setRoom(mRoom); success = true; } return success; } // Comprueba si el jugador esta en el borde de la pantalla void Game::checkPlayerOnBorder() { if (mPlayer->getOnBorder()) { changeRoom(mRoom->getRoom(mPlayer->getBorder())); mPlayer->switchBorders(); } } // Comprueba si el jugador esta sobre el suelo void Game::checkPlayerOnFloor() { // Comprueba ambos pies if ((mRoom->isFloor(mPlayer->getLeftFoot())) || (mRoom->isFloor(mPlayer->getRightFoot()))) { mPlayer->setStatus(STATUS_STANDING); } else if (mPlayer->getStatus() != STATUS_JUMPING) { mPlayer->setStatus(STATUS_FALLING); } } // Comprueba que el jugador no atraviese ninguna pared void Game::checkPlayerAndWalls() { // Comprueba las cuatro esquinas de los dos tiles del jugador SDL_Rect rect = mPlayer->getRect(); SDL_Point p1 = {rect.x, rect.y}; SDL_Point p2 = {rect.x + 7, rect.y}; SDL_Point p3 = {rect.x + 7, rect.y + 7}; SDL_Point p4 = {rect.x, rect.y + 7}; SDL_Point p5 = {rect.x, rect.y + 8}; SDL_Point p6 = {rect.x + 7, rect.y + 8}; SDL_Point p7 = {rect.x + 7, rect.y + 15}; SDL_Point p8 = {rect.x, rect.y + 15}; bool test = mRoom->isFloor(p1); test |= mRoom->isFloor(p2); test |= mRoom->isFloor(p3); test |= mRoom->isFloor(p4); test |= mRoom->isFloor(p5); test |= mRoom->isFloor(p6); test |= mRoom->isFloor(p7); test |= mRoom->isFloor(p8); if (test) { // Si hay colisión, deshace el movimiento y lo pone en modo caída mPlayer->undoLastMove(); mPlayer->setStatus(STATUS_FALLING); } }