From 3f3f50a583443abaf1082b0165e237dd58c9f75a Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Thu, 13 Oct 2022 12:02:05 +0200 Subject: [PATCH] =?UTF-8?q?A=C3=B1adido=20el=20modo=20demo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/const.h | 3 +- source/credits.cpp | 2 +- source/demo.cpp | 224 ++++++++++++++++++++++++++++++++++++++++++++ source/demo.h | 75 +++++++++++++++ source/director.cpp | 13 ++- source/director.h | 5 + source/game.cpp | 16 +--- source/game.h | 25 ++--- 8 files changed, 338 insertions(+), 25 deletions(-) create mode 100644 source/demo.cpp create mode 100644 source/demo.h diff --git a/source/const.h b/source/const.h index 55ddc3a..86e9442 100644 --- a/source/const.h +++ b/source/const.h @@ -53,7 +53,8 @@ const int GAMECANVAS_THIRD_QUARTER_Y = (GAMECANVAS_HEIGHT / 4) * 3; #define SECTION_PROG_TITLE 2 #define SECTION_PROG_CREDITS 3 #define SECTION_PROG_GAME 4 -#define SECTION_PROG_QUIT 5 +#define SECTION_PROG_DEMO 5 +#define SECTION_PROG_QUIT 6 // Subsecciones #define SUBSECTION_GAME_PLAY 0 diff --git a/source/credits.cpp b/source/credits.cpp index e8dad3c..939594c 100644 --- a/source/credits.cpp +++ b/source/credits.cpp @@ -176,7 +176,7 @@ void Credits::update() // Comprueba si ha terminado la sección if (counter > 1000) { - section.name = SECTION_PROG_LOGO; + section.name = SECTION_PROG_DEMO; } } } diff --git a/source/demo.cpp b/source/demo.cpp new file mode 100644 index 0000000..fd60efb --- /dev/null +++ b/source/demo.cpp @@ -0,0 +1,224 @@ +#include "demo.h" + +// Constructor +Demo::Demo(SDL_Renderer *renderer, Screen *screen, Asset *asset, Debug *debug) +{ + // Inicia algunas variables + board.iniClock = SDL_GetTicks(); + rooms.push_back("04.room"); + rooms.push_back("03.room"); + rooms.push_back("02.room"); + rooms.push_back("01.room"); + rooms.push_back("05.room"); + rooms.push_back("06.room"); + roomIndex = 0; + currentRoom = rooms.at(roomIndex); + + // Copia los punteros + this->renderer = renderer; + this->asset = asset; + this->screen = screen; + this->debug = debug; + + // Crea los objetos + itemTracker = new ItemTracker(); + scoreboard = new ScoreBoard(renderer, asset, &board); + room = new Room(asset->get(currentRoom), renderer, screen, asset, itemTracker, &board.items, debug); + eventHandler = new SDL_Event(); + text = new Text(asset->get("smb2.png"), asset->get("smb2.txt"), renderer); + + // Inicializa el resto de variables + counter = 0; + ticks = 0; + ticksSpeed = 15; + board.lives = 9; + board.items = 0; + board.rooms = 1; + const color_t c = room->getBorderColor(); + board.color = (c.r + c.g + c.b == 0) ? stringToColor("white") : c; // Si el color es negro lo cambia a blanco + + board.music = !debug->getEnabled(); + + section.name = SECTION_PROG_DEMO; + section.subsection = 0; +} + +Demo::~Demo() +{ + // Libera la memoria de los objetos + delete itemTracker; + delete scoreboard; + delete room; + delete eventHandler; + delete text; +} + +// Comprueba los eventos de la cola +void Demo::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; + screen->setBorderColor(stringToColor("black")); + 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_TITLE; + break; + + case SDL_SCANCODE_B: + screen->switchBorder(); + reLoadTextures(); + 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; + } + } + } +} + +// Bucle para el juego +section_t Demo::run() +{ + while (section.name == SECTION_PROG_DEMO) + { + update(); + render(); + } + + return section; +} + +// Actualiza el juego, las variables, comprueba la entrada, etc. +void Demo::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 + room->update(); + scoreboard->update(); + screen->updateFX(); + { + counter++; + if (counter == 400) + { + counter = 0; + roomIndex++; + if (roomIndex == (int)rooms.size()) + { + section.name = SECTION_PROG_TITLE; + } + else + { + changeRoom(rooms.at(roomIndex)); + } + } + } + } +} + +// Pinta los objetos en pantalla +void Demo::render() +{ + // Prepara para dibujar el frame + screen->start(); + screen->clean(room->getBGColor()); + + room->renderMap(); + room->renderEnemies(); + room->renderItems(); + renderRoomName(); + scoreboard->render(); + screen->renderFX(); + + text->write(0, 0, std::to_string(counter)); + + // Actualiza la pantalla + screen->blit(); +} + +// Escribe el nombre de la pantalla +void Demo::renderRoomName() +{ + // Texto en el centro de la pantalla + SDL_Rect rect = {0, 16 * BLOCK, PLAY_AREA_WIDTH, BLOCK * 2}; + color_t color = stringToColor("white"); + SDL_SetRenderDrawColor(renderer, color.r, color.g, color.b, 0xFF); + SDL_RenderFillRect(renderer, &rect); + + text->writeDX(TXT_CENTER | TXT_COLOR, GAMECANVAS_CENTER_X, 16 * 8 + 4, room->getName(), 1, room->getBGColor()); +} + +// Recarga todas las texturas +void Demo::reLoadTextures() +{ + room->reLoadTexture(); + scoreboard->reLoadTexture(); + text->reLoadTexture(); +} + +// Cambia de habitación +bool Demo::changeRoom(std::string file) +{ + // 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 + delete room; + room = nullptr; + + // Crea un objeto habitación nuevo a partir del fichero + room = new Room(asset->get(file), renderer, screen, asset, itemTracker, &board.items, debug); + + // Actualiza el marcador + const color_t c = room->getBorderColor(); // Pone el color del marcador + board.color = (c.r + c.g + c.b == 0) ? stringToColor("white") : c; // Si el color es negro lo cambia a blanco + + return true; + } + + return false; +} \ No newline at end of file diff --git a/source/demo.h b/source/demo.h new file mode 100644 index 0000000..faed501 --- /dev/null +++ b/source/demo.h @@ -0,0 +1,75 @@ +#pragma once + +#include +#include "const.h" +#include "item_tracker.h" +#include "room_tracker.h" +#include "room.h" +#include "scoreboard.h" +#include "utils/animatedsprite.h" +#include "utils/asset.h" +#include "utils/debug.h" +#include "utils/input.h" +#include "utils/screen.h" +#include "utils/sprite.h" +#include "utils/text.h" +#include "utils/utils.h" + +#ifndef DEMO_H +#define DEMO_H + +// Demo +class Demo +{ +private: + // Objetos + SDL_Renderer *renderer; // El renderizador de la ventana + SDL_Event *eventHandler; // Manejador de eventos + Screen *screen; // Objeto encargado de manejar el renderizador + Room *room; // Objeto encargado de gestionar cada habitación del juego + Asset *asset; // Objeto con la ruta a todos los ficheros de recursos + Text *text; // Objeto para los textos del juego + ScoreBoard *scoreboard; // Objeto encargado de gestionar el marcador + ItemTracker *itemTracker; // Lleva el control de los objetos recogidos + Debug *debug; // Objeto para gestionar la información de debug + + // Variables + Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa + Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa + section_t section; // Seccion actual dentro del juego + std::string currentRoom; // Fichero de la habitación actual + board_t board; // Estructura con los datos del marcador + int counter; // Contador para el modo demo + int roomIndex; // Indice para el vector de habitaciones + std::vector rooms; // Listado con los mapas de la demo + + // Actualiza el juego, las variables, comprueba la entrada, etc. + void update(); + + // Pinta los objetos en pantalla + void render(); + + // Comprueba los eventos de la cola + void checkEventHandler(); + + // Escribe el nombre de la pantalla + void renderRoomName(); + + // Recarga todas las texturas + void reLoadTextures(); + + // Cambia de habitación + bool changeRoom(std::string file); + +public: + // Constructor + Demo(SDL_Renderer *renderer, Screen *screen, Asset *asset, Debug *debug); + + // Destructor + ~Demo(); + + // Bucle para el juego + section_t run(); +}; + +#endif diff --git a/source/director.cpp b/source/director.cpp index 5f6a47e..c54ed00 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -9,7 +9,7 @@ Director::Director(std::string path) section.name = SECTION_PROG_LOGO; section.subsection = 0; - section.name = SECTION_PROG_GAME; + section.name = SECTION_PROG_CREDITS; // Crea el objeto que controla los ficheros de recursos asset = new Asset(path.substr(0, path.find_last_of("\\/"))); @@ -638,6 +638,14 @@ void Director::runCredits() delete credits; } +// Ejecuta la seccion de la demo, donde se ven pantallas del juego +void Director::runDemo() +{ + demo = new Demo(renderer, screen, asset, debug); + setSection(demo->run()); + delete demo; +} + // Ejecuta la seccion de juego donde se juega void Director::runGame() { @@ -665,6 +673,9 @@ void Director::run() case SECTION_PROG_CREDITS: runCredits(); break; + case SECTION_PROG_DEMO: + runDemo(); + break; case SECTION_PROG_GAME: runGame(); break; diff --git a/source/director.h b/source/director.h index fd65df3..2dc8815 100644 --- a/source/director.h +++ b/source/director.h @@ -1,5 +1,6 @@ #pragma once #include +#include "demo.h" #include "const.h" #include "credits.h" #include "game.h" @@ -31,6 +32,7 @@ private: Title *title; // Objeto para gestionar la pantalla de título Intro *intro; // Objeto para gestionar la introducción del juego Credits *credits; // Objeto para gestionar los creditos del juego + Demo *demo; // Objeto para gestionar el modo demo, en el que se ven pantallas del juego Asset *asset; // Objeto que gestiona todos los ficheros de recursos Debug *debug; // Objeto para getsionar la información de debug @@ -81,6 +83,9 @@ private: // Ejecuta la seccion de los creditos del juego void runCredits(); + // Ejecuta la seccion de la demo, donde se ven pantallas del juego + void runDemo(); + // Ejecuta la seccion de juego donde se juega void runGame(); diff --git a/source/game.cpp b/source/game.cpp index 88332ab..8e73224 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -110,10 +110,6 @@ void Game::checkEventHandler() board.music ? JA_ResumeMusic() : JA_PauseMusic(); break; - case SDL_SCANCODE_T: - screen->setspectrumFade(); - break; - case SDL_SCANCODE_P: if (paused) { @@ -238,7 +234,6 @@ void Game::render() // Debug info renderDebugInfo(); - // test->render(); screen->renderFX(); // Actualiza la pantalla @@ -248,9 +243,9 @@ void Game::render() // Pasa la información de debug void Game::updateDebugInfo() { - debug->add("X = " + std::to_string((int)player->x) + ", Y = " + std::to_string((int)player->y)); - debug->add("VX = " + std::to_string(player->vx).substr(0, 4) + ", VY = " + std::to_string(player->vy).substr(0, 4)); - debug->add("STATE = " + std::to_string(player->state)); + debug->add("X = " + std::to_string((int)player->x) + ", Y = " + std::to_string((int)player->y)); + debug->add("VX = " + std::to_string(player->vx).substr(0, 4) + ", VY = " + std::to_string(player->vy).substr(0, 4)); + debug->add("STATE = " + std::to_string(player->state)); } // Pone la información de debug en pantalla @@ -267,7 +262,7 @@ void Game::renderDebugInfo() SDL_RenderFillRect(renderer, &rect); // Pinta la rejilla - /*SDL_SetRenderDrawColor(renderer, 255, 255, 255, 32); + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 32); for (int i = 0; i < PLAY_AREA_BOTTOM; i += 8) { // Lineas horizontales SDL_RenderDrawLine(renderer, 0, i, PLAY_AREA_RIGHT, i); @@ -275,7 +270,7 @@ void Game::renderDebugInfo() for (int i = 0; i < PLAY_AREA_RIGHT; i += 8) { // Lineas verticales SDL_RenderDrawLine(renderer, i, 0, i, PLAY_AREA_BOTTOM - 1); - }*/ + } // Pinta el texto debug->setPos({1, 18 * 8}); @@ -416,7 +411,6 @@ void Game::reLoadTextures() void Game::setBlackScreen() { blackScreen = true; - // screen->setspectrumFade(); } // Actualiza las variables relativas a la pantalla en negro diff --git a/source/game.h b/source/game.h index 24908c2..0ff4682 100644 --- a/source/game.h +++ b/source/game.h @@ -25,6 +25,7 @@ class Game { private: + // Objetos SDL_Renderer *renderer; // El renderizador de la ventana SDL_Event *eventHandler; // Manejador de eventos Screen *screen; // Objeto encargado de manejar el renderizador @@ -36,20 +37,22 @@ private: Input *input; // Objeto pata gestionar la entrada Text *text; // Objeto para los textos del juego ScoreBoard *scoreboard; // Objeto encargado de gestionar el marcador - JA_Music music; // Musica que suena durante el juego Debug *debug; // Objeto para gestionar la información de debug - Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa - Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa - section_t section; // Seccion actual dentro del juego - std::string currentRoom; // Fichero de la habitación actual - player_t spawnPoint; // Lugar de la habitación donde aparece el jugador - JA_Sound deathSound; // Sonido a reproducir cuando muere el jugador - board_t board; // Estructura con los datos del marcador - bool paused; // Indica si el juego se encuentra en pausa - bool blackScreen; // Indica si la pantalla está en negro. Se utiliza para la muerte del jugador - int blackScreenCounter; // Contador para temporizar la pantalla en negro Test *test; + // Variables + JA_Music music; // Musica que suena durante el juego + Uint32 ticks; // Contador de ticks para ajustar la velocidad del programa + Uint32 ticksSpeed; // Velocidad a la que se repiten los bucles del programa + section_t section; // Seccion actual dentro del juego + std::string currentRoom; // Fichero de la habitación actual + player_t spawnPoint; // Lugar de la habitación donde aparece el jugador + JA_Sound deathSound; // Sonido a reproducir cuando muere el jugador + board_t board; // Estructura con los datos del marcador + bool paused; // Indica si el juego se encuentra en pausa + bool blackScreen; // Indica si la pantalla está en negro. Se utiliza para la muerte del jugador + int blackScreenCounter; // Contador para temporizar la pantalla en negro + // Actualiza el juego, las variables, comprueba la entrada, etc. void update();