diff --git a/data/animations/player.ani b/data/animations/player.ani index 6bd3498..5b628b0 100644 --- a/data/animations/player.ani +++ b/data/animations/player.ani @@ -19,8 +19,8 @@ frames=8,9,10,10,9,8,11,12,13,13,14,15 [animation] name=jump speed=10 -loop=yes -frames=16 +loop=no +frames=16,17,18,17,16 [/animation] [animation] diff --git a/media/gfx/player.png b/media/gfx/player.png index 59e22be..fe0808b 100644 Binary files a/media/gfx/player.png and b/media/gfx/player.png differ diff --git a/source/game.cpp b/source/game.cpp index ba743d0..05e8b21 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -116,6 +116,12 @@ void Game::renderDebugInfo() text = std::to_string((int)player->sprite->getPosX()) + "," + std::to_string((int)player->sprite->getPosY()); debugText->write(0, line, text, -1); - //text = std::to_string(player->checkMapCollisions()); - //debugText->write(0, line+=6, text, -1); + text = "VY " + std::to_string(player->vy) + " " + std::to_string(player->jumpStrenght); + debugText->write(0, line+=6, text, -1); + + text = "VX " + std::to_string(player->vx); + debugText->write(0, line+=6, text, -1); + + text = "jump_pressed " + std::to_string(player->jumpPressed); + debugText->write(0, line+=6, text, -1); } \ No newline at end of file diff --git a/source/player.cpp b/source/player.cpp index b07c52c..84c2744 100644 --- a/source/player.cpp +++ b/source/player.cpp @@ -18,7 +18,7 @@ Player::Player(SDL_Renderer *renderer, Asset *asset, Input *input, Map *map) sprite = new AnimatedSprite(texture, renderer, asset->get("player.ani")); x = 3 * 16; - y = 40; + y = 168; vx = 0; vy = 0; const SDL_Rect rect = {(int)x, (int)y, 16, 24}; @@ -26,18 +26,25 @@ Player::Player(SDL_Renderer *renderer, Asset *asset, Input *input, Map *map) sprite->setCurrentAnimation("stand"); sprite->setFlip(SDL_FLIP_HORIZONTAL); + // jumpStrenght = -5.6f; + jumpStrenght = 2.0f; gravity = 0.3f; - can_jump = true; + accelX = 0.12f; + maxVX = 1.5f; + maxVY = 4.0f; + + jumping = false; + jumpPressed = false; standing = true; - invulnerable = true; - jumpforce = 10; + invulnerable = false; enabled = true; cooldown = 0; - lifes = 10; + lives = 10; coins = 0; key.insert(key.end(), {0, 0, 0, 0, 0, 0}); const SDL_Point p = {0, 0}; collider.insert(collider.end(), {p, p, p, p, p, p}); + underFeet.insert(underFeet.end(), {p, p}); } // Destructor @@ -59,6 +66,7 @@ void Player::update() checkInput(); addGravity(); move(); + animate(); } // Dibuja el objeto @@ -70,36 +78,59 @@ void Player::render() // Comprueba las entradas y modifica variables void Player::checkInput() { - const float speed = 1.0f; - // Solo comprueba las entradas de dirección cuando está de pie if (input->checkInput(INPUT_LEFT, REPEAT_TRUE)) { - vx = -speed; + vx = std::max(vx -= accelX, -maxVX); sprite->setFlip(SDL_FLIP_NONE); - sprite->setCurrentAnimation("walk"); } else if (input->checkInput(INPUT_RIGHT, REPEAT_TRUE)) { - vx = speed; + vx = std::min(vx += accelX, maxVX); sprite->setFlip(SDL_FLIP_HORIZONTAL); - sprite->setCurrentAnimation("walk"); } else { - vx = 0; - sprite->setCurrentAnimation("stand"); + if (vx > 0.0f) + { + vx = std::max(vx -= accelX, 0.0f); + } + else + { + vx = std::min(vx += accelX, 0.0f); + } } - if (input->checkInput(INPUT_UP, REPEAT_FALSE)) + if (input->checkInput(INPUT_UP, REPEAT_TRUE)) { - vy = -5.0f; + if (!jumping) + { + if (!jumpPressed) + { + jumpStrenght = 2.0f; + vy -= jumpStrenght; + jumping = true; + jumpPressed = true; + } + } + else + { + jumpStrenght = std::max(jumpStrenght -= 0.4f, 0.0f); + vy -= jumpStrenght; + } + } + else + { + jumpPressed = false; } } // Aplica la gravedad void Player::addGravity() { - vy = std::min(vy += gravity, 2.0f); + if (!isOnFloor()) + { + vy = std::min(vy += gravity, maxVY); + } } // Actualiza los puntos de colisión @@ -113,6 +144,9 @@ void Player::updateColliders() collider[3] = {p.x + 15, p.y}; collider[4] = {p.x + 15, p.y + 12}; collider[5] = {p.x + 15, p.y + 23}; + + underFeet[0] = {p.x, p.y + 24}; + underFeet[1] = {p.x + 15, p.y + 24}; } // Compruena las colisiones con el mapa @@ -133,24 +167,39 @@ bool Player::checkMapCollisions() // Mueve al jugador en función de la velocidad/desplazamiento void Player::move() { - const float old_x = x; x += vx; if (checkMapCollisions()) { - x = old_x; + if (vx > 0) + { + do + { + x--; + } while (checkMapCollisions()); + } + else + { + do + { + x++; + } while (checkMapCollisions()); + } + + vx = 0.0f; } - // const float old_y = y; y += vy; if (checkMapCollisions()) { - // y = old_y; if (vy > 0) { do { y--; } while (checkMapCollisions()); + jumping = false; + vy = 0.0f; + jumpStrenght = 2.0f; } else { @@ -159,11 +208,44 @@ void Player::move() y++; } while (checkMapCollisions()); } - - vy = 0; } sprite->setPosX(x); sprite->setPosY(y); - sprite->update(); +} + +// Anima al jugador +void Player::animate() +{ + if (jumping) + { + sprite->setCurrentAnimation("jump"); + } + else + { + if (abs(vx) < 1.00f) + { + sprite->setCurrentAnimation("stand"); + } + else + { + sprite->setCurrentAnimation("walk"); + } + } + + sprite->animate(); +} + +// Comprueba si el jugador tiene suelo debajo de los pies +bool Player::isOnFloor() +{ + bool onFloor = false; + + updateColliders(); + + for (auto f : underFeet) + { + onFloor |= (map->getTile(f) == wall); + } + return onFloor; } \ No newline at end of file diff --git a/source/player.h b/source/player.h index ad21266..89fc19c 100644 --- a/source/player.h +++ b/source/player.h @@ -21,24 +21,32 @@ public: LTexture *texture; // Textura con los graficos del jugador Map *map; // Objeto con el mapa - float x; // Posición del jugador en el eje X - float y; // Posición del jugador en el eje Y - float vx; // Velocidad/desplazamiento del jugador en el eje X - float vy; // Velocidad/desplazamiento del jugador en el eje Y - bool can_jump; // Si puede saltar - bool enabled; // Si está habilitado - bool standing; // Si esta de pie (o quieto?) - bool invulnerable; // Si es invulnerable - int coins; // Cantidad de monedas - int cooldown; // Tiempo de inhabilitación - int jumpforce; // Cantidad de pixels a desplazarse y velocidad que pilla al saltar - int lifes; // Cantidad de vidas - float gravity; // Gravedad - std::vector key; // Indica las llaves que posee el jugador - std::vector collider; // Contiene los puntos de colisión del jugador con el mapa - JA_Sound sound_coin; // Sonido al coger monedas - JA_Sound sound_death; // Sonido al morir - JA_Sound sound_jump; // Sonido al saltar + float x; // Posición del jugador en el eje X + float y; // Posición del jugador en el eje Y + float vx; // Velocidad/desplazamiento del jugador en el eje X + float vy; // Velocidad/desplazamiento del jugador en el eje Y + bool jumping; // Indica si se encuentra saltando + bool jumpPressed; // Indica si esta pulsada la tecla de salto + bool enabled; // Si está habilitado + bool standing; // Si esta de pie (o quieto?) + bool invulnerable; // Indica si se encuentra en estado invulnerable + int coins; // Cantidad de monedas + int cooldown; // Tiempo de inhabilitación + int lives; // Cantidad de vidas + + // Variables que afectan a la inercia del movimiento + float jumpStrenght; // Cantidad de pixels a desplazarse y velocidad que pilla al saltar + float gravity; // Gravedad + float accelX; // Aceleración al desplazarse horizontalmente + float maxVX; // Velocidad mazima de desplazamiento horizontal + float maxVY; // Velocidad mazima de desplazamiento vertical + + std::vector key; // Indica las llaves que posee el jugador + std::vector collider; // Contiene los puntos de colisión del jugador con el mapa + std::vector underFeet; // Contiene los puntos que hay bajo cada pie del jugador + JA_Sound sound_coin; // Sonido al coger monedas + JA_Sound sound_death; // Sonido al morir + JA_Sound sound_jump; // Sonido al saltar // Comprueba las entradas y modifica variables void checkInput(); @@ -55,6 +63,12 @@ public: // Mueve al jugador en función de la velocidad/desplazamiento void move(); + // Anima al jugador + void animate(); + + // Comprueba si el jugador tiene suelo debajo de los pies + bool isOnFloor(); + public: // Constructor Player(SDL_Renderer *renderer, Asset *asset, Input *input, Map *map);