diff --git a/data/config/demo.bin b/data/config/demo1.bin similarity index 100% rename from data/config/demo.bin rename to data/config/demo1.bin diff --git a/data/config/demo2.bin b/data/config/demo2.bin new file mode 100644 index 0000000..4b63448 Binary files /dev/null and b/data/config/demo2.bin differ diff --git a/source/const.h b/source/const.h index f16010a..5d9c0f0 100644 --- a/source/const.h +++ b/source/const.h @@ -6,6 +6,8 @@ #ifndef CONST_H #define CONST_H +#define RECORDING + // Tamaño de bloque #define BLOCK 8 #define HALF_BLOCK BLOCK / 2 diff --git a/source/director.cpp b/source/director.cpp index ba097c4..a40fca8 100644 --- a/source/director.cpp +++ b/source/director.cpp @@ -16,7 +16,12 @@ Director::Director(int argc, char *argv[]) { // Inicializa variables section = new section_t(); +#ifdef RECORDING + section->name = SECTION_PROG_GAME; + section->subsection = SUBSECTION_GAME_PLAY_1P; +#else section->name = SECTION_PROG_LOGO; +#endif // Comprueba los parametros del programa checkProgramArguments(argc, argv); @@ -279,7 +284,8 @@ bool Director::setFileList() asset->add(systemFolder + "/config.txt", t_data, false, true); asset->add(systemFolder + "/score.bin", t_data, false, true); asset->add(prefix + "/data/config/param.txt", t_data); - asset->add(prefix + "/data/config/demo.bin", t_data); + asset->add(prefix + "/data/config/demo1.bin", t_data); + asset->add(prefix + "/data/config/demo2.bin", t_data); asset->add(prefix + "/data/config/gamecontrollerdb.txt", t_data); // Notificaciones @@ -419,7 +425,11 @@ void Director::initOptions() // Pone unos valores por defecto para las opciones // Opciones varias +#ifdef VERBOSE + options->console = true; +#else options->console = false; +#endif // Opciones de video options->video.mode = 0; @@ -818,7 +828,8 @@ void Director::runInstructions() // Ejecuta el juego en modo demo void Director::runDemoGame() { - demoGame = new Game(1, 0, renderer, screen, asset, lang, input, true, param, options, section, nullptr); + const int playerID = (rand() % 2) + 1; + demoGame = new Game(playerID, 0, renderer, screen, asset, lang, input, true, param, options, section, nullptr); demoGame->run(); delete demoGame; } diff --git a/source/game.cpp b/source/game.cpp index 9ad50f4..1f5464b 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -31,8 +31,25 @@ Game::Game(int playerID, int currentStage, SDL_Renderer *renderer, Screen *scree // Carga los recursos loadMedia(); - // Carga ficheros - loadDemoFile(); + // Inicializa los vectores con los datos para la demo + if (demo) + { + std::vector tmp; + this->demo.dataFile.clear(); + this->demo.dataFile.push_back(tmp); + this->demo.dataFile.push_back(tmp); + + // Aleatoriza la asignación del fichero + const int index1 = rand() % 2; + const int index2 = (index1 + 1) % 2; + loadDemoFile(asset->get("demo1.bin"), &this->demo.dataFile.at(index1)); + loadDemoFile(asset->get("demo2.bin"), &this->demo.dataFile.at(index2)); + } + +#ifdef RECORDING + // Prepara el vector para recoger los datos + //this->demo.dataFile[0].clear(); +#endif // Establece la máxima puntuación desde fichero o desde las puntuaciones online setHiScore(); @@ -171,14 +188,14 @@ void Game::init(int playerID) }; players.clear(); - // Crea los jugadores + // Crea los dos jugadores Player *player1 = new Player((PLAY_AREA_CENTER_FIRST_QUARTER_X * ((0 * 2) + 1)) - 11, PLAY_AREA_BOTTOM - 24, renderer, playerTextures[0], playerAnimations); players.push_back(player1); Player *player2 = new Player((PLAY_AREA_CENTER_FIRST_QUARTER_X * ((1 * 2) + 1)) - 11, PLAY_AREA_BOTTOM - 24, renderer, playerTextures[1], playerAnimations); players.push_back(player2); - // playerID es player 1 o player 2 + // Habilita el jugador seleccionado. playerID es player 1 o player 2 players[playerID - 1]->enable(true); // Variables relacionadas con la dificultad @@ -243,6 +260,7 @@ void Game::init(int playerID) powerBallCounter = 0; coffeeMachineEnabled = false; + // Inicializa las variables para el modo demo if (demo.enabled) { // Selecciona una pantalla al azar @@ -258,6 +276,13 @@ void Game::init(int playerID) currentStage = 6; } + // Activa o no al otro jugador + // if (rand() % 3 == 0) + { + const int otherPlayer = playerID == 1 ? 2 : 1; + players[otherPlayer - 1]->enable(true); + } + // Añade 0, 1 o 2 cafes al jugador for (int i = 0; i < rand() % 3; ++i) { @@ -286,7 +311,7 @@ void Game::init(int playerID) totalPowerToCompleteGame += stage[i].powerToComplete; } - // Modo demo + // Modo grabar demo #ifdef RECORDING demo.recording = true; #else @@ -603,13 +628,12 @@ bool Game::loadScoreFile() } // Carga el fichero de datos para la demo -bool Game::loadDemoFile() +bool Game::loadDemoFile(std::string f, std::vector *dataFile) { // Indicador de éxito en la carga bool success = true; - const std::string p = asset->get("demo.bin"); - const std::string filename = p.substr(p.find_last_of("\\/") + 1); - SDL_RWops *file = SDL_RWFromFile(p.c_str(), "r+b"); + const std::string filename = f.substr(f.find_last_of("\\/") + 1); + SDL_RWops *file = SDL_RWFromFile(f.c_str(), "r+b"); // El fichero no existe if (file == nullptr) @@ -620,7 +644,9 @@ bool Game::loadDemoFile() } // Creamos el fichero para escritura - file = SDL_RWFromFile(p.c_str(), "w+b"); + file = SDL_RWFromFile(f.c_str(), "w+b"); + + // Si no existe el fichero if (file != nullptr) { if (options->console) @@ -628,24 +654,26 @@ bool Game::loadDemoFile() std::cout << "New file (" << filename.c_str() << ") created!" << std::endl; } - // Inicializamos los datos + // Inicializas los datos y los guarda en el fichero + dataFile->clear(); for (int i = 0; i < TOTAL_DEMO_DATA; ++i) { - demo.keys.left = 0; - demo.keys.right = 0; - demo.keys.noInput = 0; - demo.keys.fire = 0; - demo.keys.fireLeft = 0; - demo.keys.fireRight = 0; - demo.dataFile[i] = demo.keys; - SDL_RWwrite(file, &demo.dataFile[i], sizeof(demoKeys_t), 1); + demoKeys_t tmp; + tmp.left = 0; + tmp.right = 0; + tmp.noInput = 0; + tmp.fire = 0; + tmp.fireLeft = 0; + tmp.fireRight = 0; + dataFile->push_back(tmp); + SDL_RWwrite(file, &tmp, sizeof(demoKeys_t), 1); } // Cerramos el fichero SDL_RWclose(file); } else - { + { // Si no puede crear el fichero if (options->console) { std::cout << "Error: Unable to create file " << filename.c_str() << std::endl; @@ -656,13 +684,22 @@ bool Game::loadDemoFile() // El fichero existe else { - // Cargamos los datos + // Mensaje de proceder a la carga de los datos if (options->console) { std::cout << "Reading file " << filename.c_str() << std::endl; } + + // Inicializa el destino + dataFile->clear(); + + // Lee todos los datos del fichero y los deja en el destino for (int i = 0; i < TOTAL_DEMO_DATA; ++i) - SDL_RWread(file, &demo.dataFile[i], sizeof(demoKeys_t), 1); + { + demoKeys_t tmp; + SDL_RWread(file, &tmp, sizeof(demoKeys_t), 1); + dataFile->push_back(tmp); + } // Cierra el fichero SDL_RWclose(file); @@ -709,17 +746,16 @@ bool Game::saveScoreFile() bool Game::saveDemoFile() { bool success = true; - const std::string p = asset->get("demo.bin"); + const std::string p = asset->get("demo1.bin"); const std::string filename = p.substr(p.find_last_of("\\/") + 1); - if (demo.recording) - { + SDL_RWops *file = SDL_RWFromFile(p.c_str(), "w+b"); if (file != nullptr) { // Guardamos los datos for (int i = 0; i < TOTAL_DEMO_DATA; ++i) { - SDL_RWwrite(file, &demo.dataFile[i], sizeof(demoKeys_t), 1); + SDL_RWwrite(file, &demo.dataFile[0][i], sizeof(demoKeys_t), 1); } if (options->console) @@ -737,7 +773,7 @@ bool Game::saveDemoFile() std::cout << "Error: Unable to save " << filename.c_str() << " file! " << SDL_GetError() << std::endl; } } - } + return success; } #endif @@ -1551,7 +1587,7 @@ void Game::updatePlayers() { killPlayer(player); - if (demo.enabled && !player->isAlive()) + if (demo.enabled && allPlayersAreDead()) { fade->setType(FADE_RANDOM_SQUARE); fade->activate(); @@ -1631,13 +1667,7 @@ void Game::updateStage() void Game::updateDeath() { // Comprueba si todos los jugadores estan muertos - bool allPlayersAreDead = true; - for (auto player : players) - { - allPlayersAreDead &= (!player->isAlive() || !player->isEnabled()); - } - - if (allPlayersAreDead) + if (allPlayersAreDead()) { if (deathCounter > 0) { @@ -2533,24 +2563,22 @@ void Game::update() // Actualiza el contador de juego counter++; - // Incrementa el contador de la demo if (demo.enabled) { + // Incrementa el contador de la demo if (demo.counter < TOTAL_DEMO_DATA) { demo.counter++; - if (demo.counter == TOTAL_DEMO_DATA - 200) - { - fade->setType(FADE_RANDOM_SQUARE); - fade->activate(); - } } - else + + // Activa el fundido antes de acabar con los datos de la demo + if (demo.counter == TOTAL_DEMO_DATA - 200) { - section->name = SECTION_PROG_HI_SCORE_TABLE; - return; + fade->setType(FADE_RANDOM_SQUARE); + fade->activate(); } - + + // Si ha terminado el fundido, cambia de sección if (fade->hasEnded()) { section->name = SECTION_PROG_HI_SCORE_TABLE; @@ -2559,15 +2587,20 @@ void Game::update() } #ifdef RECORDING + // Solo mira y guarda el input en cada update checkInput(); - if (demo.recording) + // Incrementa el contador de la demo + if (demo.counter < TOTAL_DEMO_DATA) { - if (demo.counter >= TOTAL_DEMO_DATA) - { - section->name = SECTION_PROG_QUIT; - return; - } + demo.counter++; + } + + // Si se ha llenado el vector con datos, sale del programa + else + { + section->name = SECTION_PROG_QUIT; + return; } #endif @@ -2760,59 +2793,67 @@ void Game::checkInput() // Modo Demo activo if (demo.enabled) { - const int index = 0; - // Comprueba direcciones - if (demo.dataFile[demo.counter].left == 1) + for (auto player : players) { - players[index]->setInput(input_left); - } - - else if (demo.dataFile[demo.counter].right == 1) - { - players[index]->setInput(input_right); - } - - else if (demo.dataFile[demo.counter].noInput == 1) - { - players[index]->setInput(input_null); - } - - // Comprueba botones - if (demo.dataFile[demo.counter].fire == 1) - { - if (players[index]->canFire()) + int i = 0; + if (player->isAlive() && player->isEnabled()) { - players[index]->setInput(input_fire_center); - createBullet(players[index]->getPosX() + (players[index]->getWidth() / 2) - 4, players[index]->getPosY() + (players[index]->getHeight() / 2), BULLET_UP, players[index]->isPowerUp(), index); - players[index]->setFireCooldown(10); - } - } + // Comprueba direcciones + if (demo.dataFile[i][demo.counter].left == 1) + { + player->setInput(input_left); + } - else if (demo.dataFile[demo.counter].fireLeft == 1) - { - if (players[index]->canFire()) - { - players[index]->setInput(input_fire_left); - createBullet(players[index]->getPosX() + (players[index]->getWidth() / 2) - 4, players[index]->getPosY() + (players[index]->getHeight() / 2), BULLET_LEFT, players[index]->isPowerUp(), index); - players[index]->setFireCooldown(10); - } - } + else if (demo.dataFile[i][demo.counter].right == 1) + { + player->setInput(input_right); + } - else if (demo.dataFile[demo.counter].fireRight == 1) - { - if (players[index]->canFire()) - { - players[index]->setInput(input_fire_right); - createBullet(players[index]->getPosX() + (players[index]->getWidth() / 2) - 4, players[index]->getPosY() + (players[index]->getHeight() / 2), BULLET_RIGHT, players[index]->isPowerUp(), index); - players[index]->setFireCooldown(10); - } - } + else if (demo.dataFile[i][demo.counter].noInput == 1) + { + player->setInput(input_null); + } - // Si se pulsa cualquier tecla, se sale del modo demo - if (input->checkAnyButtonPressed()) - { - section->name = SECTION_PROG_TITLE; - return; + // Comprueba botones + if (demo.dataFile[i][demo.counter].fire == 1) + { + if (player->canFire()) + { + player->setInput(input_fire_center); + createBullet(player->getPosX() + (player->getWidth() / 2) - 4, player->getPosY() + (player->getHeight() / 2), BULLET_UP, player->isPowerUp(), i); + player->setFireCooldown(10); + } + } + + else if (demo.dataFile[i][demo.counter].fireLeft == 1) + { + if (player->canFire()) + { + player->setInput(input_fire_left); + createBullet(player->getPosX() + (player->getWidth() / 2) - 4, player->getPosY() + (player->getHeight() / 2), BULLET_LEFT, player->isPowerUp(), i); + player->setFireCooldown(10); + } + } + + else if (demo.dataFile[i][demo.counter].fireRight == 1) + { + if (player->canFire()) + { + player->setInput(input_fire_right); + createBullet(player->getPosX() + (player->getWidth() / 2) - 4, player->getPosY() + (player->getHeight() / 2), BULLET_RIGHT, player->isPowerUp(), i); + player->setFireCooldown(10); + } + } + + // Si se pulsa cualquier tecla, se sale del modo demo + if (input->checkAnyButtonPressed()) + { + section->name = SECTION_PROG_TITLE; + return; + } + } + + i++; } } // Modo Demo no activo @@ -2914,7 +2955,7 @@ void Game::checkInput() { if (demo.counter < TOTAL_DEMO_DATA) { - demo.dataFile[demo.counter] = demo.keys; + demo.dataFile[0][demo.counter] = demo.keys; } } #endif @@ -2956,7 +2997,7 @@ void Game::renderMessages() { if (timeStoppedCounter % 30 == 0) { - //JA_PlaySound(clockSound, false); + // JA_PlaySound(clockSound, false); JA_PlaySound(clockSound); } } @@ -2964,7 +3005,7 @@ void Game::renderMessages() { if (timeStoppedCounter % 15 == 0) { - //JA_PlaySound(clockSound, false); + // JA_PlaySound(clockSound, false); JA_PlaySound(clockSound); } } @@ -3220,7 +3261,7 @@ bool Game::allPlayersAreDead() bool success = true; for (auto player : players) { - success &= (!player->isAlive()); + success &= (!player->isAlive() || !player->isEnabled()); } return success; @@ -3355,10 +3396,15 @@ void Game::setHiScore() // Actualiza el marcador void Game::updateScoreboard() { + // Jugador 1 scoreboard->setScore1(players[0]->getScore()); scoreboard->setMult1(players[0]->getScoreMultiplier()); - scoreboard->setScore2(players[0]->getScore()); - scoreboard->setMult2(players[0]->getScoreMultiplier()); + + // Jugador 2 + scoreboard->setScore2(players[1]->getScore()); + scoreboard->setMult2(players[1]->getScoreMultiplier()); + + // Resto de marcador scoreboard->setStage(stage[currentStage].number); scoreboard->setPower((float)stage[currentStage].currentPower / (float)stage[currentStage].powerToComplete); scoreboard->setHiScore(hiScore); diff --git a/source/game.h b/source/game.h index 64b91a5..0066374 100644 --- a/source/game.h +++ b/source/game.h @@ -100,11 +100,11 @@ private: struct demo_t { - bool enabled; // Indica si está activo el modo demo - bool recording; // Indica si está activado el modo para grabar la demo - Uint16 counter; // Contador para el modo demo - demoKeys_t keys; // Variable con las pulsaciones de teclas del modo demo - demoKeys_t dataFile[TOTAL_DEMO_DATA]; // Datos del fichero con los movimientos para la demo + bool enabled; // Indica si está activo el modo demo + bool recording; // Indica si está activado el modo para grabar la demo + int counter; // Contador para el modo demo + demoKeys_t keys; // Variable con las pulsaciones de teclas del modo demo + demoKeys_t dataFile[2][TOTAL_DEMO_DATA]; // Vector con diferentes sets de datos con los movimientos para la demo }; // Objetos y punteros @@ -232,7 +232,7 @@ private: bool loadScoreFile(); // Carga el fichero de datos para la demo - bool loadDemoFile(); + bool loadDemoFile(std::string fileName, std::vector *dataFile); // Guarda el fichero de puntos bool saveScoreFile(); diff --git a/source/scoreboard.cpp b/source/scoreboard.cpp index d51b99c..33f2074 100644 --- a/source/scoreboard.cpp +++ b/source/scoreboard.cpp @@ -95,52 +95,62 @@ void Scoreboard::render() SDL_RenderCopy(renderer, background, nullptr, &rect); } +// Establece el valor de la variable void Scoreboard::setScore1(int score) { score1 = score; } +// Establece el valor de la variable void Scoreboard::setScore2(int score) { score2 = score; } +// Establece el valor de la variable void Scoreboard::setMult1(float mult) { mult1 = mult; } +// Establece el valor de la variable void Scoreboard::setMult2(float mult) { mult2 = mult; } +// Establece el valor de la variable void Scoreboard::setStage(int stage) { this->stage = stage; } +// Establece el valor de la variable void Scoreboard::setHiScore(int hiScore) { this->hiScore = hiScore; } +// Establece el valor de la variable void Scoreboard::setPower(float power) { this->power = power; } +// Establece el valor de la variable void Scoreboard::setHiScoreName(std::string name) { hiScoreName = name; } +// Establece el valor de la variable void Scoreboard::setColor(color_t color) { this->color = color; fillBackgroundTexture(); } +// Establece el valor de la variable void Scoreboard::setPos(SDL_Rect rect) { this->rect = rect; diff --git a/source/scoreboard.h b/source/scoreboard.h index 98aa075..44d0e93 100644 --- a/source/scoreboard.h +++ b/source/scoreboard.h @@ -74,15 +74,34 @@ public: // Pinta el marcador void render(); + // Establece el valor de la variable void setScore1(int score); + + // Establece el valor de la variable void setScore2(int score); + + // Establece el valor de la variable void setMult1(float mult); + + // Establece el valor de la variable void setMult2(float mult); + + // Establece el valor de la variable void setStage(int stage); + + // Establece el valor de la variable void setHiScore(int hiScore); + + // Establece el valor de la variable void setPower(float power); + + // Establece el valor de la variable void setHiScoreName(std::string name); + + // Establece el valor de la variable void setColor(color_t color); + + // Establece el valor de la variable void setPos(SDL_Rect rect); };