#include "game.h" // Constructor Game::Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input, Debug *debug) { // Copia punteros this->renderer = renderer; this->asset = asset; this->screen = screen; this->input = input; this->debug = debug; this->debug->setEnabled(true); // Reserva memoria para los objetos scoreboard = new ScoreBoard(renderer, asset, &board); eventHandler = new SDL_Event(); 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, asset->get(map->getEnemyFile())); music = JA_LoadMusic(asset->get("music_surface.ogg").c_str()); // Inicializa variables ticks = 0; ticksSpeed = 15; section.name = SECTION_PROG_GAME; section.subsection = SUBSECTION_GAME_PLAY; musicEnabled = !debug->getEnabled(); board.diamonds = 0; board.lives = 5; } // Destructor Game::~Game() { delete scoreboard; delete eventHandler; delete itemTracker; delete map; delete player; delete enemyEngine; JA_DeleteMusic(music); } // Bucle para el juego section_t Game::run() { JA_PlayMusic(music); if (!musicEnabled) { JA_PauseMusic(); } while (section.name == SECTION_PROG_GAME) { // Sección juego jugando if (section.subsection == SUBSECTION_GAME_PLAY) { update(); render(); } } JA_StopMusic(); return section; } // 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() - ticks > ticksSpeed) { // Actualiza el contador de ticks ticks = SDL_GetTicks(); // Comprueba los eventos de la cola checkEventHandler(); // Actualiza los objetos debug->clear(); scoreboard->update(); map->update(); enemyEngine->update(); player->update(); checkScreenBorders(); updateDebugInfo(); } } // Pinta los objetos en pantalla void Game::render() { // Prepara para dibujar el frame screen->start(); screen->clean(); // Dibuja los objetos map->render(); enemyEngine->render(); player->render(); scoreboard->render(); renderDebugInfo(); // Actualiza la pantalla screen->blit(); } // Comprueba los eventos de la cola void Game::checkEventHandler() { // Comprueba los eventos que hay en la cola while (SDL_PollEvent(eventHandler) != 0) { // Evento de salida de la aplicación if (eventHandler->type == SDL_QUIT) { section.name = SECTION_PROG_QUIT; break; } else if ((eventHandler->type == SDL_KEYDOWN) and (eventHandler->key.repeat == 0)) { switch (eventHandler->key.keysym.scancode) { case SDL_SCANCODE_ESCAPE: section.name = SECTION_PROG_QUIT; break; case SDL_SCANCODE_D: debug->switchEnabled(); musicEnabled = !debug->getEnabled(); musicEnabled ? JA_ResumeMusic() : JA_PauseMusic(); break; case SDL_SCANCODE_M: musicEnabled = !musicEnabled; musicEnabled ? JA_ResumeMusic() : JA_PauseMusic(); break; case SDL_SCANCODE_R: delete map; map = new Map(asset->get("01.map"), renderer, asset, itemTracker); delete player; player = new Player(renderer, asset, input, map); break; case SDL_SCANCODE_F: screen->switchVideoMode(); reLoadTextures(); break; case SDL_SCANCODE_F1: screen->setWindowSize(1); reLoadTextures(); break; case SDL_SCANCODE_F2: screen->setWindowSize(2); reLoadTextures(); break; case SDL_SCANCODE_F3: screen->setWindowSize(3); reLoadTextures(); break; case SDL_SCANCODE_F4: screen->setWindowSize(4); reLoadTextures(); break; default: break; } } } } // Pasa la información de debug void Game::updateDebugInfo() { debug->add("R - Reload player and map"); debug->add("D - Toggle debug mode"); debug->add(std::to_string((int)player->sprite->getPosX()) + "," + std::to_string((int)player->sprite->getPosY()) + "," + std::to_string((int)player->sprite->getWidth()) + "," + std::to_string((int)player->sprite->getHeight())); debug->add("VY " + std::to_string(player->vy) + " " + std::to_string(player->jumpStrenght)); debug->add("VX " + std::to_string(player->vx)); debug->add("jump_pressed " + std::to_string(player->jumpPressed)); debug->add("isOnFloor " + std::to_string(player->isOnFloor())); debug->add("getTile(" + std::to_string(player->underFeet[0].x) + "," + std::to_string(player->underFeet[0].y) + ") = " + std::to_string(player->map->getTile(player->underFeet[0]))); debug->add("state " + std::to_string(player->state)); debug->add(map->getName() + " (" + map->getRoomFileName(b_top) + ", " + map->getRoomFileName(b_right) + ", " + map->getRoomFileName(b_bottom) + ", " + map->getRoomFileName(b_left) + ")"); debug->add("hookedOn = " + std::to_string(player->hookedOnMovingPlatform)); debug->add("DIAMONDS = " + std::to_string(player->diamonds)); } // Pone la información de debug en pantalla void Game::renderDebugInfo() { if (!debug->getEnabled()) { return; } // Pinta la rejilla SDL_SetRenderDrawColor(renderer, 0, 0, 0, 16); for (int i = 0; i < 240; i += 8) { SDL_RenderDrawLine(renderer, 0, i, 320, i); } for (int i = 0; i < 320; i += 8) { SDL_RenderDrawLine(renderer, i, 0, i, 240); } // Pinta mascaras SDL_SetRenderDrawColor(renderer, 0, 255, 0, 128); SDL_Rect rect = player->sprite->getRect(); SDL_RenderFillRect(renderer, &rect); // Pinta el texto debug->setPos({1, PLAY_AREA_TOP}); debug->render(); } // Cambia el mapa bool Game::changeMap(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 (asset->get(file) != "") { // Elimina la habitación actual y crea un objeto nuevo a partir del fichero delete map; map = new Map(asset->get(file), renderer, asset, itemTracker); // Elimina el gestor de enemigos y crea uno nuevo a partir de un fichero delete enemyEngine; enemyEngine = new EnemyEngine(renderer, asset, player, map, asset->get(map->getEnemyFile())); success = true; } } return success; } // Comprueba si el jugador está en el borde y se ha de cambiar el mapa void Game::checkScreenBorders() { if (player->isOnScreenBorder()) { if (changeMap(map->getRoomFileName(player->getBorder()))) { player->setMap(map); player->switchBorders(); } } } // Recarga las texturas void Game::reLoadTextures() { map->reLoadTextures(); player->reLoadTextures(); scoreboard->reLoadTexture(); }