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"/>
<layer id="1" name="Capa de patrones 1" width="32" height="16">
<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,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
</data>
</layer>
</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;
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,35 +85,34 @@ 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;
setState(s_jumping);
vy = -maxVY;
jump_ini = y;
}
}
}
// Indica si el jugador esta en uno de los cuatro bordes de la pantalla
@@ -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;
}
@@ -662,3 +673,10 @@ void Player::setInvincible(bool 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> 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);

View File

@@ -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);
}
}
@@ -452,27 +452,38 @@ void Room::fillMapTexture()
// ****
if (debug->getEnabled())
{
if (true)
{
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);
}
}
if (true)
{
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);
}
}
if (true)
{
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);
}
}
if (true)
{
SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);
for (auto l : rightSurfaces)
{
@@ -480,6 +491,7 @@ void Room::fillMapTexture()
SDL_RenderDrawLine(renderer, l.x, l.y1, l.x, l.y2);
}
}
}
// ****
SDL_SetRenderTarget(renderer, nullptr);
@@ -939,3 +951,16 @@ 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;
}

View File

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

View File

@@ -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)
{

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