diff --git a/data/room/06.tmx b/data/room/06.tmx index 64f9a00..b87f10e 100644 --- a/data/room/06.tmx +++ b/data/room/06.tmx @@ -3,7 +3,7 @@ -26,26,0,26,0,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, +26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, 26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,183,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26, 26,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,183,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26, 26,0,0,0,0,0,86,0,0,0,0,0,0,0,0,0,0,183,0,0,0,0,0,0,0,0,0,0,0,0,0,26, @@ -13,12 +13,12 @@ 26,0,0,0,0,0,0,0,0,0,0,0,0,162,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26, 26,0,0,0,0,0,0,0,0,0,0,0,162,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,26, 26,0,0,0,0,0,0,0,0,161,212,212,212,212,212,212,212,0,212,212,181,0,0,0,0,0,0,0,0,0,0,26, -26,0,0,0,0,0,0,0,161,0,0,0,0,0,0,0,0,0,0,0,0,181,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,161,0,0,0,0,0,0,0,0,0,269,0,0,0,0,181,0,0,0,0,0,0,0,0,26, -26,0,0,0,0,0,161,0,0,0,0,0,0,0,0,0,0,269,0,0,0,0,0,181,0,61,0,0,0,0,0,1, -0,0,0,0,0,161,0,0,0,0,0,0,0,0,0,0,0,289,0,0,0,0,0,0,181,0,0,0,0,0,0,1, -26,0,26,0,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, -26,0,26,0,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26 +26,0,0,0,0,0,0,0,161,0,0,0,0,0,0,0,0,0,0,0,0,181,0,0,0,0,0,0,0,0,0,26, +26,0,0,0,0,0,0,161,0,0,0,0,0,0,0,0,0,269,0,0,0,0,181,0,0,0,0,0,0,0,0,26, +26,0,0,0,0,0,161,0,0,0,0,0,0,0,0,0,0,269,0,0,0,0,0,181,0,0,0,0,0,0,0,0, +26,0,0,0,0,161,0,0,0,0,0,0,0,0,0,0,81,289,81,0,0,0,0,0,181,0,0,0,0,0,0,0, +26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26, +26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26,26 diff --git a/source/player.cpp b/source/player.cpp index b89bfa9..9aaf019 100644 --- a/source/player.cpp +++ b/source/player.cpp @@ -24,6 +24,7 @@ Player::Player(player_t ini, std::string tileset, std::string animation, SDL_Ren jump_ini = ini.jump_ini; state = ini.state; + prevState = state; x = ini.x; y = ini.y; @@ -62,6 +63,12 @@ void Player::render() { sprite->getTexture()->setColor(color.r, color.g, color.b); sprite->render(); + if (debug->getEnabled()) + { + SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255); + SDL_RenderDrawPoint(renderer, underFeet[0].x, underFeet[0].y); + SDL_RenderDrawPoint(renderer, underFeet[1].x, underFeet[1].y); + } } // Actualiza las variables del objeto @@ -78,34 +85,33 @@ void Player::update() void Player::checkInput() { // Solo comprueba las entradas de dirección cuando está dsobre una superficie - if (!isOnFloor()) + if (state != s_standing) { return; } - if ((input->checkInput(INPUT_LEFT, REPEAT_TRUE)) && (state == s_standing)) + if (input->checkInput(INPUT_LEFT, REPEAT_TRUE)) { vx = -0.6f; sprite->setFlip(SDL_FLIP_HORIZONTAL); } - else if ((input->checkInput(INPUT_RIGHT, REPEAT_TRUE)) && (state == s_standing)) + + else if (input->checkInput(INPUT_RIGHT, REPEAT_TRUE)) { vx = 0.6f; sprite->setFlip(SDL_FLIP_NONE); } - else if (state == s_standing) + + else { vx = 0.0f; } if (input->checkInput(INPUT_UP, REPEAT_TRUE)) { - if (state == s_standing) - { - state = s_jumping; - vy = -maxVY; - jump_ini = y; - } + setState(s_jumping); + vy = -maxVY; + jump_ini = y; } } @@ -153,6 +159,7 @@ void Player::checkBorders() // Comprueba el estado del jugador void Player::checkState() { + // Actualiza las variables en función del estado if (state == s_falling) { vx = 0.0f; @@ -194,8 +201,9 @@ void Player::applyGravity() { const float gf = 0.035f; - // La gravedad solo se aplica cuando no está sobre una superficie - if (!isOnFloor()) + // La gravedad solo se aplica cuando el jugador esta saltando + // Nunca mientras cae o esta de pie + if (state == s_jumping) { vy += gf; if (vy > maxVY) @@ -221,23 +229,18 @@ SDL_Rect &Player::getCollider() // Recalcula la posición del jugador y su animación void Player::move() { - const int tileSize = room->getTileSize(); lastPosition = {(int)x, (int)y}; // Guarda la posicion actual antes de modificarla applyGravity(); // Aplica gravedad al jugador checkState(); // Comprueba el estado del jugador - //-------------------------------------------------------------- - //--- NUEVA DETECCION DE COLISIONES --- - //-------------------------------------------------------------- - // Se mueve hacia la izquierda if (vx < 0.0f) { // Crea el rectangulo de proyección en el eje X para ver si colisiona SDL_Rect proj; - proj.x = lastPosition.x; - proj.y = lastPosition.y; - proj.h = h; + proj.x = (int)x; + proj.y = (int)y; + proj.h = h - 1; proj.w = (int)vx; // Comprueba la colisión @@ -259,9 +262,9 @@ void Player::move() { // Crea el rectangulo de proyección en el eje X para ver si colisiona SDL_Rect proj; - proj.x = lastPosition.x + w; - proj.y = lastPosition.y; - proj.h = h; + proj.x = (int)x + w; + proj.y = (int)y; + proj.h = h - 1; proj.w = (int)(vx); // Comprueba la colisión @@ -278,15 +281,21 @@ void Player::move() } } + // Si ha salido del suelo, el jugador cae + if (state == s_standing && !isOnFloor()) + { + setState(s_falling); + } + // Se mueve hacia arriba if (vy < 0.0f) { // Crea el rectangulo de proyección en el eje X para ver si colisiona SDL_Rect proj; - proj.x = lastPosition.x; - proj.y = lastPosition.y; + proj.x = (int)x; + proj.y = (int)y; proj.h = (int)vy; - proj.w = w; + proj.w = w - 1; // Comprueba la colisión const int pos = room->checkBottomSurfaces(&proj); @@ -297,9 +306,9 @@ void Player::move() y += vy; } else - { // Si hay colisión lo coloca donde colisiona + { // Si hay colisión lo coloca donde colisiona y entra en caída y = pos; - state = s_falling; + setState(s_falling); } } @@ -308,10 +317,10 @@ void Player::move() { // Crea el rectangulo de proyección en el eje X para ver si colisiona SDL_Rect proj; - proj.x = lastPosition.x; - proj.y = lastPosition.y + h; + proj.x = (int)x; + proj.y = (int)y + h; proj.h = (int)vy; - proj.w = w; + proj.w = w - 1; // Comprueba la colisión const int pos = room->checkTopSurfaces(&proj); @@ -322,9 +331,9 @@ void Player::move() y += vy; } else - { // Si hay colisión lo coloca donde colisiona + { // Si hay colisión lo coloca donde colisiona y pasa a estar sobre el suelo y = pos - h; - state = s_standing; + setState(s_standing); } } @@ -394,13 +403,13 @@ void Player::move() if (vy > 0.0f) { // Bajando y -= ((int)y + h) % tileSize; - state = s_standing; + setState(s_standing); vy = 0.0f; } else { // Subiendo y += tileSize - ((int)y % tileSize); - state = s_falling; + setState(s_falling); vy = maxVY; } } @@ -420,7 +429,7 @@ void Player::move() // Comprueba si tiene uno de los pies sobre una superficie if (isOnFloor()) { // Y deja al jugador de pie - state = s_standing; + setState(s_standing); vy = 0.0f; // Si ademas ha habido un cambio de tile recoloca al jugador @@ -433,7 +442,7 @@ void Player::move() // Si tiene ambos pies sobre el vacío y no está saltando else if (state != s_jumping) { - state = s_falling; + setState(s_falling); vy = maxVY; } } @@ -446,7 +455,7 @@ void Player::move() { if (state != s_jumping) { - state = s_falling; + setState(s_falling); vy = maxVY; } @@ -456,14 +465,14 @@ void Player::move() { if (isOnFloor()) { - state = s_standing; + setState(s_standing); vy = 0.0f; } } // EXPERIMENTAL else if (checkSlopes()) { - state = s_standing; + setState(s_standing); vy = 0.0f; } } @@ -489,8 +498,8 @@ void Player::checkJumpEnd() if (state == s_jumping) if (vy > 0) if (y >= jump_ini) - { - state = s_falling; + { // Si alcanza la altura de salto inicial, pasa al estado de caída + setState(s_falling); vy = maxVY; } } @@ -504,11 +513,13 @@ bool Player::isOnFloor() for (auto f : underFeet) { - const tile_e tile = (room->getTile(f)); - onFloor |= (tile == t_wall || tile == t_passable); + onFloor |= room->checkTopSurfaces(&f); } - debug->add("ONFLOOR = " + std::to_string(onFloor)); + if (onFloor) + { + debug->add("ONFLOOR"); + } return onFloor; } @@ -661,4 +672,11 @@ bool Player::getInvincible() void Player::setInvincible(bool value) { invincible = value; +} + +// Cambia el estado del jugador +void Player::setState(state_e value) +{ + prevState = state; + state = value; } \ No newline at end of file diff --git a/source/player.h b/source/player.h index e6ab9c1..841d5dd 100644 --- a/source/player.h +++ b/source/player.h @@ -55,6 +55,7 @@ public: std::vector underFeet; // Contiene los puntos que hay bajo cada pie del jugador std::vector feet; // Contiene los puntos que hay en el pie del jugador state_e state; // Estado en el que se encuentra el jugador. Util apara saber si está saltando o cayendo + state_e prevState; // Estado previo en el que se encontraba el jugador 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 @@ -104,6 +105,9 @@ public: // Actualiza los puntos de los pies void updateFeet(); + // Cambia el estado del jugador + void setState(state_e value); + public: // Constructor Player(player_t ini, std::string tileset, std::string animation, SDL_Renderer *renderer, Asset *asset, Input *input, Room *room, Debug *debug); diff --git a/source/room.cpp b/source/room.cpp index 6d6ba64..9b3b15d 100644 --- a/source/room.cpp +++ b/source/room.cpp @@ -437,14 +437,14 @@ void Room::fillMapTexture() { clip.x = ((tilemap[(y * 32) + x] - 1) % 20) * 8; clip.y = ((tilemap[(y * 32) + x] - 1) / 20) * 8; - // texture->render(renderer, x * 8, y * 8, &clip); + texture->render(renderer, x * 8, y * 8, &clip); if (debug->getEnabled()) { if (clip.x != -8) { clip.x = x * 8; clip.y = y * 8; - SDL_SetRenderDrawColor(renderer, 32, 32, 32, 0xFF); + SDL_SetRenderDrawColor(renderer, 48, 48, 48, 192); SDL_RenderFillRect(renderer, &clip); } } @@ -453,31 +453,43 @@ void Room::fillMapTexture() // **** if (debug->getEnabled()) { - for (auto l : bottomSurfaces) + if (true) { - SDL_SetRenderDrawColor(renderer, (rand() % 128) + 80, (rand() % 128) + 80, (rand() % 128) + 80, 0xFF); - SDL_RenderDrawLine(renderer, l.x1, l.y, l.x2, l.y); + for (auto l : bottomSurfaces) + { + SDL_SetRenderDrawColor(renderer, (rand() % 128) + 80, (rand() % 128) + 80, (rand() % 128) + 80, 0xFF); + SDL_RenderDrawLine(renderer, l.x1, l.y, l.x2, l.y); + } } - SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0x00, 0xFF); - for (auto l : topSurfaces) + if (true) { - SDL_SetRenderDrawColor(renderer, (rand() % 128) + 80, (rand() % 128) + 80, (rand() % 128) + 80, 0xFF); - SDL_RenderDrawLine(renderer, l.x1, l.y, l.x2, l.y); + SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0x00, 0xFF); + for (auto l : topSurfaces) + { + SDL_SetRenderDrawColor(renderer, (rand() % 128) + 80, (rand() % 128) + 80, (rand() % 128) + 80, 0xFF); + SDL_RenderDrawLine(renderer, l.x1, l.y, l.x2, l.y); + } } - SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF); - for (auto l : leftSurfaces) + if (true) { - SDL_SetRenderDrawColor(renderer, (rand() % 128) + 80, (rand() % 128) + 80, (rand() % 128) + 80, 0xFF); - SDL_RenderDrawLine(renderer, l.x, l.y1, l.x, l.y2); + SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF); + for (auto l : leftSurfaces) + { + SDL_SetRenderDrawColor(renderer, (rand() % 128) + 80, (rand() % 128) + 80, (rand() % 128) + 80, 0xFF); + SDL_RenderDrawLine(renderer, l.x, l.y1, l.x, l.y2); + } } - SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF); - for (auto l : rightSurfaces) + if (true) { - SDL_SetRenderDrawColor(renderer, (rand() % 128) + 80, (rand() % 128) + 80, (rand() % 128) + 80, 0xFF); - SDL_RenderDrawLine(renderer, l.x, l.y1, l.x, l.y2); + SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF); + for (auto l : rightSurfaces) + { + SDL_SetRenderDrawColor(renderer, (rand() % 128) + 80, (rand() % 128) + 80, (rand() % 128) + 80, 0xFF); + SDL_RenderDrawLine(renderer, l.x, l.y1, l.x, l.y2); + } } } // **** @@ -938,4 +950,17 @@ int Room::checkBottomSurfaces(SDL_Rect *rect) } return pos; +} + +// Comprueba las colisiones +bool Room::checkTopSurfaces(SDL_Point *p) +{ + bool collision = false; + + for (auto s : topSurfaces) + { + collision |= checkCollision(s, *p); + } + + return collision; } \ No newline at end of file diff --git a/source/room.h b/source/room.h index e819a6b..47f79f6 100644 --- a/source/room.h +++ b/source/room.h @@ -161,6 +161,9 @@ public: // Comprueba las colisiones int checkBottomSurfaces(SDL_Rect *rect); + + // Comprueba las colisiones + bool checkTopSurfaces(SDL_Point *p); }; #endif diff --git a/source/utils.cpp b/source/utils.cpp index fe92176..312c2c5 100644 --- a/source/utils.cpp +++ b/source/utils.cpp @@ -202,6 +202,37 @@ bool checkCollision(v_line_t &l, SDL_Rect &r) return true; } +// Detector de colisiones entre una linea horizontal y un punto +bool checkCollision(h_line_t &l, SDL_Point &p) +{ + // Comprueba si el punto esta sobre la linea + if (p.y > l.y) + { + return false; + } + + // Comprueba si el punto esta bajo la linea + if (p.y < l.y) + { + return false; + } + + // Comprueba si el punto esta a la izquierda de la linea + if (p.x < l.x1) + { + return false; + } + + // Comprueba si el punto esta a la derecha de la linea + if (p.x > l.x2) + { + return false; + } + + // Si ha llegado aquí, hay colisión + return true; +} + // Devuelve un color_t a partir de un string color_t stringToColor(std::string str) { diff --git a/source/utils.h b/source/utils.h index b533957..b3f2900 100644 --- a/source/utils.h +++ b/source/utils.h @@ -95,6 +95,9 @@ bool checkCollision(h_line_t &l, SDL_Rect &r); // Detector de colisiones entre una linea vertical y un rectangulo bool checkCollision(v_line_t &l, SDL_Rect &r); +// Detector de colisiones entre una linea horizontal y un punto +bool checkCollision(h_line_t &l, SDL_Point &p); + // Devuelve un color_t a partir de un string color_t stringToColor(std::string str);