Completadas las colisiones y estados

This commit is contained in:
2022-09-08 21:31:51 +02:00
parent 88d6471dc8
commit 98916cd1be
7 changed files with 153 additions and 69 deletions

View File

@@ -3,7 +3,7 @@
<tileset firstgid="1" source="../../../jaildoctors_dilemma_resources/tilesets/standard.tsx"/> <tileset firstgid="1" source="../../../jaildoctors_dilemma_resources/tilesets/standard.tsx"/>
<layer id="1" name="Capa de patrones 1" width="32" height="16"> <layer id="1" name="Capa de patrones 1" width="32" height="16">
<data encoding="csv"> <data encoding="csv">
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,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,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, 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,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,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,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, 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,
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,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, 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,
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,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,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,
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
</data> </data>
</layer> </layer>
</map> </map>

View File

@@ -24,6 +24,7 @@ Player::Player(player_t ini, std::string tileset, std::string animation, SDL_Ren
jump_ini = ini.jump_ini; jump_ini = ini.jump_ini;
state = ini.state; state = ini.state;
prevState = state;
x = ini.x; x = ini.x;
y = ini.y; y = ini.y;
@@ -62,6 +63,12 @@ void Player::render()
{ {
sprite->getTexture()->setColor(color.r, color.g, color.b); sprite->getTexture()->setColor(color.r, color.g, color.b);
sprite->render(); 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 // Actualiza las variables del objeto
@@ -78,34 +85,33 @@ void Player::update()
void Player::checkInput() void Player::checkInput()
{ {
// Solo comprueba las entradas de dirección cuando está dsobre una superficie // Solo comprueba las entradas de dirección cuando está dsobre una superficie
if (!isOnFloor()) if (state != s_standing)
{ {
return; return;
} }
if ((input->checkInput(INPUT_LEFT, REPEAT_TRUE)) && (state == s_standing)) if (input->checkInput(INPUT_LEFT, REPEAT_TRUE))
{ {
vx = -0.6f; vx = -0.6f;
sprite->setFlip(SDL_FLIP_HORIZONTAL); 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; vx = 0.6f;
sprite->setFlip(SDL_FLIP_NONE); sprite->setFlip(SDL_FLIP_NONE);
} }
else if (state == s_standing)
else
{ {
vx = 0.0f; vx = 0.0f;
} }
if (input->checkInput(INPUT_UP, REPEAT_TRUE)) if (input->checkInput(INPUT_UP, REPEAT_TRUE))
{ {
if (state == s_standing) setState(s_jumping);
{ vy = -maxVY;
state = s_jumping; jump_ini = y;
vy = -maxVY;
jump_ini = y;
}
} }
} }
@@ -153,6 +159,7 @@ void Player::checkBorders()
// Comprueba el estado del jugador // Comprueba el estado del jugador
void Player::checkState() void Player::checkState()
{ {
// Actualiza las variables en función del estado
if (state == s_falling) if (state == s_falling)
{ {
vx = 0.0f; vx = 0.0f;
@@ -194,8 +201,9 @@ void Player::applyGravity()
{ {
const float gf = 0.035f; const float gf = 0.035f;
// La gravedad solo se aplica cuando no está sobre una superficie // La gravedad solo se aplica cuando el jugador esta saltando
if (!isOnFloor()) // Nunca mientras cae o esta de pie
if (state == s_jumping)
{ {
vy += gf; vy += gf;
if (vy > maxVY) if (vy > maxVY)
@@ -221,23 +229,18 @@ SDL_Rect &Player::getCollider()
// Recalcula la posición del jugador y su animación // Recalcula la posición del jugador y su animación
void Player::move() void Player::move()
{ {
const int tileSize = room->getTileSize();
lastPosition = {(int)x, (int)y}; // Guarda la posicion actual antes de modificarla lastPosition = {(int)x, (int)y}; // Guarda la posicion actual antes de modificarla
applyGravity(); // Aplica gravedad al jugador applyGravity(); // Aplica gravedad al jugador
checkState(); // Comprueba el estado del jugador checkState(); // Comprueba el estado del jugador
//--------------------------------------------------------------
//--- NUEVA DETECCION DE COLISIONES ---
//--------------------------------------------------------------
// Se mueve hacia la izquierda // Se mueve hacia la izquierda
if (vx < 0.0f) if (vx < 0.0f)
{ {
// Crea el rectangulo de proyección en el eje X para ver si colisiona // Crea el rectangulo de proyección en el eje X para ver si colisiona
SDL_Rect proj; SDL_Rect proj;
proj.x = lastPosition.x; proj.x = (int)x;
proj.y = lastPosition.y; proj.y = (int)y;
proj.h = h; proj.h = h - 1;
proj.w = (int)vx; proj.w = (int)vx;
// Comprueba la colisión // 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 // Crea el rectangulo de proyección en el eje X para ver si colisiona
SDL_Rect proj; SDL_Rect proj;
proj.x = lastPosition.x + w; proj.x = (int)x + w;
proj.y = lastPosition.y; proj.y = (int)y;
proj.h = h; proj.h = h - 1;
proj.w = (int)(vx); proj.w = (int)(vx);
// Comprueba la colisión // 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 // Se mueve hacia arriba
if (vy < 0.0f) if (vy < 0.0f)
{ {
// Crea el rectangulo de proyección en el eje X para ver si colisiona // Crea el rectangulo de proyección en el eje X para ver si colisiona
SDL_Rect proj; SDL_Rect proj;
proj.x = lastPosition.x; proj.x = (int)x;
proj.y = lastPosition.y; proj.y = (int)y;
proj.h = (int)vy; proj.h = (int)vy;
proj.w = w; proj.w = w - 1;
// Comprueba la colisión // Comprueba la colisión
const int pos = room->checkBottomSurfaces(&proj); const int pos = room->checkBottomSurfaces(&proj);
@@ -297,9 +306,9 @@ void Player::move()
y += vy; y += vy;
} }
else else
{ // Si hay colisión lo coloca donde colisiona { // Si hay colisión lo coloca donde colisiona y entra en caída
y = pos; 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 // Crea el rectangulo de proyección en el eje X para ver si colisiona
SDL_Rect proj; SDL_Rect proj;
proj.x = lastPosition.x; proj.x = (int)x;
proj.y = lastPosition.y + h; proj.y = (int)y + h;
proj.h = (int)vy; proj.h = (int)vy;
proj.w = w; proj.w = w - 1;
// Comprueba la colisión // Comprueba la colisión
const int pos = room->checkTopSurfaces(&proj); const int pos = room->checkTopSurfaces(&proj);
@@ -322,9 +331,9 @@ void Player::move()
y += vy; y += vy;
} }
else 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; y = pos - h;
state = s_standing; setState(s_standing);
} }
} }
@@ -394,13 +403,13 @@ void Player::move()
if (vy > 0.0f) if (vy > 0.0f)
{ // Bajando { // Bajando
y -= ((int)y + h) % tileSize; y -= ((int)y + h) % tileSize;
state = s_standing; setState(s_standing);
vy = 0.0f; vy = 0.0f;
} }
else else
{ // Subiendo { // Subiendo
y += tileSize - ((int)y % tileSize); y += tileSize - ((int)y % tileSize);
state = s_falling; setState(s_falling);
vy = maxVY; vy = maxVY;
} }
} }
@@ -420,7 +429,7 @@ void Player::move()
// Comprueba si tiene uno de los pies sobre una superficie // Comprueba si tiene uno de los pies sobre una superficie
if (isOnFloor()) if (isOnFloor())
{ // Y deja al jugador de pie { // Y deja al jugador de pie
state = s_standing; setState(s_standing);
vy = 0.0f; vy = 0.0f;
// Si ademas ha habido un cambio de tile recoloca al jugador // 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 // Si tiene ambos pies sobre el vacío y no está saltando
else if (state != s_jumping) else if (state != s_jumping)
{ {
state = s_falling; setState(s_falling);
vy = maxVY; vy = maxVY;
} }
} }
@@ -446,7 +455,7 @@ void Player::move()
{ {
if (state != s_jumping) if (state != s_jumping)
{ {
state = s_falling; setState(s_falling);
vy = maxVY; vy = maxVY;
} }
@@ -456,14 +465,14 @@ void Player::move()
{ {
if (isOnFloor()) if (isOnFloor())
{ {
state = s_standing; setState(s_standing);
vy = 0.0f; vy = 0.0f;
} }
} }
// EXPERIMENTAL // EXPERIMENTAL
else if (checkSlopes()) else if (checkSlopes())
{ {
state = s_standing; setState(s_standing);
vy = 0.0f; vy = 0.0f;
} }
} }
@@ -489,8 +498,8 @@ void Player::checkJumpEnd()
if (state == s_jumping) if (state == s_jumping)
if (vy > 0) if (vy > 0)
if (y >= jump_ini) if (y >= jump_ini)
{ { // Si alcanza la altura de salto inicial, pasa al estado de caída
state = s_falling; setState(s_falling);
vy = maxVY; vy = maxVY;
} }
} }
@@ -504,11 +513,13 @@ bool Player::isOnFloor()
for (auto f : underFeet) for (auto f : underFeet)
{ {
const tile_e tile = (room->getTile(f)); onFloor |= room->checkTopSurfaces(&f);
onFloor |= (tile == t_wall || tile == t_passable);
} }
debug->add("ONFLOOR = " + std::to_string(onFloor)); if (onFloor)
{
debug->add("ONFLOOR");
}
return onFloor; return onFloor;
} }
@@ -662,3 +673,10 @@ void Player::setInvincible(bool value)
{ {
invincible = value; invincible = value;
} }
// Cambia el estado del jugador
void Player::setState(state_e value)
{
prevState = state;
state = value;
}

View File

@@ -55,6 +55,7 @@ public:
std::vector<SDL_Point> underFeet; // Contiene los puntos que hay bajo cada pie del jugador std::vector<SDL_Point> underFeet; // Contiene los puntos que hay bajo cada pie del jugador
std::vector<SDL_Point> feet; // Contiene los puntos que hay en el pie del jugador std::vector<SDL_Point> 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 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 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 int border; // Indica en cual de los cuatro bordes se encuentra
bool invincible; // Si es invencible, no puede morir bool invincible; // Si es invencible, no puede morir
@@ -104,6 +105,9 @@ public:
// Actualiza los puntos de los pies // Actualiza los puntos de los pies
void updateFeet(); void updateFeet();
// Cambia el estado del jugador
void setState(state_e value);
public: public:
// Constructor // Constructor
Player(player_t ini, std::string tileset, std::string animation, SDL_Renderer *renderer, Asset *asset, Input *input, Room *room, Debug *debug); Player(player_t ini, std::string tileset, std::string animation, SDL_Renderer *renderer, Asset *asset, Input *input, Room *room, Debug *debug);

View File

@@ -437,14 +437,14 @@ void Room::fillMapTexture()
{ {
clip.x = ((tilemap[(y * 32) + x] - 1) % 20) * 8; clip.x = ((tilemap[(y * 32) + x] - 1) % 20) * 8;
clip.y = ((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 (debug->getEnabled())
{ {
if (clip.x != -8) if (clip.x != -8)
{ {
clip.x = x * 8; clip.x = x * 8;
clip.y = y * 8; clip.y = y * 8;
SDL_SetRenderDrawColor(renderer, 32, 32, 32, 0xFF); SDL_SetRenderDrawColor(renderer, 48, 48, 48, 192);
SDL_RenderFillRect(renderer, &clip); SDL_RenderFillRect(renderer, &clip);
} }
} }
@@ -453,31 +453,43 @@ void Room::fillMapTexture()
// **** // ****
if (debug->getEnabled()) if (debug->getEnabled())
{ {
for (auto l : bottomSurfaces) if (true)
{ {
SDL_SetRenderDrawColor(renderer, (rand() % 128) + 80, (rand() % 128) + 80, (rand() % 128) + 80, 0xFF); for (auto l : bottomSurfaces)
SDL_RenderDrawLine(renderer, l.x1, l.y, l.x2, l.y); {
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); if (true)
for (auto l : topSurfaces)
{ {
SDL_SetRenderDrawColor(renderer, (rand() % 128) + 80, (rand() % 128) + 80, (rand() % 128) + 80, 0xFF); SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0x00, 0xFF);
SDL_RenderDrawLine(renderer, l.x1, l.y, l.x2, l.y); 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); if (true)
for (auto l : leftSurfaces)
{ {
SDL_SetRenderDrawColor(renderer, (rand() % 128) + 80, (rand() % 128) + 80, (rand() % 128) + 80, 0xFF); SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0xFF);
SDL_RenderDrawLine(renderer, l.x, l.y1, l.x, l.y2); 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); if (true)
for (auto l : rightSurfaces)
{ {
SDL_SetRenderDrawColor(renderer, (rand() % 128) + 80, (rand() % 128) + 80, (rand() % 128) + 80, 0xFF); SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
SDL_RenderDrawLine(renderer, l.x, l.y1, l.x, l.y2); 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);
}
} }
} }
// **** // ****
@@ -939,3 +951,16 @@ int Room::checkBottomSurfaces(SDL_Rect *rect)
return pos; return pos;
} }
// Comprueba las colisiones
bool Room::checkTopSurfaces(SDL_Point *p)
{
bool collision = false;
for (auto s : topSurfaces)
{
collision |= checkCollision(s, *p);
}
return collision;
}

View File

@@ -161,6 +161,9 @@ public:
// Comprueba las colisiones // Comprueba las colisiones
int checkBottomSurfaces(SDL_Rect *rect); int checkBottomSurfaces(SDL_Rect *rect);
// Comprueba las colisiones
bool checkTopSurfaces(SDL_Point *p);
}; };
#endif #endif

View File

@@ -202,6 +202,37 @@ bool checkCollision(v_line_t &l, SDL_Rect &r)
return true; 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 // Devuelve un color_t a partir de un string
color_t stringToColor(std::string str) color_t stringToColor(std::string str)
{ {

View File

@@ -95,6 +95,9 @@ bool checkCollision(h_line_t &l, SDL_Rect &r);
// Detector de colisiones entre una linea vertical y un rectangulo // Detector de colisiones entre una linea vertical y un rectangulo
bool checkCollision(v_line_t &l, SDL_Rect &r); 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 // Devuelve un color_t a partir de un string
color_t stringToColor(std::string str); color_t stringToColor(std::string str);