From 4f6a99f670c1956a9edd8b89caf6426c85a7cef2 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Mon, 11 Jul 2022 14:18:30 +0200 Subject: [PATCH] Creadas las colisiones con los enemigos --- data/room/room1.tmx | 6 +++--- data/room/room2.tmx | 4 ++-- source/enemy.cpp | 19 +++++++++++++++++-- source/enemy.h | 7 +++++++ source/game.cpp | 12 +++++++++++- source/game.h | 3 +++ source/movingsprite.cpp | 7 +++++++ source/movingsprite.h | 3 +++ source/player.cpp | 11 +++++++++-- source/player.h | 12 ++++++++---- source/room.cpp | 25 +++++++++++++++++++------ source/room.h | 3 +++ source/utils.h | 2 +- todo.txt | 5 ++++- 14 files changed, 97 insertions(+), 22 deletions(-) diff --git a/data/room/room1.tmx b/data/room/room1.tmx index 5f69ab0..4457e9e 100644 --- a/data/room/room1.tmx +++ b/data/room/room1.tmx @@ -12,11 +12,11 @@ 41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41, 41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,41,0,0,0,0,0,0,0,0,0,0,0,0,41, 41,41,41,0,0,0,0,0,0,0,0,0,0,0,41,41,41,41,41,41,41,41,0,0,0,0,0,0,0,0,0,41, +41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,81,0,0,0,0,0,0,41, 41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41, -41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,0,0,0,0,0,41, 41,0,0,0,0,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,0,0,0,0,0,41, -0,0,0,0,0,0,0,0,0,81,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +41,0,0,0,0,0,0,0,0,81,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41, 41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41,41 diff --git a/data/room/room2.tmx b/data/room/room2.tmx index 0d8e1e4..89b0bab 100644 --- a/data/room/room2.tmx +++ b/data/room/room2.tmx @@ -15,8 +15,8 @@ 43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,43, 43,0,0,0,0,0,0,0,0,83,0,0,0,0,0,0,0,0,0,3,0,0,0,0,83,83,0,0,0,0,0,43, 43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,43, -0,0,0,0,0,0,0,83,83,83,83,83,83,0,0,0,0,0,0,3,0,0,0,0,83,83,0,0,0,0,0,0, -0,0,0,0,0,83,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,83,83,83,83,83,83,0,0,0,0,0,0,3,0,0,0,0,83,83,0,0,0,0,0,43, +0,0,0,0,0,83,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0,0,43, 63,43,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,43,43,43,43,43,43,43,43,43,43,43,63, 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63 diff --git a/source/enemy.cpp b/source/enemy.cpp index 893f389..2323159 100644 --- a/source/enemy.cpp +++ b/source/enemy.cpp @@ -40,6 +40,8 @@ Enemy::Enemy(enemy_t enemy) sprite->setAnimationFrames(0, 2, 16 * 2, 0, 16, 16); sprite->setAnimationFrames(0, 3, 16 * 3, 0, 16, 16); sprite->setSpriteClip(sprite->getAnimationClip(0, 0)); + + collider = getRect(); } // Destructor @@ -67,6 +69,7 @@ void Enemy::update() sprite->update(); sprite->animate(0); checkPath(); + collider = getRect(); } // Comprueba si ha llegado al limite del recorrido para darse media vuelta @@ -74,13 +77,25 @@ void Enemy::checkPath() { if (sprite->getPosX() > x2 || sprite->getPosX() < x1) { - //sprite->setPosX(sprite->getPosX() - sprite->getVelX()); + // sprite->setPosX(sprite->getPosX() - sprite->getVelX()); sprite->setVelX(sprite->getVelX() * (-1)); } if (sprite->getPosY() > y2 || sprite->getPosY() < y1) { - //sprite->setPosY(sprite->getPosY() - sprite->getVelY()); + // sprite->setPosY(sprite->getPosY() - sprite->getVelY()); sprite->setVelY(sprite->getVelY() * (-1)); } +} + +// Devuelve el rectangulo que contiene al enemigo +SDL_Rect Enemy::getRect() +{ + return sprite->getRect(); +} + +// Obtiene el rectangulo de colision del enemigo +SDL_Rect &Enemy::getCollider() +{ + return collider; } \ No newline at end of file diff --git a/source/enemy.h b/source/enemy.h index ca6ebbe..57a1dd8 100644 --- a/source/enemy.h +++ b/source/enemy.h @@ -54,6 +54,7 @@ private: int x2; // Limite derecho de la ruta en el eje X int y1; // Limite superior de la ruta en el eje Y int y2; // Limite inferior de la ruta en el eje Y + SDL_Rect collider; // Caja de colisión // Comprueba si ha llegado al limite del recorrido para darse media vuelta void checkPath(); @@ -70,6 +71,12 @@ public: // Actualiza las variables del objeto void update(); + + // Devuelve el rectangulo que contiene al enemigo + SDL_Rect getRect(); + + // Obtiene el rectangulo de colision del enemigo + SDL_Rect &getCollider(); }; #endif diff --git a/source/game.cpp b/source/game.cpp index da74110..a6e1348 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -153,6 +153,10 @@ void Game::draw() text = "tile: " + std::to_string(a) + " - " + std::to_string(b); mText->write(0, 19 * 8, text); + const bool collision = checkPlayerAndEnemies(); + text = "collision: " + std::to_string(collision); + mText->write(0, 20 * 8, text); + // Actualiza la pantalla mScreen->blit(); } @@ -230,7 +234,7 @@ void Game::checkPlayerOnFloor() const bool is_tile_aligned = mPlayer->getLeftFoot().y % 8 == 0; if (((is_not_going_up) && (is_tile_aligned)) || ((is_not_going_up) && (tile_change))) - { + { bool test = false; test |= (mRoom->getTile(mPlayer->getLeftFoot()) == TILE_SOLID); test |= (mRoom->getTile(mPlayer->getRightFoot()) == TILE_SOLID); @@ -287,4 +291,10 @@ void Game::checkPlayerAndWalls() mPlayer->undoLastMove(); mPlayer->setStatus(STATUS_FALLING); } +} + +// Comprueba las colisiones del jugador con los enemigos +bool Game::checkPlayerAndEnemies() +{ + return mRoom->enemyCollision(mPlayer->getCollider()); } \ No newline at end of file diff --git a/source/game.h b/source/game.h index d8c79a7..6b4cf42 100644 --- a/source/game.h +++ b/source/game.h @@ -65,6 +65,9 @@ private: // Comprueba que el jugador no atraviese ninguna pared void checkPlayerAndWalls(); + // Comprueba las colisiones del jugador con los enemigos + bool checkPlayerAndEnemies(); + public: // Constructor Game(SDL_Window *window, SDL_Renderer *renderer, Asset *asset, Lang *lang, Input *input); diff --git a/source/movingsprite.cpp b/source/movingsprite.cpp index 0ad2e1f..885182a 100644 --- a/source/movingsprite.cpp +++ b/source/movingsprite.cpp @@ -292,4 +292,11 @@ void MovingSprite::switchRotate() void MovingSprite::setFlip(SDL_RendererFlip flip) { mFlip = flip; +} + +// Devuelve el rectangulo donde está el sprite +SDL_Rect MovingSprite::getRect() +{ + SDL_Rect rect = {(int)getPosX(), (int)getPosY(), getWidth(), getHeight()}; + return rect; } \ No newline at end of file diff --git a/source/movingsprite.h b/source/movingsprite.h index 585b114..fcf7bb6 100644 --- a/source/movingsprite.h +++ b/source/movingsprite.h @@ -137,6 +137,9 @@ public: // Establece el valor de la variable void setFlip(SDL_RendererFlip flip); + + // Devuelve el rectangulo donde está el sprite + SDL_Rect getRect(); }; #endif diff --git a/source/player.cpp b/source/player.cpp index 3637faa..d50d3d5 100644 --- a/source/player.cpp +++ b/source/player.cpp @@ -47,6 +47,7 @@ Player::Player(std::string _tileset, SDL_Renderer *_renderer, Asset *_asset, Inp sprite->setSpriteClip(sprite->getAnimationClip(0, 0)); lastPosition = getRect(); + collider = getRect(); } // Destructor @@ -78,6 +79,7 @@ void Player::update() checkBorders(); // Comprueba si está situado en alguno de los cuatro bordes de la habitación applyGravity(); // Aplica gravedad al jugador checkJump(); // Comprueba si ha finalizado el salto + collider = getRect(); } // Comprueba las entradas y modifica variables @@ -238,8 +240,13 @@ void Player::applyGravity() // Obtiene el rectangulo que delimita al jugador SDL_Rect Player::getRect() { - SDL_Rect rect = {(int)sprite->getPosX(), (int)sprite->getPosY(), sprite->getWidth(), sprite->getHeight()}; - return rect; + return sprite->getRect(); +} + +// Obtiene el rectangulo de colision del jugador +SDL_Rect &Player::getCollider() +{ + return collider; } // Guarda la posición actual en la variable lastPosition diff --git a/source/player.h b/source/player.h index c47e7a9..2922f0b 100644 --- a/source/player.h +++ b/source/player.h @@ -23,12 +23,13 @@ class Player { private: - LTexture *texture; // Textura con los graficos del enemigo - Input *input; // Objeto para gestionar la entrada + LTexture *texture; // Textura con los graficos del enemigo + Input *input; // Objeto para gestionar la entrada SDL_Renderer *renderer; // El renderizador de la ventana Asset *asset; // Objeto con la ruta a todos los ficheros de recursos color_t color; // Color del jugador + SDL_Rect collider; // Caja de colisión 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 @@ -57,8 +58,8 @@ private: public: AnimatedSprite *sprite; // Sprite del enemigo SDL_Rect lastPosition; // Contiene la ultima posición del jugador, por si hay que deshacer algun movimiento - int jump_ini; // Valor del eje Y en el que se inicia el salto - int status; // Estado en el que se encuentra el jugador. Util apara saber si está saltando o cayendo + int jump_ini; // Valor del eje Y en el que se inicia el salto + int status; // Estado en el que se encuentra el jugador. Util apara saber si está saltando o cayendo // Constructor Player(std::string _tileset, SDL_Renderer *_renderer, Asset *_asset, Input *_input, Room *_room); @@ -99,6 +100,9 @@ public: // Obtiene el rectangulo que delimita al jugador SDL_Rect getRect(); + // Obtiene el rectangulo de colision del jugador + SDL_Rect &getCollider(); + // Deshace el ultimo movimiento void undoLastMove(); }; diff --git a/source/room.cpp b/source/room.cpp index c19c796..ce6ffd5 100644 --- a/source/room.cpp +++ b/source/room.cpp @@ -84,13 +84,13 @@ bool Room::load(std::string _file_path) // Si la linea contiene el texto [tilemap] se realiza el proceso de carga del fichero tmx else if (line == "[tilemap]") { - //printf("Loading tilemap...\n"); + // printf("Loading tilemap...\n"); do { std::getline(file, line); if (line.find(".tmx") != std::string::npos) { - //printf("Reading file %s\n", asset->get(line).c_str()); + // printf("Reading file %s\n", asset->get(line).c_str()); std::ifstream file2(asset->get(line)); // Abre el fichero tmx if (file2.good()) { @@ -103,10 +103,10 @@ bool Room::load(std::string _file_path) do { std::getline(file2, line); - //printf("parsing: %s\n", line.c_str()); + // printf("parsing: %s\n", line.c_str()); pos = line.find("data encoding"); - //printf("pos: %i\n", pos); + // printf("pos: %i\n", pos); } while (pos == std::string::npos); @@ -116,12 +116,12 @@ bool Room::load(std::string _file_path) std::getline(file2, line); if (line != "") { - //printf("data: %s\n", line.c_str()); + // printf("data: %s\n", line.c_str()); std::stringstream ss(line); std::string tmp; while (getline(ss, tmp, ',')) { - //printf("tile: %s\n", tmp.c_str()); + // printf("tile: %s\n", tmp.c_str()); tilemap.push_back(std::stoi(tmp)); } } @@ -411,3 +411,16 @@ int Room::getTile(SDL_Point point) return tile; } + +// Indica si hay colision con un enemigo a partir de un rectangulo +bool Room::enemyCollision(SDL_Rect &rect) +{ + bool collision = false; + + for (auto enemy : enemy_list) + { + collision |= checkCollision(rect, enemy->getCollider()); + } + + return collision; +} \ No newline at end of file diff --git a/source/room.h b/source/room.h index 6327139..aa614cd 100644 --- a/source/room.h +++ b/source/room.h @@ -86,6 +86,9 @@ public: // Devuelve el tipo de tile que hay en ese pixel int getTile(SDL_Point point); + + // Indica si hay colision con un enemigo a partir de un rectangulo + bool enemyCollision(SDL_Rect &rect); }; #endif diff --git a/source/utils.h b/source/utils.h index b403e70..ae63eba 100644 --- a/source/utils.h +++ b/source/utils.h @@ -74,7 +74,7 @@ bool checkCollision(circle_t &a, circle_t &b); bool checkCollision(circle_t &a, SDL_Rect &b); // Detector de colisiones entre un dos rectangulos -bool checkCollision(SDL_Rect a, SDL_Rect b); +bool checkCollision(SDL_Rect &a, SDL_Rect &b); // Carga un archivo de imagen en una textura bool loadTextureFromFile(LTexture *texture, std::string path, SDL_Renderer *renderer); diff --git a/todo.txt b/todo.txt index d02376e..e1cb707 100644 --- a/todo.txt +++ b/todo.txt @@ -1,4 +1,7 @@ [x] Hacer que deje de poder moverse tras el salto al alcanzar la misma posicion en altura que tenia cuando saltó [x] Arreglar que no atraviese tiles atravaseables al caer muy rapido [x] Leer los mapas directamente del archivo tmx -[ ] Crear la clase item \ No newline at end of file +[ ] Crear la clase item +[ ] Colisiones con los enemigos +[ ] Decidir un diseño para qué sucede en caso de morir: Recordar el punto por donde se entró al mapa y la velocidad en el eje X/Y que llevaba el personaje, crear puntos de reaparicion en las habitaciones, etc + En el Jet Set Willy el juego recuerda la posicion y el momento. En las Tres Luces de Glaurung solo la posición. Se va a optar por seguir el diseño del Jet Set Willy \ No newline at end of file