#include "elements.hpp" #include "globals.hpp" #include #include #include #include #ifdef __APPLE__ #include #include #else #include #endif Entity::Entity(sf::Vector2 size, sf::Vector2 pos, sf::Vector2f velocity, float border_thickness, sf::Color inside_color, sf::Color border_color) { rect.setSize(size); rect.setPosition(pos); rect.setOutlineThickness(border_thickness); rect.setFillColor(inside_color); rect.setOutlineColor(border_color); _velocity = velocity; } void Entity::set_velocity(sf::Vector2 velocity) { _velocity = velocity; } void Entity::set_velocity_x(int velocity) { _velocity.x = velocity; } void Entity::set_velocity_y(int velocity) { _velocity.y = velocity; } sf::Vector2 Entity::get_velocity() { return _velocity; } CollisionDir Entity::find_intersection(Entity &entity) { sf::FloatRect a = rect.getGlobalBounds(); sf::FloatRect b = entity.rect.getGlobalBounds(); auto inter = a.findIntersection(b); if (!inter) { return CollisionDir::None; } const auto overlap = *inter; float overlapW = overlap.size.x; float overlapH = overlap.size.y; // Compare which axis overlap is smaller if (overlapW < overlapH) { // Horizontal collision return (a.position.x < b.position.x) ? CollisionDir::Right // a hit b from the left side : CollisionDir::Left; // a hit b from the right side } else { // Vertical collision return (a.position.y < b.position.y) ? CollisionDir::Bottom // a hit b from above : CollisionDir::Top; // a hit b from below } } Player::Player(sf::Vector2 size, sf::Vector2 pos, sf::Vector2f velocity, float border_thickness, float gravity, float max_acceleration, float dash_distance, sf::Color inside_color, sf::Color border_color) : Entity(size, pos, velocity, border_thickness, inside_color, border_color) { _min_velocity = velocity; m_acceleration = gravity; m_jump_strength = max_acceleration; m_dash_distance = dash_distance; m_jumping = m_dash = false; } void Player::handle_movment() { if(sf::Keyboard::isKeyPressed(sf::Keyboard::Key::D)) { rect.move({_velocity.x, 0}); } if(sf::Keyboard::isKeyPressed(sf::Keyboard::Key::A)) { rect.move({-_velocity.x, 0}); } if(timers.dash_cooldown <= 0) { m_dash = false; } if(sf::Keyboard::isKeyPressed(sf::Keyboard::Key::W) && !m_dash && timers.dash_cooldown <= 0) { m_dash = true; _velocity.x = m_dash_distance; timers.dash_cooldown = timers.dash_cooldown_max; } if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Space) && !m_jumping) { m_jumping = true; _velocity.y = -m_jump_strength; // push up } } void Player::handle_gravity() { if(get_velocity().x > _min_velocity.x) { set_velocity_x(get_velocity().x - m_acceleration); } set_velocity_y(get_velocity().y + m_acceleration); rect.move({0, get_velocity().y}); } void Player::horizontal_no_out_of_bounds(Entity &base) { float right_border = WIDTH - rect.getSize().x; if(rect.getPosition().x > right_border) { 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(Entity &base) { float groundY = base.rect.getPosition().y - base.rect.getSize().y - rect.getSize().y - base.rect.getOutlineThickness() - rect.getOutlineThickness(); if (rect.getPosition().y >= groundY) { rect.setPosition({rect.getPosition().x, groundY}); set_velocity_y(0); m_jumping = false; } } // bool Player::get_horizontal_collision(Entity *wall_list[MAX_ROWS][MAX_COLS]) { bool Player::get_horizontal_collision(Entity *wall_list[MAX_ROWS][MAX_COLS]) { #ifdef __APPLE__ for(auto [i, j] : ranges::views::cartesian_product(ranges::views::iota(0, MAX_ROWS), ranges::views::iota(0, MAX_COLS))) { #else for(auto [i, j] : std::views::cartesian_product(std::views::iota(0, MAX_ROWS), std::views::iota(0, MAX_COLS))) { #endif if(wall_list[i][j] == nullptr) continue; auto collision = wall_list[i][j]->find_intersection(*this); if(collision == CollisionDir::None) continue; if(collision == CollisionDir::Left) { rect.setPosition({ wall_list[i][j]->rect.getPosition().x - rect.getSize().x, rect.getPosition().y }); } if(collision == CollisionDir::Right) { rect.setPosition({ wall_list[i][j]->rect.getPosition().x + wall_list[i][j]->rect.getSize().x, rect.getPosition().y }); } } return false; } bool Player::get_vertical_top_collision(Entity *wall_list[MAX_ROWS][MAX_COLS]) { #ifdef __APPLE__ for(auto [i, j] : ranges::views::cartesian_product(ranges::views::iota(0, MAX_ROWS), ranges::views::iota(0, MAX_COLS))) { #else for(auto [i, j] : std::views::cartesian_product(std::views::iota(0, MAX_ROWS), std::views::iota(0, MAX_COLS))) { #endif if(wall_list[i][j] == nullptr) continue; auto collision = find_intersection(*wall_list[i][j]); if(collision == CollisionDir::None) continue; if(collision == CollisionDir::Top) { rect.setPosition({ rect.getPosition().x, wall_list[i][j]->rect.getSize().y + wall_list[i][j]->rect.getPosition().y + rect.getOutlineThickness()}); set_velocity_y(0); return true; } } return false; } bool Player::get_vertical_bottom_collision(Entity *wall_list[MAX_ROWS][MAX_COLS]) { #ifdef __APPLE__ for(auto [i, j] : ranges::views::cartesian_product(ranges::views::iota(0, MAX_ROWS), ranges::views::iota(0, MAX_COLS))) { #else for(auto [i, j] : std::views::cartesian_product(std::views::iota(0, MAX_ROWS), std::views::iota(0, MAX_COLS))) { #endif if(wall_list[i][j] == nullptr) continue; auto collision = find_intersection(*wall_list[i][j]); if(collision == CollisionDir::None) continue; if(collision == CollisionDir::Bottom && get_velocity().y > 0) { rect.setPosition({ rect.getPosition().x, wall_list[i][j]->rect.getPosition().y - rect.getSize().y }); m_jumping = false; set_velocity_y(0); return true; } } return false; }