diff --git a/.clang-format b/.clang-format index 271cffa..e34e8c0 100644 --- a/.clang-format +++ b/.clang-format @@ -1,5 +1,4 @@ --- -# Base Style BasedOnStyle: Google Standard: Latest ColumnLimit: 100 @@ -7,50 +6,15 @@ UseTab: Always TabWidth: 8 IndentWidth: 8 BreakBeforeBraces: Allman -# BreakBeforeBraces: Stroustrup SpaceBeforeCpp11BracedList: true SeparateDefinitionBlocks: Always Cpp11BracedListStyle: false BreakAfterReturnType: TopLevel AlignTrailingComments: Kind: Always - # OverEmptyLines: 2 ReflowComments: Always AllowShortFunctionsOnASingleLine: All AllowShortIfStatementsOnASingleLine: AllIfsAndElse AllowShortLoopsOnASingleLine: true -# RemoveEmptyLinesInUnwrappedLines: true - -# ReflowComments: true -# SortIncludes: true -# IncludeBlocks: Regroup -# -# # Indentation -# ContinuationIndentWidth: 8 -# AlignAfterOpenBracket: true -# PointerAlignment: Left -# ReferenceAlignment: Left -# -# # Braces -# BreakBeforeBraces: Custom -# BraceWrapping: -# AfterFunction: false -# AfterClass: false -# AfterControlStatement: false -# AfterNamespace: false -# IndentBraces: false -# -# # Containers & lists -# -# SpaceBeforeCpp11BracedList: true -# BreakAfterOpenBracketBracedList: true -# -# # Control statements & loops -# SpaceBeforeParens: Custom -# SpaceBeforeParensOptions: -# AfterControlStatements: true -# SpaceBeforeRangeBasedForLoopColon: true -# -# # Preprocessor -# IndentPPDirectives: AfterHash -# PPIndentWidth: 0 +IndentAccessModifiers: false # Indent access specifiers by one level +AccessModifierOffset: -4 # Optional: adjust offset relative to the class indentation level diff --git a/GEMINI.md b/GEMINI.md new file mode 100644 index 0000000..27db880 --- /dev/null +++ b/GEMINI.md @@ -0,0 +1 @@ +When the user provides code, they prefer suggestions for changes rather than direct modifications to the files, unless they explicitly ask for modifications. \ No newline at end of file diff --git a/include/data.hpp b/include/data.hpp index c11f30d..fdf78be 100644 --- a/include/data.hpp +++ b/include/data.hpp @@ -13,7 +13,6 @@ #include #include -#include #include #include @@ -21,34 +20,35 @@ struct ObjectData { - sf::Vector2 size { TILESIZE, TILESIZE }; - sf::Vector2 pos { TILESIZE, TILESIZE }; - sf::Color interior_color { sf::Color::Black }; - sf::Color exterior_color { sf::Color::White }; - float edge { -2.0f }; + const sf::Vector2 size { TILESIZE, TILESIZE }; + const sf::Vector2 pos { TILESIZE, TILESIZE }; + const sf::Color interior_color { sf::Color::Black }; + const sf::Color exterior_color { sf::Color::White }; + const float edge { -2.0f }; }; -struct EntityData : ObjectData +struct EntityData { - sf::Vector2 velocity { 0, 0 }; + ObjectData object; + const sf::Vector2 velocity { 0, 0 }; }; -struct PlayerData : EntityData +struct PlayerData { - float max_dash_acceleration { 0.0f }; - float max_vertical_acceleration { 0.0f }; + EntityData entity; + const float max_dash_acceleration { 0.0f }; + const float max_vertical_acceleration { 0.0f }; }; struct LevelData { - // std::array, MAX_ROWS> data {}; const char data[MAX_ROWS][MAX_COLS + 1]; }; struct TimerData { - std::string name { "NULL" }; - float max_time { 1.f }; + const std::string name { "NULL" }; + const float max_time { 1.f }; }; extern const std::vector object_data; diff --git a/include/elements.hpp b/include/elements.hpp index 98cc0a1..70ad29e 100644 --- a/include/elements.hpp +++ b/include/elements.hpp @@ -13,63 +13,70 @@ #include "globals.hpp" #include "scheduler.hpp" +float +total_distance(int k); + +float const +distance_to_acceleration(int target); + +struct Object; class Entity; -class Object; class Player; -class Object +struct Object { - public: - Object(ObjectData data); + Object(ObjectData data) + { + rect.setSize(data.size); + rect.setPosition(data.pos); + rect.setOutlineThickness(data.edge); + rect.setFillColor(data.interior_color); + rect.setOutlineColor(data.exterior_color); + }; + sf::RectangleShape rect; }; class Entity : public Object { - public: - Entity(EntityData data) : Object(data), _velocity(data.velocity) {}; + public: + Entity(EntityData data) : Object(data.object), _velocity(data.velocity) {}; void set_velocity(sf::Vector2f velocity); void set_velocity_x(int velocity); void set_velocity_y(int velocity); - sf::Vector2 get_velocity(); + const sf::Vector2 get_velocity(); - protected: + protected: sf::Vector2f _velocity; }; class Player : public Entity { - public: - Player(PlayerData data, float gravity) - : Entity(data), - max_dash_acceleration(data.max_vertical_acceleration), - max_vertical_acceleration(data.max_vertical_acceleration), - gravity(gravity) {}; + public: + Player(PlayerData data) + : Entity(data.entity), + max_dash_acceleration(data.max_dash_acceleration), + max_vertical_acceleration(data.max_vertical_acceleration) + { + bounding_box.rect.setSize( + { total_distance(max_dash_acceleration), + data.entity.object.size.y }); + }; + + Object bounding_box { object_data[1] }; float max_vertical_acceleration; float max_dash_acceleration; - float gravity; bool m_jumping { false }; - void handle_movment(Timer& dash, - std::array, 19>, 13>& tilemap); + void handle_bounding_box(std::array, MAX_COLS>, MAX_ROWS>& tilemap); + void handle_movment(std::optional dash); void handle_gravity(); - bool get_jumping(); - void horizontal_no_out_of_bounds(); - void vertical_no_out_of_bounds(); bool get_horizontal_collision( std::array, MAX_COLS>, MAX_ROWS>& tilemap); bool get_vertical_collision( std::array, MAX_COLS>, MAX_ROWS>& tilemap); - // bool get_vertical_bottom_collision( - // std::array, MAX_COLS>, MAX_ROWS>& tilemap); - private: - std::string direction; + private: + std::string direction { "left" }; }; -float -total_distance(int k); - -float -distance_to_acceleration(int target); - #endif diff --git a/include/maps.hpp b/include/maps.hpp index 80ea818..01563b2 100644 --- a/include/maps.hpp +++ b/include/maps.hpp @@ -14,11 +14,11 @@ class Manager public: void clear(); void load(LevelData level); - void draw(sf::RenderWindow& window); + const void draw(sf::RenderWindow& window); void set_next(); void set_previous(); - int get_active(); void set_active(int level); + const int get_active(); std::array, MAX_COLS>, MAX_ROWS> tilemap = {}; private: diff --git a/include/scheduler.hpp b/include/scheduler.hpp index 76dd6c2..00f6360 100644 --- a/include/scheduler.hpp +++ b/include/scheduler.hpp @@ -2,6 +2,7 @@ #define SCHEDULER_HPP #include +#include #include #include #include @@ -26,7 +27,7 @@ struct Scheduler { Scheduler(); std::vector timers; void update(std::atomic& running); - int pull(std::string name); + std::optional pull(std::string name); }; diff --git a/src/data.cpp b/src/data.cpp index 1a6934a..3d54d8c 100644 --- a/src/data.cpp +++ b/src/data.cpp @@ -14,31 +14,21 @@ const std::vector object_data { }, }; -/* - Example EntityData - []() -> EntityData { - EntityData e; - e.size = { TILESIZE / 1.5f, TILESIZE / 1.5f }; - e.pos = { 400.0f, 300.0f }; - e.interior_color = sf::Color::Blue; - e.velocity = { 6.0f, 0.0f }; - return e; - }(), -*/ const std::vector entity_data { {}, }; -const PlayerData player_data = [] -{ - PlayerData data; - data.size = { TILESIZE / 2.0f, TILESIZE / 2.0f }; - data.edge = -1.0f; - data.velocity = { 3.0f, 0.0f }; - data.max_dash_acceleration = 30.0f; // 15 - data.max_vertical_acceleration = 12.5f; // 12.5 default - return data; -}(); +const PlayerData player_data { + .entity { + .object { + .size = { TILESIZE / 2.f, TILESIZE / 2.f }, + .edge = -1.f, + }, + .velocity = { 3.f, 0.f }, + }, + .max_dash_acceleration = 30.f, + .max_vertical_acceleration = 12.5f, +}; const std::vector timer_data { {}, @@ -110,7 +100,7 @@ const std::vector level_data = { " ", " 0 ", " ", - " 0 0", + " 0 ", "1-----------------2", }}, }; diff --git a/src/elements.cpp b/src/elements.cpp index 259abe3..d78b2c2 100644 --- a/src/elements.cpp +++ b/src/elements.cpp @@ -1,13 +1,13 @@ #include "elements.hpp" +#include + #include #include #include #include #include #include -#include -#include #include #include @@ -25,23 +25,18 @@ namespace rv = std::views; float total_distance(int k) { - if (k > 0) return k + total_distance(k - 1); + if (k > 3) return k + total_distance(k - 1); else return 0; } -float +const float distance_to_acceleration(int target) { - return roundf(-1 + sqrtf(1 + 8 * target) / 2); -} - -Object::Object(ObjectData data) -{ - rect.setSize(data.size); - rect.setPosition(data.pos); - rect.setOutlineThickness(data.edge); - rect.setFillColor(data.interior_color); - rect.setOutlineColor(data.exterior_color); + if (target <= 0) + { + return 0; + } + return roundf((-1 + sqrtf(1 + 8 * target)) / 2); } void @@ -62,15 +57,79 @@ Entity::set_velocity_y(int velocity) _velocity.y = velocity; } -sf::Vector2 +const sf::Vector2 Entity::get_velocity() { return _velocity; } void -Player::handle_movment(Timer& dash, - std::array, 19>, 13>& tilemap) +Player::handle_bounding_box( + std::array, MAX_COLS>, MAX_ROWS>& tilemap) +{ + float max_possible_dist = total_distance(player_data.max_dash_acceleration); + sf::FloatRect dash_check_box; + if (direction == "right") + { + dash_check_box = sf::FloatRect( + sf::Vector2f({ rect.getPosition().x + rect.getSize().x, rect.getPosition().y }), + sf::Vector2f({ max_possible_dist, rect.getSize().y })); + } + else + { + dash_check_box = + sf::FloatRect(sf::Vector2f({ rect.getPosition().x - max_possible_dist, + rect.getPosition().y }), + sf::Vector2f({ max_possible_dist, rect.getSize().y })); + } + + float allowed_dash_dist = max_possible_dist; + for (auto [i, j] : rv::cartesian_product(rv::iota(0, MAX_ROWS), rv::iota(0, MAX_COLS))) + { + if (tilemap[i][j] == nullptr) continue; + sf::FloatRect tile = tilemap[i][j]->rect.getGlobalBounds(); + auto intersection = dash_check_box.findIntersection(tile); + float dist_to_tile; + if (intersection.has_value()) + { + if (direction == "right") + { + dist_to_tile = + tile.position.x - (rect.getPosition().x + rect.getSize().x); + } + else + { + dist_to_tile = + rect.getPosition().x - (tile.position.x + tile.size.x); + } + if (dist_to_tile < allowed_dash_dist) + { + allowed_dash_dist = dist_to_tile; + } + } + + if (allowed_dash_dist < 0) + { + allowed_dash_dist = 0; + } + + bounding_box.rect.setSize({ allowed_dash_dist, rect.getSize().y }); + if (direction == "right") + { + bounding_box.rect.setPosition( + { rect.getPosition().x + rect.getSize().x, rect.getPosition().y }); + } + else + { + bounding_box.rect.setPosition( + { rect.getPosition().x - allowed_dash_dist, rect.getPosition().y }); + } + max_dash_acceleration = distance_to_acceleration(allowed_dash_dist); + } +} + +void +Player::handle_movment(std::optional dash) { if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::D)) { @@ -82,10 +141,11 @@ Player::handle_movment(Timer& dash, direction = "left"; rect.move({ -_velocity.x, 0 }); } - if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::W) && dash.get_time() <= 0) + if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::W) && (*dash)->get_time() <= 0 && + dash.has_value()) { _velocity.x = max_dash_acceleration; - dash.reset(); + (*dash)->reset(); } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Space) && !m_jumping && _velocity.x <= 3) { @@ -97,37 +157,20 @@ Player::handle_movment(Timer& dash, void Player::handle_gravity() { - if (get_velocity().x > player_data.velocity.x) + if (get_velocity().x > player_data.entity.velocity.x) { - set_velocity_x(get_velocity().x - gravity); + set_velocity_x(get_velocity().x - GRAVITY); + } + else + { + set_velocity_x(get_velocity().x + GRAVITY); } - set_velocity_y(get_velocity().y + gravity); + set_velocity_y(get_velocity().y + GRAVITY); rect.move({ 0, get_velocity().y }); -} - -void -Player::horizontal_no_out_of_bounds() -{ - float right_border = WIDTH - rect.getSize().x; - if (rect.getPosition().x > right_border) + if (get_velocity().y > ((float)TILESIZE / 2 - GRAVITY)) { - rect.setPosition({ right_border, rect.getPosition().y }); - } - if (rect.getPosition().x < std::abs(rect.getOutlineThickness())) - { - rect.setPosition({ 0, rect.getPosition().y }); - } -} - -void -Player::vertical_no_out_of_bounds() -{ - if (rect.getPosition().y >= HEIGHT - 48) - { - rect.setPosition({ rect.getPosition().x, HEIGHT - 48 }); - set_velocity_y(0); - m_jumping = false; + set_velocity_y((TILESIZE / 2) - GRAVITY); } } @@ -174,7 +217,8 @@ Player::get_vertical_collision( auto intersection = self.findIntersection(tile); if (!intersection) continue; if (intersection->position.y <= 0) continue; - if (intersection->size.y < intersection->size.x || intersection->size.y - intersection->size.x < rect.getSize().x) + if (intersection->size.y < intersection->size.x || + intersection->size.y - intersection->size.x < rect.getSize().x) { if (self.position.y < tile.position.y) { @@ -186,7 +230,9 @@ Player::get_vertical_collision( } else { - rect.setPosition({ rect.getPosition().x, tile.position.y + tilemap[i][j]->rect.getSize().y }); + rect.setPosition( + { rect.getPosition().x, + tile.position.y + tilemap[i][j]->rect.getSize().y }); set_velocity_y(0); return true; } @@ -194,26 +240,3 @@ Player::get_vertical_collision( } return false; } - -// -// bool -// Player::get_vertical_bottom_collision( -// std::array, MAX_COLS>, MAX_ROWS>& tilemap) -// { -// for (auto [i, j] : rv::cartesian_product(rv::iota(0, MAX_ROWS), rv::iota(0, MAX_COLS))) -// { -// if (tilemap[i][j] == nullptr) continue; -// auto collision = find_intersection(*tilemap[i][j]); -// if (collision == CollisionDir::None) continue; -// if (collision == CollisionDir::Bottom && get_velocity().y > 0) -// { -// rect.setPosition( -// { rect.getPosition().x, -// tilemap[i][j]->rect.getPosition().y - rect.getSize().y }); -// m_jumping = false; -// set_velocity_y(0); -// return true; -// } -// } -// return false; -// } diff --git a/src/main.cpp b/src/main.cpp index 2aeaeac..76f68cf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -15,7 +15,7 @@ #ifdef __APPLE__ #include #include -namespace rv = ranges::views; +// namespace rv = ranges::views; std::string assets = "/Users/andrew/personal/Projects/CPP/engine/assets/"; #else #include @@ -41,8 +41,7 @@ main() sf::RenderWindow window(sf::VideoMode({ WIDTH, HEIGHT }), "engine", sf::Style::Default); window.setFramerateLimit(FPS); - Player player { player_data, GRAVITY }; - // player.initialize_bounding_box(player.get_velocity().x); + Player player { player_data }; sf::Font font(assets + "pixel.ttf"); sf::Text text(font, "0, 0", 16); @@ -77,46 +76,22 @@ main() } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Enter) && - scheduler.timers.at(1).below_or_zero()) + (*scheduler.pull("Dash"))->below_or_zero()) { map_manager.set_next(); - scheduler.timers.at(1).reset(); + (*scheduler.pull("Dash"))->reset(); } - player.handle_movment(scheduler.timers.at(scheduler.pull("Dash")), - map_manager.tilemap); - std::cout << player.get_horizontal_collision(map_manager.tilemap) << "\n"; + player.handle_movment(scheduler.pull("Dash")); + player.get_horizontal_collision(map_manager.tilemap); player.handle_gravity(); player.get_vertical_collision(map_manager.tilemap); - player.vertical_no_out_of_bounds(); - // if (player.get_velocity().y > ((float)TILESIZE / 2 - GRAVITY)) - // { - // player.set_velocity_y((TILESIZE / 2) - GRAVITY); - // } - - // if (!player.get_vertical_bottom_collision(map_manager.tilemap)) - // { - // player.get_vertical_top_collision(map_manager.tilemap); - // } - // if (player.bounding_box != nullptr) - // { - // player.update_bounding_box(); - // // player.check_bounding_box(map_manager.tilemap); - // } - // for (auto [i, j] : - // rv::cartesian_product(rv::iota(0, MAX_ROWS), rv::iota(0, MAX_COLS))) - // { - // if (map_manager.tilemap[i][j] == nullptr) continue; - // if(player.find_intersection(*map_manager.tilemap[i][j]).x > 0) { - // std::cout << player.find_intersection(*map_manager.tilemap[i][j]).x << "\n"; - // // running = false; - // // window.close(); - // } - // } + player.handle_bounding_box(map_manager.tilemap); map_manager.draw(window); window.draw(player.rect); + window.draw(player.bounding_box.rect); window.draw(text); window.display(); } diff --git a/src/maps.cpp b/src/maps.cpp index 24f5b1e..b2f8119 100644 --- a/src/maps.cpp +++ b/src/maps.cpp @@ -25,7 +25,7 @@ Manager::clear() } } -int +const int Manager::get_active() { return _active; @@ -53,7 +53,7 @@ Manager::set_previous() load(level_data[_active]); } -void +const void Manager::draw(sf::RenderWindow& window) { for (auto [i, j] : rv::cartesian_product(rv::iota(0, MAX_ROWS), rv::iota(0, MAX_COLS))) diff --git a/src/scheduler.cpp b/src/scheduler.cpp index f9c3141..ccfe189 100644 --- a/src/scheduler.cpp +++ b/src/scheduler.cpp @@ -48,13 +48,13 @@ Timer::update() } } -int +std::optional Scheduler::pull(std::string name) { try { for (int i = 0; i < timers.size(); i++) { if (timers[i].get_name() == name) { - return i; + return &timers[i]; } } throw -1; @@ -62,10 +62,10 @@ Scheduler::pull(std::string name) catch (int x) { std::cout << "No valid timer with name: (" << name << ") as a value\n"; std::cout << "Using defualt timer values\n"; - return -1; + return std::nullopt; } - return 0; + return std::nullopt; } void