diff --git a/source/game.cpp b/source/game.cpp index 00776ac..c6beb0a 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -30,6 +30,7 @@ Game::Game(SDL_Renderer *renderer, Screen *screen, Asset *asset, Input *input) ticksSpeed = 15; playerLives = 9; itemsPicked = 0; + player->setInvincible(true); section.name = SECTION_PROG_GAME; section.subsection = SUBSECTION_GAME_PLAY; @@ -221,19 +222,19 @@ void Game::renderDebugInfo() const int inc = debugText->getCharacterWidth() + 1; int line = 131; - text = std::to_string((int)player->x) + "," + std::to_string((int)player->y); + text = std::to_string(player->getRect().x) + "," + std::to_string(player->getRect().y); debugText->write(0, line += inc, text); text = "status: " + std::to_string(player->status); debugText->write(0, line += inc, text); - // text = "foot: " + std::to_string((int)player->getLeftFoot().y); - // debugText->write(0, line += inc, text); + text = "foot: " + std::to_string((int)player->getLeftFoot().y); + debugText->write(0, line += inc, text); - // const int a = (player->lastPosition.y + 16) / 8; - // const int b = player->getLeftFoot().y / 8; - // text = "tile: " + std::to_string(a) + " - " + std::to_string(b); - // debugText->write(0, line += inc, text); + const int a = (player->lastPosition.y + 16) / 8; + const int b = player->getLeftFoot().y / 8; + text = "tile: " + std::to_string(a) + " - " + std::to_string(b); + debugText->write(0, line += inc, text); const bool collision = checkPlayerAndEnemies(); text = "collision: " + std::to_string(collision); @@ -313,6 +314,11 @@ void Game::checkPlayerAndItems() // Mata al jugador void Game::killPlayer() { + if (player->getInvincible()) + { + return; + } + playerLives--; // Destruye la habitacion y el jugador diff --git a/source/player.cpp b/source/player.cpp index f84e50b..6f7dd87 100644 --- a/source/player.cpp +++ b/source/player.cpp @@ -21,6 +21,7 @@ Player::Player(player_t ini, std::string tileset, std::string animation, SDL_Ren color = stringToColor("white"); onBorder = false; border = BORDER_TOP; + invincible = false; jump_ini = ini.jump_ini; status = ini.status; @@ -34,8 +35,6 @@ Player::Player(player_t ini, std::string tileset, std::string animation, SDL_Ren sprite->setPosX(ini.x); sprite->setPosY(ini.y); - sprite->setVelX(ini.vx); - sprite->setVelY(ini.vy); sprite->setWidth(8); sprite->setHeight(16); @@ -64,14 +63,11 @@ void Player::render() // Actualiza las variables del objeto void Player::update() { - setLastPosition(); // Guarda la posición actual en la variable lastPosition - checkInput(); // Comprueba las entradas y modifica variables - move(); // Recalcula la posición del jugador y su animación - checkBorders(); // Comprueba si está situado en alguno de los cuatro bordes de la habitación - applyGravity(); // Aplica gravedad al jugador - checkJump(); // Comprueba si ha finalizado el salto - checkOnFloor(); // Comprueba si el jugador esta sobre el suelo - colliderBox = getRect(); // Obtiene el rectangulo que delimita al jugador + checkInput(); // Comprueba las entradas y modifica variables + move(); // Recalcula la posición del jugador + animate(); // Establece la animación del jugador + checkBorders(); // Comprueba si está situado en alguno de los cuatro bordes de la habitación + checkJumpEnd(); // Comprueba si ha finalizado el salto al alcanzar la altura de inicio } // Comprueba las entradas y modifica variables @@ -114,22 +110,22 @@ int Player::getBorder() // Comprueba si está situado en alguno de los cuatro bordes de la habitación void Player::checkBorders() { - if (sprite->getPosX() < PLAY_AREA_LEFT) + if (x < PLAY_AREA_LEFT) { border = BORDER_LEFT; onBorder = true; } - else if (sprite->getPosX() > PLAY_AREA_RIGHT - sprite->getWidth()) + else if (x > PLAY_AREA_RIGHT - w) { border = BORDER_RIGHT; onBorder = true; } - else if (sprite->getPosY() < PLAY_AREA_TOP) + else if (y < PLAY_AREA_TOP) { border = BORDER_TOP; onBorder = true; } - else if (sprite->getPosY() > PLAY_AREA_BOTTOM - sprite->getHeight()) + else if (y > PLAY_AREA_BOTTOM - h) { border = BORDER_BOTTOM; onBorder = true; @@ -145,7 +141,7 @@ void Player::switchBorders() { if (border == BORDER_TOP) { - y = PLAY_AREA_BOTTOM - sprite->getHeight() - 1; + y = PLAY_AREA_BOTTOM - h - 1; jump_ini += 128; } else if (border == BORDER_BOTTOM) @@ -158,7 +154,7 @@ void Player::switchBorders() } if (border == BORDER_LEFT) { - x = PLAY_AREA_RIGHT - sprite->getWidth() - 1; + x = PLAY_AREA_RIGHT - w - 1; } onBorder = false; @@ -167,15 +163,13 @@ void Player::switchBorders() // Obtiene el valor del pixel inferior izquierdo del jugador SDL_Point Player::getLeftFoot() { - SDL_Point point = {(int)sprite->getPosX(), (int)sprite->getPosY() + sprite->getHeight()}; - return point; + return {(int)x, (int)y + h}; } // Obtiene el valor del pixel inferior derecho del jugador SDL_Point Player::getRightFoot() { - SDL_Point point = {(int)sprite->getPosX() + sprite->getWidth() - 1, (int)sprite->getPosY() + sprite->getHeight()}; - return point; + return {(int)x + 7, (int)y + h}; } // Cambia el estado del jugador @@ -211,12 +205,6 @@ int Player::getStatus() return status; } -// Obtiene la velocidad en el eje Y del jugador -float Player::getVelY() -{ - return sprite->getVelY(); -} - // Aplica gravedad al jugador void Player::applyGravity() { @@ -233,32 +221,22 @@ void Player::applyGravity() // Obtiene el rectangulo que delimita al jugador SDL_Rect Player::getRect() { - return sprite->getRect(); + return {(int)x, (int)y, w, h}; } // Obtiene el rectangulo de colision del jugador SDL_Rect &Player::getCollider() { + colliderBox = getRect(); return colliderBox; } -// Guarda la posición actual en la variable lastPosition -void Player::setLastPosition() -{ - lastPosition = getRect(); -} - -// Deshace el ultimo movimiento -void Player::undoLastMove() -{ - x = lastPosition.x; - y = lastPosition.y; -} - // Recalcula la posición del jugador y su animación void Player::move() { - const int tileSize = 8; + const int tileSize = room->getTileSize(); + lastPosition = {(int)x, (int)y}; + applyGravity(); // Calcula la nueva posición del jugador y compensa en caso de colisión x += vx; @@ -267,16 +245,16 @@ void Player::move() if (checkWalls()) { // Recoloca - if (vx > 0) + if (vx > 0.0f) { - x -= ((int)x + w) % tileSize; + x = (int)x - ((int)x + w) % tileSize; } else { - x += tileSize - ((int)x % tileSize); + x = (int)x + tileSize - ((int)x % tileSize); } - // vx = 0.0f; + //vx = 0.0f; } y += vy; @@ -284,16 +262,31 @@ void Player::move() { // Recoloca if (vy > 0.0f) - { - y -= ((int)y + h) % tileSize; + { // Bajando + // y -= ((int)y + h) % tileSize; + y -= 8; + setStatus(STATUS_STANDING); } else - { + { // Subiendo y += tileSize - ((int)y % tileSize); + setStatus(STATUS_FALLING); } - setStatus(STATUS_FALLING); + } + else + // Si no colisiona con los muros, comprueba los tiles atravesables + { + checkOnFloor(); } + // Actualiza la posición del sprite + sprite->setPosX(x); + sprite->setPosY(y); +} + +// Establece la animación del jugador +void Player::animate() +{ // Establece la animación if (vx != 0) { @@ -304,18 +297,14 @@ void Player::move() sprite->setCurrentAnimation("stand"); } sprite->animate(); - - // Actualiza la posición del sprite - sprite->setPosX(x); - sprite->setPosY(y); } -// Comprueba si ha finalizado el salto -void Player::checkJump() +// Comprueba si ha finalizado el salto al alcanzar la altura de inicio +void Player::checkJumpEnd() { if (status == STATUS_JUMPING) - if (sprite->getVelY() > 0) - if (sprite->getPosY() > jump_ini) + if (vy > 0) + if (y >= jump_ini) { setStatus(STATUS_FALLING); } @@ -324,45 +313,35 @@ void Player::checkJump() // Comprueba si el jugador esta sobre el suelo void Player::checkOnFloor() { - // Comprueba si tiene suelo bajo los pies solo cuando no hay velocidad de subida - // y solo cuando el pie este encima de un bloque, es decir, en multiplos de 8 + const int tileSize = room->getTileSize(); - // *** HAY UN POSIBLE PROBLEMA y es que caiga muy rapido y viaje a mas de un pixel de velocidad, - // con lo que se saltaria la comprobación - - // *** POSIBLE SOLUCION. Comprobar si el tile actual del pie es diferente al tile del pie previo. - // Esto indica que se ha saltado la comprobacion cada 8 pixeles. - // En este caso habría que recolocar al jugador en el sitio - - // *** PARECE RESUELTO - - const int a = (lastPosition.y + 16) / 8; - const int b = getLeftFoot().y / 8; + const int a = (lastPosition.y + h) / tileSize; + const int b = getLeftFoot().y / tileSize; const bool tile_change = a != b; - const bool is_not_going_up = getVelY() >= 0; - const bool is_tile_aligned = getLeftFoot().y % 8 == 0; + const bool going_down = vy >= 0.0f; + const bool is_tile_aligned = getLeftFoot().y % tileSize == 0; - if (((is_not_going_up) && (is_tile_aligned)) || ((is_not_going_up) && (tile_change))) + if (((going_down) && (is_tile_aligned)) || ((going_down) && (tile_change))) { - bool test = false; - test |= (room->getTile(getLeftFoot()) == TILE_SOLID); - test |= (room->getTile(getRightFoot()) == TILE_SOLID); - test |= (room->getTile(getLeftFoot()) == TILE_TRAVESSABLE); - test |= (room->getTile(getRightFoot()) == TILE_TRAVESSABLE); + bool onFloor = false; + onFloor |= (room->getTile(getLeftFoot()) == TILE_SOLID); + onFloor |= (room->getTile(getRightFoot()) == TILE_SOLID); + onFloor |= (room->getTile(getLeftFoot()) == TILE_TRAVESSABLE); + onFloor |= (room->getTile(getRightFoot()) == TILE_TRAVESSABLE); // Tiene uno de los pies sobre una superficie - if (test) + if (onFloor) { setStatus(STATUS_STANDING); - // Si ha habido un cambio de tile, hay que recolocarlo + // Si ha habido un cambio de tile recoloca al jugador if (tile_change) { - const int offset = (int)y % 8; - y = ((int)y - offset); + y = ((int)y - ((int)y % tileSize)); } } + // Tiene ambos pies sobre el vacío else if (getStatus() != STATUS_JUMPING) { @@ -393,10 +372,10 @@ player_t Player::getSpawnParams() { player_t params; - params.x = sprite->getPosX(); - params.y = sprite->getPosY(); - params.vx = sprite->getVelX(); - params.vy = sprite->getVelY(); + params.x = x; + params.y = y; + params.vx = vx; + params.vy = vy; params.jump_ini = jump_ini; params.status = status; params.flip = sprite->getFlip(); @@ -428,4 +407,16 @@ void Player::updateColliderPoints() colliderPoints[5] = {rect.x + 7, rect.y + 8}; colliderPoints[6] = {rect.x + 7, rect.y + 15}; colliderPoints[7] = {rect.x, rect.y + 15}; +} + +// Obtiene el valor de la variable +bool Player::getInvincible() +{ + return invincible; +} + +// Establece el valor de la variable +void Player::setInvincible(bool value) +{ + invincible = value; } \ No newline at end of file diff --git a/source/player.h b/source/player.h index c235aa6..42095c3 100644 --- a/source/player.h +++ b/source/player.h @@ -52,6 +52,7 @@ public: std::vector colliderPoints; // Puntos de colisión con el mapa bool onBorder; // Indica si el jugador esta en uno de los cuatro bordes de la pantalla int border; // Indica en cual de los cuatro bordes se encuentra + bool invincible; // Si es invencible, no puede morir // Comprueba las entradas y modifica variables void checkInput(); @@ -65,14 +66,14 @@ public: // Aplica gravedad al jugador void applyGravity(); - // Guarda la posición actual en la variable lastPosition - void setLastPosition(); - // Recalcula la posición del jugador y su animación void move(); - // Comprueba si ha finalizado el salto - void checkJump(); + // Establece la animación del jugador + void animate(); + + // Comprueba si ha finalizado el salto al alcanzar la altura de inicio + void checkJumpEnd(); // Comprueba si el jugador esta sobre el suelo void checkOnFloor(); @@ -122,18 +123,12 @@ public: // Obtiene el estado del jugador int getStatus(); - // Obtiene la velocidad en el eje Y del jugador - float getVelY(); - // Obtiene el rectangulo que delimita al jugador SDL_Rect getRect(); // Obtiene el rectangulo de colision del jugador SDL_Rect &getCollider(); - // Deshace el ultimo movimiento - void undoLastMove(); - // Obtiene algunos parametros del jugador player_t getSpawnParams(); @@ -142,6 +137,12 @@ public: // Establece el valor de la variable void setRoom(Room *room); + + // Obtiene el valor de la variable + bool getInvincible(); + + // Establece el valor de la variable + void setInvincible(bool value); }; #endif diff --git a/source/room.cpp b/source/room.cpp index 7a830fb..8c17617 100644 --- a/source/room.cpp +++ b/source/room.cpp @@ -566,4 +566,10 @@ void Room::reLoadTexture() { item->reLoadTexture(); } +} + +// Obten el tamaño del tile +int Room::getTileSize() +{ + return 8; } \ No newline at end of file diff --git a/source/room.h b/source/room.h index d874226..c87ed9d 100644 --- a/source/room.h +++ b/source/room.h @@ -109,6 +109,9 @@ public: // Recarga la textura void reLoadTexture(); + + // Obten el tamaño del tile + int getTileSize(); }; #endif