diff --git a/CMakeLists.txt b/CMakeLists.txt index b81e968..7c666e9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,8 +3,8 @@ project(PhantomForce LANGUAGES CXX) find_package(SFML 2.5.1 COMPONENTS graphics window system) -set(SOURCES src/Main.cpp src/Game.cpp src/Player.cpp src/TileMap.cpp) -set(HEADERS include/utils/utils.h include/utils/platform_utils.h include/Game.h include/Player.h include/TileMap.h) +set(SOURCES src/Main.cpp src/Game.cpp src/Player.cpp src/TileMap.cpp src/Object.cpp) +set(HEADERS include/utils/utils.h include/utils/platform_utils.h include/Game.h include/Player.h include/TileMap.h include/Object.h) set(RESOURCE_PATH assets) set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install) file(GLOB_RECURSE RESOURCES "${RESOURCE_PATH}/*") diff --git a/assets/crate.png b/assets/crate.png new file mode 100644 index 0000000..36865e8 Binary files /dev/null and b/assets/crate.png differ diff --git a/include/Game.h b/include/Game.h index 1081d84..f047182 100644 --- a/include/Game.h +++ b/include/Game.h @@ -2,18 +2,24 @@ #define GAME_H #include -class Game -{ - public: - Game(int framerate = 60); - Game(const Game&) = delete; - void operator=(const Game&) = delete; - ~Game(); +#include "Object.h" - void pollEvents(); - private: - sf::RenderWindow* m_window; - uint8_t m_input; +class Game { + public: + Game(int framerate = 60); + Game(const Game&) = delete; + void operator=(const Game&) = delete; + ~Game(); + + void pollEvents(); + + private: + sf::Clock m_clock; + sf::RenderWindow* m_window; + // Up to 4 drawing layers + std::vector m_sprite_layer[4]; + std::vector m_object_list; + uint8_t m_input; }; #endif diff --git a/include/Object.h b/include/Object.h new file mode 100644 index 0000000..2021cb8 --- /dev/null +++ b/include/Object.h @@ -0,0 +1,63 @@ +#ifndef OBJECT_H +#define OBJECT_H +#include + +class Object : virtual public sf::Sprite { + public: + Object(); + Object(sf::Texture &tex); + virtual bool checkCollision(Object *obj) const = 0; + virtual void snapCollision(Object *obj) = 0; + virtual void drawCollision(sf::RenderTarget *target) const = 0; + + sf::Vector2f m_spd_vec; + float m_mass; // 0 if static + static bool g_draw_collisions; +}; + +class Circle; +class Rectangle; + +class Circle : public Object { + public: + Circle() : Object(), m_radius(1) {} + Circle(sf::Texture &tex); + Circle(sf::Texture &tex, float r) : Object(tex), m_radius(r) {} + + bool checkCollision(Object *obj) const override; + bool checkCollision(Circle *obj) const; + bool checkCollision(Rectangle *obj) const; + + void snapCollision(Object *obj) override; + void snapCollision(Circle *obj); + void snapCollision(Rectangle *obj); + + void drawCollision(sf::RenderTarget *target) const override; + float getRadius() const { return m_radius; } + + private: + float m_radius; +}; + +class Rectangle : public Object { + public: + Rectangle() : Object(), m_size(2, 2) {} + Rectangle(sf::Texture &tex); + Rectangle(sf::Texture &tex, sf::Vector2f size) : Object(tex), m_size(size) {} + + bool checkCollision(Object *obj) const override; + bool checkCollision(Rectangle *obj) const; + bool checkCollision(Circle *obj) const; + + void snapCollision(Object *obj) override; + void snapCollision(Circle *obj); + void snapCollision(Rectangle *obj); + + void drawCollision(sf::RenderTarget *target) const override; + const sf::Vector2f getSize() const { return m_size; } + + private: + sf::Vector2f m_size; +}; + +#endif diff --git a/include/Player.h b/include/Player.h index f205bb1..796b46e 100644 --- a/include/Player.h +++ b/include/Player.h @@ -2,23 +2,26 @@ #define PLAYER_H #include +#include "Object.h" + struct MoveStats { - float max_spd; - float accel; - float fric; - float reload_rate; + float max_spd; + float accel; + float fric; + float reload_rate; }; -class Player : public sf::Sprite -{ - public: - Player(); - Player(sf::Texture& tex, MoveStats* s); - void move(sf::Vector2f velocity, float fr, bool sprint, uint8_t input); +class Player : public Circle { + public: + Player(sf::Texture& tex, MoveStats* s, float r); + void move(sf::Vector2f velocity, float fr, bool sprint, uint8_t input); + void setObjects(std::vector* objs); - private: - sf::Vector2f spd_vec; - MoveStats* stat; + private: + std::vector* m_objects_ref; + sf::Vector2f m_last_pos; + void checkCollision(); + MoveStats* m_stat; }; #endif diff --git a/include/TileMap.h b/include/TileMap.h index df47081..24e0939 100644 --- a/include/TileMap.h +++ b/include/TileMap.h @@ -2,25 +2,28 @@ #define TILEMAP_H #include -class TileMap : public sf::Drawable, public sf::Transformable -{ - public: - bool loadTileset(const std::string& tileset, sf::Vector2u tileSize); - void loadMap(const int* tiles, unsigned int mapWidth, unsigned int mapHeight, sf::View view); - void loadVertexChunk(sf::Vector2f view_coord); - // Flashes the chunk with tile v as the topleft corner - void flash(sf::Vector2i v); +class TileMap : public sf::Drawable { + public: + bool loadTileset(const std::string& tileset, sf::Vector2u tileSize); + void loadMap(const int* tiles, unsigned int mapWidth, unsigned int mapHeight, + sf::View view); + void loadVertexChunk(sf::Vector2f view_coord); + // Flashes the chunk with tile v as the topleft corner + void flash(sf::Vector2i v); - private: - virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const; + private: + virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const; - sf::VertexArray m_vertices; // The vertex array to draw the tiles onto the view - sf::Vector2u m_chunkSize; // The dimensions of a VertexArray chunk when rendered (in tiles) - sf::Texture m_tileset; // The tileset texture - sf::Vector2u m_tileSize; // The dimensions of each tile (in pixels) - std::vector m_tiles; // The tile map - sf::Vector2u m_mapSize; // The dimensions of the entire tile map (in tiles) - sf::Vector2f m_center; // The center of the view since loadVertexChunk is last called + sf::VertexArray + m_vertices; // The vertex array to draw the tiles onto the view + sf::Vector2u m_chunkSize; // The dimensions of a VertexArray chunk when + // rendered (in tiles) + sf::Texture m_tileset; // The tileset texture + sf::Vector2u m_tileSize; // The dimensions of each tile (in pixels) + std::vector m_tiles; // The tile map + sf::Vector2u m_mapSize; // The dimensions of the entire tile map (in tiles) + sf::Vector2f + m_center; // The center of the view since loadVertexChunk is last called }; -#endif \ No newline at end of file +#endif diff --git a/include/utils/platform_utils.h b/include/utils/platform_utils.h index d43dec5..68dea1e 100644 --- a/include/utils/platform_utils.h +++ b/include/utils/platform_utils.h @@ -1,28 +1,29 @@ -#ifndef PLATFORM_UTILS_H +#ifndef PLATFORM_UTILS_H #define PLATFORM_UTILS_H #ifdef __APPLE__ #include #endif #include -std::string getResourcePath() -{ - #ifdef __APPLE__ - CFURLRef appUrlRef = CFBundleCopyBundleURL(CFBundleGetMainBundle()); - CFStringRef macPath = CFURLCopyFileSystemPath(appUrlRef, kCFURLPOSIXPathStyle); - const char *pathPtr = CFStringGetCStringPtr(macPath, CFStringGetSystemEncoding()); - std::string path(pathPtr); - std::string resourcePath = path + "/Contents/Resources/"; +std::string getResourcePath() { +#ifdef __APPLE__ + CFURLRef appUrlRef = CFBundleCopyBundleURL(CFBundleGetMainBundle()); + CFStringRef macPath = + CFURLCopyFileSystemPath(appUrlRef, kCFURLPOSIXPathStyle); + const char *pathPtr = + CFStringGetCStringPtr(macPath, CFStringGetSystemEncoding()); + std::string path(pathPtr); + std::string resourcePath = path + "/Contents/Resources/"; - CFRelease(appUrlRef); - CFRelease(macPath); + CFRelease(appUrlRef); + CFRelease(macPath); - return resourcePath; - #elif defined(_WIN32) - return "assets/"; - #else - return "assets/"; - #endif + return resourcePath; +#elif defined(_WIN32) + return "assets/"; +#else + return "assets/"; +#endif } -#endif \ No newline at end of file +#endif diff --git a/include/utils/utils.h b/include/utils/utils.h index 6482bad..61eb8a8 100644 --- a/include/utils/utils.h +++ b/include/utils/utils.h @@ -2,47 +2,41 @@ #define GLOBAL_H #define _USE_MATH_DEFINES #include + #include // Weighted avg between x and y -template -T converge(T x, T y, T weight) -{ - return (weight * x) + (1 - weight) * y; +template +T converge(T x, T y, T weight) { + return (weight * x) + (1 - weight) * y; } // Angle of Vector2 -template -float get_angle(sf::Vector2 v) -{ - return (atan2f(v.y, v.x) * 180 / M_PI); +template +float get_angle(sf::Vector2 v) { + return (atan2f(v.y, v.x) * 180 / M_PI); } // Length (magnitude) of Vector2 -template -float len(const sf::Vector2 v) -{ - return sqrtf(powf(v.x, 2) + powf(v.y, 2)); +template +float len(const sf::Vector2 v) { + return sqrtf(powf(v.x, 2) + powf(v.y, 2)); } // Helper function keeps x between -180 & 180 degrees -template -void normalize(T& x) -{ - if (x > 180) - { - x -= 360; - } - if (x <= -180) - { - x += 360; - } +template +void normalize(T& x) { + if (x > 180) { + x -= 360; + } + if (x <= -180) { + x += 360; + } } -template -sf::Vector2 max(sf::Vector2 a, sf::Vector2 b) -{ - return sf::Vector2(std::max(a.x, b.x), std::max(a.y, b.y)); +template +sf::Vector2 max(sf::Vector2 a, sf::Vector2 b) { + return sf::Vector2(std::max(a.x, b.x), std::max(a.y, b.y)); } #endif diff --git a/src/Game.cpp b/src/Game.cpp index 6005d2a..259ec2b 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -1,138 +1,145 @@ -#include #include "Game.h" + +#include + #include "Player.h" #include "TileMap.h" -#include "utils.h" #include "platform_utils.h" +#include "utils.h" -Game::Game(int framerate) : m_input(0) -{ - sf::Clock clock; +Game::Game(int framerate) : m_input(0) { const std::string resourcePath = getResourcePath(); - m_window = new sf::RenderWindow { { 1000u, 800u }, "Phantom Force" }; + m_window = new sf::RenderWindow{{1000u, 800u}, "Phantom Force"}; m_window->setFramerateLimit(framerate); sf::Texture tex; - sf::Texture background_tex; + sf::Texture crate_tex; - std::vector game_sprites[4]; MoveStats def({5.0f, 0.5f, 0.8f, 1.0f}); - // Viewport of 250 x 200, 1/4 of the original window 1000 x 800 sf::View view = m_window->getView(); sf::Vector2f minCenter = sf::Vector2f(125.f, 100.f); view.zoom(0.25f); m_window->setView(view); - if (!(tex.loadFromFile(resourcePath + "player.png"))) - { - printf("Loading texture failed\n"); - } + if (!(tex.loadFromFile(resourcePath + "player.png"))) { + printf("Loading texture failed\n"); + } + if (!(crate_tex.loadFromFile(resourcePath + "crate.png"))) { + printf("Loading texture failed\n"); + } - Player play = Player(tex, &def); + Player play = Player(tex, &def, 6.f); play.setPosition(10, 10); - game_sprites[1].push_back(&play); + m_sprite_layer[1].push_back(&play); + play.setObjects(&m_object_list); + Circle c = Circle(tex, 20.f); + c.setPosition(160, 40); + m_object_list.push_back(&c); + m_sprite_layer[1].push_back(&c); + Rectangle r = Rectangle(crate_tex, sf::Vector2f(40.f, 400.f)); + r.setPosition(90, 240); + m_object_list.push_back(&r); + m_sprite_layer[1].push_back(&r); TileMap background_map; int* p = new int[10000]; - for (int i = 0; i < 10000; i++) - p[i] = i%4; + for (int i = 0; i < 10000; i++) p[i] = i % 4; p[101] = 15; p[102] = 16; p[203] = 15; p[302] = 15; - if (!background_map.loadTileset(resourcePath + "background.png", sf::Vector2u(32, 32))) + if (!background_map.loadTileset(resourcePath + "background.png", + sf::Vector2u(32, 32))) printf("Loading tileset failed\n"); background_map.loadMap(p, 100, 100, view); background_map.flash(sf::Vector2i(0, 0)); - while (m_window->isOpen()) - { - float frame = clock.restart().asSeconds() * 60; + while (m_window->isOpen()) { + float frame = m_clock.restart().asSeconds() * 60; pollEvents(); - sf::Vector2f mouse_pos = m_window->mapPixelToCoords(sf::Mouse::getPosition(*m_window), m_window->getView()); + sf::Vector2f mouse_pos = m_window->mapPixelToCoords( + sf::Mouse::getPosition(*m_window), m_window->getView()); sf::Vector2f player_pos = play.getPosition(); float play_dir = get_angle(sf::Vector2f(mouse_pos) - player_pos); m_window->clear(); view = m_window->getView(); - sf::Vector2f v_center((3 * player_pos.x + mouse_pos.x) / 4.0f, (3 * player_pos.y + mouse_pos.y) / 4.0f); + sf::Vector2f v_center((3 * player_pos.x + mouse_pos.x) / 4.0f, + (3 * player_pos.y + mouse_pos.y) / 4.0f); view.setCenter(max(v_center, minCenter)); m_window->setView(view); background_map.loadVertexChunk(v_center); - play.move(sf::Vector2f(3,3), frame, false, m_input); + play.move(sf::Vector2f(3, 3), frame, false, m_input); play.setRotation(play_dir); m_window->draw(background_map); - for (int i = 3; i >= 1; i--) - { - for (int j = 0; j < game_sprites[i].size(); j++) - { - m_window->draw(*game_sprites[i][j]); - } - } + if (Object::g_draw_collisions) { + play.drawCollision(m_window); + for (int i = 0; i < m_object_list.size(); i++) { + m_object_list[i]->drawCollision(m_window); + } + } + for (int i = 3; i >= 1; i--) { + for (int j = 0; j < m_sprite_layer[i].size(); j++) { + m_window->draw(*m_sprite_layer[i][j]); + } + } m_window->display(); } } -Game::~Game() -{ - delete m_window; -} +Game::~Game() { delete m_window; } -void Game::pollEvents() -{ +void Game::pollEvents() { sf::Event event; - while (m_window->pollEvent(event)) - { - if (event.type == sf::Event::Closed) - { + while (m_window->pollEvent(event)) { + if (event.type == sf::Event::Closed) { m_window->close(); - } else if (event.type == sf::Event::KeyPressed) - { - switch (event.key.code) - { - case sf::Keyboard::A: - m_input |= 0b00000010; // Set bit 1 (left) - break; - case sf::Keyboard::D: - m_input |= 0b00000001; // Set bit 0 (right) - break; - case sf::Keyboard::W: - m_input |= 0b00001000; // Set bit 3 (up) - break; - case sf::Keyboard::S: - m_input |= 0b00000100; // Set bit 2 (down) - break; - case sf::Keyboard::Escape: - m_window->close(); - break; - default: - break; + } else if (event.type == sf::Event::KeyPressed) { + switch (event.key.code) { + case sf::Keyboard::A: + m_input |= 0b00000010; // Set bit 1 (left) + break; + case sf::Keyboard::D: + m_input |= 0b00000001; // Set bit 0 (right) + break; + case sf::Keyboard::W: + m_input |= 0b00001000; // Set bit 3 (up) + break; + case sf::Keyboard::S: + m_input |= 0b00000100; // Set bit 2 (down) + break; + case sf::Keyboard::Space: + Object::g_draw_collisions = !Object::g_draw_collisions; + break; + case sf::Keyboard::Escape: + m_window->close(); + break; + default: + break; } - } else if (event.type == sf::Event::KeyReleased) - { - switch (event.key.code) - { - case sf::Keyboard::A: - m_input &= ~0b00000010; // Reset bit 1 (left) - break; - case sf::Keyboard::D: - m_input &= ~0b00000001; // Reset bit 0 (right) - break; - case sf::Keyboard::W: - m_input &= ~0b00001000; // Reset bit 3 (up) - break; - case sf::Keyboard::S: - m_input &= ~0b00000100; // Reset bit 2 (down) - break; - default: - break; + } else if (event.type == sf::Event::KeyReleased) { + switch (event.key.code) { + case sf::Keyboard::A: + m_input &= ~0b00000010; // Reset bit 1 (left) + break; + case sf::Keyboard::D: + m_input &= ~0b00000001; // Reset bit 0 (right) + break; + case sf::Keyboard::W: + m_input &= ~0b00001000; // Reset bit 3 (up) + break; + case sf::Keyboard::S: + m_input &= ~0b00000100; // Reset bit 2 (down) + break; + default: + break; } } } diff --git a/src/Main.cpp b/src/Main.cpp index 8d385e7..48f424b 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -1,5 +1,2 @@ #include "Game.h" -int main() -{ - Game g = Game(); -} +int main() { Game g = Game(60); } diff --git a/src/Object.cpp b/src/Object.cpp new file mode 100644 index 0000000..2e439ed --- /dev/null +++ b/src/Object.cpp @@ -0,0 +1,179 @@ +#include "Object.h" + +#include "utils.h" + +bool Object::g_draw_collisions = false; + +Object::Object() : m_mass(0) { + sf::Vector2f object_size = + sf::Vector2f(getLocalBounds().width, getLocalBounds().height); + setOrigin(object_size.x / 2, object_size.y / 2); +}; + +Object::Object(sf::Texture &tex) : m_mass(0) { + setTexture(tex); + sf::Vector2f object_size = + sf::Vector2f(getLocalBounds().width, getLocalBounds().height); + setOrigin(object_size.x / 2, object_size.y / 2); +}; + +Circle::Circle(sf::Texture &tex) { + setTexture(tex); + sf::Vector2f object_size = + sf::Vector2f(getLocalBounds().width, getLocalBounds().height); + setOrigin(object_size.x / 2, object_size.y / 2); + m_radius = object_size.x / 2; +} + +Rectangle::Rectangle(sf::Texture &tex) { + setTexture(tex); + sf::Vector2f object_size = + sf::Vector2f(getLocalBounds().width, getLocalBounds().height); + setOrigin(object_size.x / 2, object_size.y / 2); + m_size = object_size; +} + +bool Circle::checkCollision(Object *obj) const { + if (dynamic_cast(obj)) { + return checkCollision(static_cast(obj)); + } else if (dynamic_cast(obj)) { + return checkCollision(static_cast(obj)); + } else { + return false; + } +} + +bool Circle::checkCollision(Circle *obj) const { + return len(obj->getPosition() - getPosition()) < (m_radius + obj->m_radius); +} + +bool Circle::checkCollision(Rectangle *obj) const { + return (getPosition().x + m_radius >= + obj->getPosition().x - obj->getSize().x / 2 && + getPosition().x - m_radius <= + obj->getPosition().x + obj->getSize().x / 2 && + getPosition().y + m_radius >= + obj->getPosition().y - obj->getSize().y / 2 && + getPosition().y - m_radius <= + obj->getPosition().y + obj->getSize().y / 2); +} + +bool Rectangle::checkCollision(Object *obj) const { + if (dynamic_cast(obj)) { + return checkCollision(static_cast(obj)); + } else if (dynamic_cast(obj)) { + return checkCollision(static_cast(obj)); + } else + return false; +} + +bool Rectangle::checkCollision(Circle *obj) const { + return (getPosition().x + m_size.x >= + obj->getPosition().x - obj->getRadius() / 2 && + getPosition().x - m_size.x <= + obj->getPosition().x + obj->getRadius() / 2 && + getPosition().y + m_size.y >= + obj->getPosition().y - obj->getRadius() / 2 && + getPosition().y - m_size.y <= + obj->getPosition().y + obj->getRadius() / 2); +} + +bool Rectangle::checkCollision(Rectangle *obj) const { + return (getPosition().x + m_size.x / 2 >= + obj->getPosition().x - obj->getSize().x / 2 && + getPosition().x - m_size.x / 2 <= + obj->getPosition().x + obj->getSize().x / 2 && + getPosition().y + m_size.y / 2 >= + obj->getPosition().y - obj->getSize().y / 2 && + getPosition().y - m_size.y / 2 <= + obj->getPosition().y + obj->getSize().y / 2); +} + +void Circle::snapCollision(Object *obj) { + if (dynamic_cast(obj)) { + snapCollision(static_cast(obj)); + } else if (dynamic_cast(obj)) { + snapCollision(static_cast(obj)); + } +} + +void Circle::snapCollision(Circle *obj) { + sf::Vector2f delta = obj->getPosition() - getPosition(); + float new_len = m_radius + obj->m_radius; + setPosition(obj->getPosition() - delta * new_len / len(delta)); +} + +void Circle::snapCollision(Rectangle *obj) { + sf::Vector2f delta = obj->getPosition() - getPosition(); + if (abs(delta.x) / obj->getSize().x < abs(delta.y) / obj->getSize().y) { + if (delta.y < 0) { + return setPosition( + getPosition().x, + obj->getPosition().y + obj->getSize().y / 2 + m_radius + 0.01f); + } else { + return setPosition( + getPosition().x, + obj->getPosition().y - obj->getSize().y / 2 - m_radius - 0.01f); + } + } else { + if (delta.x < 0) { + return setPosition( + obj->getPosition().x + obj->getSize().x / 2 + m_radius + 0.01f, + getPosition().y); + } else { + return setPosition( + obj->getPosition().x - obj->getSize().x / 2 - m_radius - 0.01f, + getPosition().y); + } + } +} + +void Rectangle::snapCollision(Object *obj) { + if (dynamic_cast(obj)) { + snapCollision(static_cast(obj)); + } else if (dynamic_cast(obj)) { + snapCollision(static_cast(obj)); + } +} + +void Rectangle::snapCollision(Circle *obj) {} + +void Rectangle::snapCollision(Rectangle *obj) { + sf::Vector2f delta = obj->getPosition() - getPosition(); + if (abs(delta.x) / (obj->getSize().x + getSize().x) < + abs(delta.y) / (obj->getSize().y + getSize().y)) { + if (delta.y < 0) { + return setPosition(getPosition().x, obj->getPosition().y + + obj->getSize().y / 2 + + getSize().y / 2 + 0.01f); + } else { + return setPosition(getPosition().x, obj->getPosition().y - + obj->getSize().y / 2 - + getSize().y / 2 - 0.01f); + } + } else { + if (delta.x < 0) { + return setPosition( + obj->getPosition().x + obj->getSize().x / 2 + getSize().x / 2 + 0.01f, + getPosition().y); + } else { + return setPosition( + obj->getPosition().x - obj->getSize().x / 2 - getSize().x / 2 - 0.01f, + getPosition().y); + } + } +} + +void Circle::drawCollision(sf::RenderTarget *target) const { + sf::CircleShape circle(m_radius); + circle.setOrigin(circle.getRadius(), circle.getRadius()); + circle.setPosition(getPosition()); + target->draw(circle); +} + +void Rectangle::drawCollision(sf::RenderTarget *target) const { + sf::RectangleShape rect(sf::Vector2f(m_size.x, m_size.y)); + rect.setOrigin(m_size.x / 2, m_size.y / 2); + rect.setPosition(getPosition()); + target->draw(rect); +} diff --git a/src/Player.cpp b/src/Player.cpp index c03e889..7d8a43a 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -1,38 +1,58 @@ #include "Player.h" + #include "utils.h" -Player::Player(): - spd_vec(0,0) -{ -} +Player::Player(sf::Texture& tex, MoveStats* s, float r) + : Circle(tex, r), m_stat(s) {} + +void Player::move(sf::Vector2f velocity, float fr, bool sprint, uint8_t input) { + sf::Vector2f v( + int((input & 0b00000001) != 0) - int((input & 0b00000010) != 0), + int((input & 0b00000100) != 0) - int((input & 0b00001000) != 0)); + + if (len(v)) m_spd_vec += v * (m_stat->accel * fr / len(v)); -Player::Player(sf::Texture& tex, MoveStats* s): - stat(s), - spd_vec(0,0) -{ - setTexture(tex); - sf::Vector2f player_size = sf::Vector2f(getLocalBounds().width, getLocalBounds().height); - setOrigin( player_size.x / 2, player_size.y / 2); + if (len(m_spd_vec)) { + m_spd_vec *= powf(m_stat->fric, fr); + if (len(m_spd_vec) < 0.05f) m_spd_vec *= 0.f; + } + + if (len(m_spd_vec) > m_stat->max_spd) + m_spd_vec *= (m_stat->max_spd / len(m_spd_vec)); + + sf::Sprite::move(m_spd_vec * fr); + checkCollision(); + m_last_pos = getPosition(); } -void Player::move(sf::Vector2f velocity, float fr, bool sprint, uint8_t input) -{ - sf::Vector2f v( - int((input & 0b00000001) != 0) - int((input & 0b00000010) != 0), - int((input & 0b00000100) != 0) - int((input & 0b00001000) != 0) - ); - - if (len(v)) - spd_vec += v * (stat->accel * fr / len(v)); - - if (len(spd_vec)) - { - spd_vec *= powf(stat->fric, fr); - if (len(spd_vec) < 0.05f) - spd_vec *= 0.f; - } - - if (len(spd_vec) > stat->max_spd) - spd_vec *= (stat->max_spd / len(spd_vec)); - sf::Sprite::move(spd_vec*fr); +void Player::checkCollision() { + if (m_objects_ref != nullptr) + for (int i = 0; i < m_objects_ref->size(); i++) { + if (Circle::checkCollision((*m_objects_ref)[i])) { + if (dynamic_cast((*m_objects_ref)[i])) { + const sf::Vector2f delta = + (*m_objects_ref)[i]->getPosition() - getPosition(); + const sf::Vector2f tangent = {delta.y, -delta.x}; + const float cos = + tangent.x * m_spd_vec.x + tangent.y * m_spd_vec.y / len(delta); + + m_spd_vec = cos * tangent / len(tangent) * 0.01f; + snapCollision((*m_objects_ref)[i]); + } else if (dynamic_cast((*m_objects_ref)[i])) { + const sf::Vector2f delta = + (*m_objects_ref)[i]->getPosition() - getPosition(); + if (abs(delta.x) / + static_cast((*m_objects_ref)[i])->getSize().x < + abs(delta.y) / + static_cast((*m_objects_ref)[i])->getSize().y) { + m_spd_vec = {0, m_spd_vec.y}; + } else { + m_spd_vec = {m_spd_vec.x, 0}; + } + snapCollision((*m_objects_ref)[i]); + } + } + } } + +void Player::setObjects(std::vector* objs) { m_objects_ref = objs; } diff --git a/src/TileMap.cpp b/src/TileMap.cpp index 963fb7a..6323973 100644 --- a/src/TileMap.cpp +++ b/src/TileMap.cpp @@ -1,25 +1,25 @@ #include "TileMap.h" + #include + #include "utils.h" -bool TileMap::loadTileset(const std::string& tileset, sf::Vector2u tileSize) -{ - if (!m_tileset.loadFromFile(tileset)) - return false; +bool TileMap::loadTileset(const std::string& tileset, sf::Vector2u tileSize) { + if (!m_tileset.loadFromFile(tileset)) return false; m_tileSize = tileSize; return (m_tileSize != sf::Vector2u(0, 0)); } -void TileMap::loadMap(const int* tiles, unsigned int mapWidth, unsigned int mapHeight, sf::View view) -{ +void TileMap::loadMap(const int* tiles, unsigned int mapWidth, + unsigned int mapHeight, sf::View view) { m_tiles.resize(mapWidth * mapHeight); - for (int i = 0; i < mapWidth * mapHeight; i++) - m_tiles[i] = tiles[i]; + for (int i = 0; i < mapWidth * mapHeight; i++) m_tiles[i] = tiles[i]; m_mapSize = sf::Vector2u(mapWidth, mapHeight); sf::Vector2f chunk = view.getSize() * 5.0f; - m_chunkSize = sf::Vector2u(chunk.x / m_tileSize.x + 1, chunk.y / m_tileSize.y + 1); + m_chunkSize = + sf::Vector2u(chunk.x / m_tileSize.x + 1, chunk.y / m_tileSize.y + 1); m_vertices.setPrimitiveType(sf::Quads); m_vertices.resize(m_chunkSize.x * m_chunkSize.y * 4); @@ -27,8 +27,7 @@ void TileMap::loadMap(const int* tiles, unsigned int mapWidth, unsigned int mapH } // view_coord is the center coordinates of the view -void TileMap::loadVertexChunk(sf::Vector2f view_coord) -{ +void TileMap::loadVertexChunk(sf::Vector2f view_coord) { /** * chunkLimit represents the furthest distance the view center * can to be from the chunk center before chunk is redrawn @@ -36,9 +35,9 @@ void TileMap::loadVertexChunk(sf::Vector2f view_coord) float chunkLimit_x = m_chunkSize.x * m_tileSize.x * 0.5; float chunkLimit_y = m_chunkSize.y * m_tileSize.y * 0.5; - if (len(m_center - view_coord) < len(sf::Vector2f(chunkLimit_x, chunkLimit_y)) * 0.3) + if (len(m_center - view_coord) < + len(sf::Vector2f(chunkLimit_x, chunkLimit_y)) * 0.3) return; - // TODO: Tests on view_coord & center to ensure following mouse/player works @@ -50,13 +49,12 @@ void TileMap::loadVertexChunk(sf::Vector2f view_coord) flash(sf::Vector2i(t_x / m_tileSize.x, t_y / m_tileSize.y)); } -void TileMap::flash(sf::Vector2i t) -{ +void TileMap::flash(sf::Vector2i t) { // Populate the vertex array, with one quad per tile - for (unsigned int i = t.x; i < std::min(m_chunkSize.x + t.x, m_mapSize.x); i++) - { - for (unsigned int j = t.y; j < std::min(m_chunkSize.y + t.y, m_mapSize.y); j++) - { + for (unsigned int i = t.x; i < std::min(m_chunkSize.x + t.x, m_mapSize.x); + i++) { + for (unsigned int j = t.y; j < std::min(m_chunkSize.y + t.y, m_mapSize.y); + j++) { // Get the current tile number int tileNumber = m_tiles[i + j * m_mapSize.x]; @@ -70,23 +68,23 @@ void TileMap::flash(sf::Vector2i t) // Define corners quad[0].position = sf::Vector2f(i * m_tileSize.x, j * m_tileSize.y); quad[1].position = sf::Vector2f((i + 1) * m_tileSize.x, j * m_tileSize.y); - quad[2].position = sf::Vector2f((i + 1) * m_tileSize.x, (j + 1) * m_tileSize.y); + quad[2].position = + sf::Vector2f((i + 1) * m_tileSize.x, (j + 1) * m_tileSize.y); quad[3].position = sf::Vector2f(i * m_tileSize.x, (j + 1) * m_tileSize.y); // Define texture coordinates quad[0].texCoords = sf::Vector2f(tu * m_tileSize.x, tv * m_tileSize.y); - quad[1].texCoords = sf::Vector2f((tu + 1) * m_tileSize.x, tv * m_tileSize.y); - quad[2].texCoords = sf::Vector2f((tu + 1) * m_tileSize.x, (tv + 1) * m_tileSize.y); - quad[3].texCoords = sf::Vector2f(tu * m_tileSize.x, (tv + 1) * m_tileSize.y); + quad[1].texCoords = + sf::Vector2f((tu + 1) * m_tileSize.x, tv * m_tileSize.y); + quad[2].texCoords = + sf::Vector2f((tu + 1) * m_tileSize.x, (tv + 1) * m_tileSize.y); + quad[3].texCoords = + sf::Vector2f(tu * m_tileSize.x, (tv + 1) * m_tileSize.y); } } } -void TileMap::draw(sf::RenderTarget& target, sf::RenderStates states) const -{ - // Combine the TileMap's transform with the current RenderStates - states.transform *= getTransform(); - +void TileMap::draw(sf::RenderTarget& target, sf::RenderStates states) const { // Set the TileMap's texture as the current texture in the RenderStates states.texture = &m_tileset;