diff --git a/source/game.cpp b/source/game.cpp index a039576..02ee37c 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -11,7 +11,7 @@ Game::Game(SDL_Renderer *renderer, Asset *asset, Screen *screen, Input *input) eventHandler = new SDL_Event(); map = new Map(asset->get("01.map"), renderer, asset); - player = new Player(renderer, asset, input); + player = new Player(renderer, asset, input, map); } // Destructor diff --git a/source/map.cpp b/source/map.cpp index 021bf68..fb4376c 100644 --- a/source/map.cpp +++ b/source/map.cpp @@ -21,6 +21,11 @@ Map::Map(std::string file, SDL_Renderer *renderer, Asset *asset) // Pinta el mapa de la habitación en la textura fillMapTexture(); + + // Inicializa variables + tile_width = 16; + map_width = 20; + map_height = 13; } // Destructor @@ -185,7 +190,7 @@ void Map::fillMapTexture() SDL_RenderClear(renderer); // Dibuja la textura de fondo - SDL_Rect clip = {0, 0, 320, 240-32}; + SDL_Rect clip = {0, 0, 320, 240 - 32}; texture_bg->render(renderer, 0, 0, &clip); // Dibuja el mapeado de tiles @@ -195,7 +200,7 @@ void Map::fillMapTexture() const int map_height_in_tiles = 13; clip = {0, 0, tile_size, tile_size}; - + for (int y = 0; y < map_height_in_tiles; y++) for (int x = 0; x < map_width_in_tiles; x++) { @@ -213,4 +218,23 @@ void Map::render() // Dibuja la textura con el mapa en pantalla SDL_Rect rect = {0, 0, GAMECANVAS_WIDTH, GAMECANVAS_HEIGHT}; SDL_RenderCopy(renderer, map_texture, &rect, NULL); +} + +// Devuelve el tipo de tile que hay en un punto +t_tile_map Map::getTile(SDL_Point p) +{ + const int tile = tilemap[((p.y / tile_width) * map_width) + (p.x / tile_width)]; + + if (tile > 0 && tile < 4 * map_width * tile_width) + { + return nothing; + } + else if (tile > (4 * map_width * tile_width) && tile < 8 * map_width * tile_width) + { + return wall; + } + else + { + return travessable; + } } \ No newline at end of file diff --git a/source/map.h b/source/map.h index 12081b6..a8f0807 100644 --- a/source/map.h +++ b/source/map.h @@ -12,6 +12,13 @@ #ifndef MAP_H #define MAP_H +enum t_tile_map +{ + nothing, + wall, + travessable +}; + // The player class Map { @@ -29,6 +36,10 @@ private: LTexture *texture_bg; // Textura con los graficos de fondo de la habitación SDL_Texture *map_texture; // Textura para dibujar el mapa de la habitación + int tile_width; // Ancho del tile en pixels + int map_width; // Alto del mapa en tiles + int map_height; // Ancho del mapa en tiles + // Carga las variables desde un fichero bool load(std::string file); @@ -50,6 +61,9 @@ public: // Dibuja el objeto void render(); + + // Devuelve el tipo de tile que hay en un punto + t_tile_map getTile(SDL_Point p); }; #endif diff --git a/source/movingsprite.cpp b/source/movingsprite.cpp index 1fb9c79..f2d7a67 100644 --- a/source/movingsprite.cpp +++ b/source/movingsprite.cpp @@ -7,7 +7,7 @@ MovingSprite::MovingSprite(float x, float y, int w, int h, float velx, float vel // Copia los punteros setTexture(texture); setRenderer(renderer); - + // Establece el alto y el ancho del sprite setWidth(w); setHeight(h); @@ -15,6 +15,8 @@ MovingSprite::MovingSprite(float x, float y, int w, int h, float velx, float vel // Establece la posición X,Y del sprite setPosX(x); setPosY(y); + mPosXPrev = x; + mPosYPrev = y; // Establece la velocidad X,Y del sprite setVelX(velx); @@ -43,7 +45,7 @@ MovingSprite::MovingSprite(float x, float y, int w, int h, float velx, float vel setSpriteClip(0, 0, w, h); // Establece el centro de rotación - mCenter = {0,0}; + mCenter = {0, 0}; // Establece el tipo de volteado mFlip = SDL_FLIP_NONE; @@ -84,6 +86,9 @@ void MovingSprite::move() { if (mEnabled) { + mPosXPrev = mPosX; + mPosYPrev = mPosY; + mPosX += mVelX; mPosY += mVelY; @@ -302,4 +307,11 @@ SDL_Rect MovingSprite::getRect() { SDL_Rect rect = {(int)getPosX(), (int)getPosY(), getWidth(), getHeight()}; return rect; +} + +// Deshace el último movimiento +void MovingSprite::undoMove() +{ + mPosX = mPosXPrev; + mPosY = mPosYPrev; } \ No newline at end of file diff --git a/source/movingsprite.h b/source/movingsprite.h index 25d3b95..055fa13 100644 --- a/source/movingsprite.h +++ b/source/movingsprite.h @@ -12,6 +12,9 @@ protected: float mPosX; // Posición en el eje X float mPosY; // Posición en el eje Y + float mPosXPrev; // Posición anterior en el eje X + float mPosYPrev; // Posición anterior en el eje Y + float mVelX; // Velocidad en el eje X. Cantidad de pixeles a desplazarse float mVelY; // Velocidad en el eje Y. Cantidad de pixeles a desplazarse @@ -140,6 +143,9 @@ public: // Devuelve el rectangulo donde está el sprite SDL_Rect getRect(); + + // Deshace el último movimiento + void undoMove(); }; #endif diff --git a/source/player.cpp b/source/player.cpp index 1404b66..041c42b 100644 --- a/source/player.cpp +++ b/source/player.cpp @@ -1,11 +1,12 @@ #include "player.h" // Constructor -Player::Player(SDL_Renderer *renderer, Asset *asset, Input *input) +Player::Player(SDL_Renderer *renderer, Asset *asset, Input *input, Map *map) { this->asset = asset; this->renderer = renderer; this->input = input; + this->map = map; sound_jump = JA_LoadSound(asset->get("sound_player_jump.wav").c_str()); sound_death = JA_LoadSound(asset->get("sound_player_death.wav").c_str()); @@ -15,10 +16,12 @@ Player::Player(SDL_Renderer *renderer, Asset *asset, Input *input) loadTextureFromFile(texture, asset->get("player.png"), renderer); sprite = new AnimatedSprite(texture, renderer, asset->get("player.ani")); + sprite->setPosX(16); - sprite->setPosY(168); + sprite->setPosY(0); sprite->setCurrentAnimation("stand"); + gravity = 0.5f; can_jump = true; standing = true; invulnerable = true; @@ -28,6 +31,8 @@ Player::Player(SDL_Renderer *renderer, Asset *asset, Input *input) lifes = 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}); } // Destructor @@ -47,7 +52,9 @@ Player::~Player() void Player::update() { checkInput(); + addGravity(); sprite->update(); + updateColliders(); } // Dibuja el objeto @@ -78,4 +85,45 @@ void Player::checkInput() sprite->setVelX(0); sprite->setCurrentAnimation("stand"); } +} + +// Aplica la gravedad +void Player::addGravity() +{ + sprite->setVelY(gravity); +} + +// Actualiza los puntos de colisión +void Player::updateColliders() +{ + const SDL_Point p = {(int)sprite->getPosX(), (int)sprite->getPosY()}; + + collider[0] = p; + collider[1] = {p.x, p.y + 12}; + collider[2] = {p.x, p.y + 23}; + collider[3] = {p.x + 15, p.y}; + collider[4] = {p.x + 15, p.y + 12}; + collider[5] = {p.x + 15, p.y + 23}; +} + +// Compruena las colisiones con el mapa +void Player::checkMapCollisions() +{ + bool collision = false; + + for (auto c : collider) + { + collision |= (map->getTile(c) == wall); + } + + if (collision) + { + undoMove(); + } +} + +// Deshace el último movimiento +void Player::undoMove() +{ + sprite->undoMove(); } \ No newline at end of file diff --git a/source/player.h b/source/player.h index aa94e77..0a4ffc6 100644 --- a/source/player.h +++ b/source/player.h @@ -5,6 +5,7 @@ #include "input.h" #include "animatedsprite.h" #include "asset.h" +#include "map.h" #ifndef PLAYER_H #define PLAYER_H @@ -18,26 +19,41 @@ private: Input *input; // Objeto Input para gestionar las entradas AnimatedSprite *sprite; // Objeto con los graficos, animaciones y posición del jugador LTexture *texture; // Textura con los graficos del jugador + Map *map; // Objeto con el mapa - 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 - std::vector key; // Indica las llaves que posee el jugador - JA_Sound sound_coin; // Sonido al coger monedas - JA_Sound sound_death; // Sonido al morir - JA_Sound sound_jump; // Sonido al saltar + 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 // Comprueba las entradas y modifica variables void checkInput(); + // Aplica la gravedad + void addGravity(); + + // Actualiza los puntos de colisión + void updateColliders(); + + // Compruena las colisiones con el mapa + void checkMapCollisions(); + + // Deshace el último movimiento + void undoMove(); + public: // Constructor - Player(SDL_Renderer *renderer, Asset *asset, Input *input); + Player(SDL_Renderer *renderer, Asset *asset, Input *input, Map *map); // Destructor ~Player();