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);