diff --git a/include/Actor.hpp b/include/Actor.hpp index c0ae3a3..cd379c5 100644 --- a/include/Actor.hpp +++ b/include/Actor.hpp @@ -15,7 +15,9 @@ namespace Actor { enum class Direction { left, - right + right, + up, + down }; @@ -41,7 +43,7 @@ namespace Actor protected: sf::Sprite sprite; static inline std::unordered_map textures{}; - Direction direction_x; + Direction direction; Multiplayer::Inventory inventory; virtual void draw(sf::RenderTarget& target, sf::RenderStates states=sf::RenderStates()) const; diff --git a/include/Controls.hpp b/include/Controls.hpp index 7e71ca1..03c0581 100644 --- a/include/Controls.hpp +++ b/include/Controls.hpp @@ -20,8 +20,8 @@ class Controls public: static void applyWindowSettings(); static void drawInterfaces(); - static void setLastActionTimepoint(const Time::Time& t = Time::getTimeNow()); - static sf::Uint32 getDeltaTime(); + static inline void setLastActionTimepoint(const Time::Time& t = Time::getTimeNow()) { last_action_timepoint = t; } + static inline sf::Uint32 getDeltaTime() { return Time::getTimeNow() - last_action_timepoint; } static void handleEvents(); static sf::Vector2f getDirection(); static void handleFrameStep(); @@ -33,10 +33,12 @@ class Controls private: Controls(); static void addEvent(const sf::Event&); + static void handleLeftClick(); + static void handleMouseDirection(); static Multiplayer::UdpManager udp_manager; static sf::Vector2f direction; - static bool left, right, up, down; + static bool left, right, up, down, mouse_direction_control; static inline sf::Uint32 last_action_timepoint; static bool draw_menu, draw_inventory; static sf::RectangleShape menu; diff --git a/src/common/Actor.cpp b/src/common/Actor.cpp index b55e596..c3a656d 100644 --- a/src/common/Actor.cpp +++ b/src/common/Actor.cpp @@ -6,10 +6,10 @@ namespace Actor Actor::Actor(const sf::Vector2f& position, const std::unordered_map& new_inventory) { if (!Actor::textures.size()) - load_textures("textures/actors/Guy_16x32"); - direction_x = Direction::right; + load_textures("textures/actors/Ted_16x32"); + direction = Direction::right; sprite.setPosition(position); - sprite.setTexture(Actor::textures.at(direction_x)); + sprite.setTexture(Actor::textures[direction]); sprite.setScale(Constants::getPIXEL_SIZE(), Constants::getPIXEL_SIZE()); setInventory(new_inventory); } @@ -18,24 +18,35 @@ namespace Actor Actor::Actor(sf::Vector2f&& position, std::unordered_map&& new_inventory) { if (!Actor::textures.size()) - load_textures("textures/actors/Guy_16x32"); - direction_x = Direction::right; + load_textures("textures/actors/Ted_16x32"); + direction = Direction::right; sprite.setPosition(position); - sprite.setTexture(Actor::textures.at(direction_x)); + sprite.setTexture(Actor::textures[direction]); sprite.setScale(Constants::getPIXEL_SIZE(), Constants::getPIXEL_SIZE()); inventory = new_inventory; } - void Actor::check_direction(const sf::Vector2f& direction) + void Actor::check_direction(const sf::Vector2f& direction_vector) { - if (direction.x > 0 && direction_x != Direction::right) - direction_x = Direction::right; - else if (direction.x < 0 && direction_x != Direction::left) - direction_x = Direction::left; - else + auto direction_vector_normalized = linalg::normalize(direction_vector); + if (direction_vector_normalized == sf::Vector2f(0.f, 0.f)) return; - sprite.setTexture(Actor::textures.at(direction_x)); + if (abs(direction_vector_normalized.x) > .7071f) + { + if (direction_vector_normalized.x > 0) + direction = Direction::right; + else + direction = Direction::left; + } + else + { + if (direction_vector_normalized.y > 0) + direction = Direction::up; + else + direction = Direction::down; + } + sprite.setTexture(Actor::textures[direction]); } @@ -147,8 +158,14 @@ namespace Actor left_texture.loadFromFile(texture_dir_path + "/left.png"); auto right_texture = sf::Texture(); right_texture.loadFromFile(texture_dir_path + "/right.png"); + auto up_texture = sf::Texture(); + up_texture.loadFromFile(texture_dir_path + "/front.png"); + auto down_texture = sf::Texture(); + down_texture.loadFromFile(texture_dir_path + "/back.png"); Actor::textures[Direction::left] = std::move(left_texture); Actor::textures[Direction::right] = std::move(right_texture); + Actor::textures[Direction::up] = std::move(up_texture); + Actor::textures[Direction::down] = std::move(down_texture); } diff --git a/src/common/Controls.cpp b/src/common/Controls.cpp index 61af881..8cb900e 100644 --- a/src/common/Controls.cpp +++ b/src/common/Controls.cpp @@ -6,6 +6,7 @@ bool Controls::left = 0, Controls::right = 0, Controls::up = 0, Controls::down = 0, + Controls::mouse_direction_control = 0, Controls::draw_menu = 0, Controls::draw_inventory = 0; sf::RenderWindow Controls::window(sf::VideoMode().getFullscreenModes().at(0), "SFML window", sf::Style::Fullscreen); @@ -34,6 +35,52 @@ void Controls::handleEvents() } +void Controls::handleLeftClick() +{ + if (draw_menu && menu.getGlobalBounds().contains(window.mapPixelToCoords(sf::Mouse::getPosition()))) + window.close(); + else if (draw_inventory && inventory_rect.getGlobalBounds().contains(window.mapPixelToCoords(sf::Mouse::getPosition()))) + { + // select object + sf::Vector2f mouse_pos = window.mapPixelToCoords(sf::Mouse::getPosition()); + for (auto& [rect, object_name] : inventory) + { + if (rect.contains(mouse_pos)) + { + selected_object = Object::Object(object_name, rect.getPosition() - user.getPosition(), Object::Passability::foreground); + break; + } + } + } + else + { + // handle object selection + for (const auto& iter : object_map.getObjectMap(Object::Passability::foreground)) + { + if (iter.second.getSprite().getGlobalBounds().contains(window.mapPixelToCoords(sf::Mouse::getPosition()))) + { + sf::Packet data; + data << Multiplayer::DataType::Event; + data << Multiplayer::EventType::takeObjectToInventory; + sf::Vector2f object_position(iter.second.getPosition().x / Constants::getPIXEL_SIZE(), iter.second.getPosition().y / Constants::getPIXEL_SIZE()); + auto object_data = Multiplayer::ObjectData(object_position, Time::getTimeNow(), SocketInfo(0, 0) /* ??? */, iter.second.getName(), iter.second.getPassability()); + data << object_data; + data << user; + udp_manager.send(data); + break; + } + } + } +} + + +void Controls::handleMouseDirection() +{ + const auto& mouse_pos = window.mapPixelToCoords(sf::Mouse::getPosition()); + direction = mouse_pos - user.getPosition() - user.getSprite().getGlobalBounds().getSize() / 2.f; +} + + void Controls::addEvent(const sf::Event& event) { switch (event.type) @@ -64,6 +111,12 @@ void Controls::addEvent(const sf::Event& event) draw_inventory = !draw_inventory; selected_object = Object::Object(); break; + case (sf::Keyboard::F): + handleLeftClick(); + break; + case (sf::Keyboard::LShift): + mouse_direction_control = 1; + break; default: break; } @@ -83,73 +136,42 @@ void Controls::addEvent(const sf::Event& event) case (sf::Keyboard::S): down = 0; break; + case (sf::Keyboard::LShift): + mouse_direction_control = 0; + break; default: break; } break; + case sf::Event::MouseButtonPressed: + switch (event.mouseButton.button) + { + case sf::Mouse::Left: + handleLeftClick(); + break; + case sf::Mouse::Right: + mouse_direction_control = 1; + break; + default: + break; + } + break; case sf::Event::MouseButtonReleased: switch (event.mouseButton.button) { - case sf::Mouse::Left: - if (draw_menu && menu.getGlobalBounds().contains(window.mapPixelToCoords(sf::Mouse::getPosition()))) - window.close(); - else if (draw_inventory && inventory_rect.getGlobalBounds().contains(window.mapPixelToCoords(sf::Mouse::getPosition()))) - { - // select object - sf::Vector2f mouse_pos = window.mapPixelToCoords(sf::Mouse::getPosition()); - for (auto& [rect, object_name] : inventory) - { - if (rect.contains(mouse_pos)) - { - selected_object = Object::Object(object_name, rect.getPosition() - user.getPosition(), Object::Passability::foreground); - break; - } - } - } - else - { - // handle object selection - for (const auto& iter : object_map.getObjectMap(Object::Passability::foreground)) - { - if (iter.second.getSprite().getGlobalBounds().contains(window.mapPixelToCoords(sf::Mouse::getPosition()))) - { - sf::Packet data; - data << Multiplayer::DataType::Event; - data << Multiplayer::EventType::takeObjectToInventory; - sf::Vector2f object_position(iter.second.getPosition().x / Constants::getPIXEL_SIZE(), iter.second.getPosition().y / Constants::getPIXEL_SIZE()); - auto object_data = Multiplayer::ObjectData(object_position, Time::getTimeNow(), SocketInfo(0, 0) /* ??? */, iter.second.getName(), iter.second.getPassability()); - data << object_data; - data << user; - udp_manager.send(data); - break; - } - } - } - break; + case sf::Mouse::Right: + mouse_direction_control = 0; + break; + default: + break; } break; + default: + break; } } -sf::Vector2f Controls::getDirection() -{ - return linalg::normalize(sf::Vector2f((right ? 1.f : 0.f) - (left ? 1.f : 0.f), (down ? 1.f : 0.f) - (up ? 1.f : 0.f))); -} - - -void Controls::setLastActionTimepoint(const sf::Uint32& t) -{ - last_action_timepoint = t; -} - - -sf::Uint32 Controls::getDeltaTime() -{ - return Time::getTimeNow() - last_action_timepoint; -} - - void Controls::drawInterfaces() { if (draw_inventory) @@ -169,7 +191,7 @@ void Controls::drawInterfaces() sf::Vector2f shift(5, 5); shift *= static_cast(Constants::getPIXEL_SIZE()); shift.y += text.getGlobalBounds().getSize().y; - for (auto iter : user.getInventory()) + for (const auto& iter : user.getInventory()) { if (!Object::Object::NameToTextureMap.count(iter.first)) { @@ -177,7 +199,7 @@ void Controls::drawInterfaces() new_texture.loadFromFile(Object::Object::NameToTextureAddressMap.at(iter.first)); Object::Object::NameToTextureMap[iter.first] = std::move(new_texture); } - auto sprite = sf::Sprite(Object::Object::NameToTextureMap.at(iter.first)); + auto sprite = sf::Sprite(Object::Object::NameToTextureMap[iter.first]); sprite.setScale(Constants::getPIXEL_SIZE(), Constants::getPIXEL_SIZE()); sprite.setPosition(inventory_rect.getGlobalBounds().getPosition() + shift); inventory[sprite.getGlobalBounds()] = iter.first; @@ -219,6 +241,13 @@ void Controls::drawInterfaces() } +sf::Vector2f Controls::getDirection() +{ + handleMouseDirection(); + return linalg::normalize(!mouse_direction_control ? sf::Vector2f((right ? 1.f : 0.f) - (left ? 1.f : 0.f), (down ? 1.f : 0.f) - (up ? 1.f : 0.f)) : direction); +} + + void Controls::handleFrameStep() { // needs another thread @@ -263,11 +292,11 @@ void Controls::handleFrameStep() data << Multiplayer::DataType::Player << Controls::user; udp_manager.send(data); handleEvents(); - auto direction = Controls::getDirection(); + auto norm_direction = Controls::getDirection(); auto dt = Controls::getDeltaTime(); - Controls::user.move_dt(direction, dt, Controls::object_map); + Controls::user.move_dt(norm_direction, dt, Controls::object_map); Controls::setLastActionTimepoint(); - // Clear screen + // Clear screen window.clear(); // Draw the sprite //window.draw(WorldMap::WorldMap::map); @@ -326,6 +355,25 @@ void Controls::handleFrameStep() window.draw(iter->second); ++iter; } + { + // draw border around object that curson is on + auto& mouse_pos = window.mapPixelToCoords(sf::Mouse::getPosition()); + for (const auto& iter : object_map.getObjectMap(Object::Passability::foreground)) + { + if (iter.second.getSprite().getGlobalBounds().contains(mouse_pos)) + { + auto rect = sf::RectangleShape(iter.second.getSprite().getGlobalBounds().getSize() + sf::Vector2f(2, 2) * static_cast(Constants::getPIXEL_SIZE())); + rect.setFillColor(sf::Color(0, 0, 0, 0)); + auto color = sf::Color::Green; + color.a /= 2; + rect.setOutlineColor(color); + rect.setOutlineThickness(static_cast(Constants::getPIXEL_SIZE()) / 2.f); + rect.setPosition(iter.second.getSprite().getGlobalBounds().getPosition() - sf::Vector2f(1, 1) * static_cast(Constants::getPIXEL_SIZE())); + window.draw(rect); + break; + } + } + } { const auto& bm = object_map.getObjectMap(Object::Passability::background); const auto& im = object_map.getObjectMap(Object::Passability::impassible); diff --git a/src/common/Multiplayer/Multiplayer.cpp b/src/common/Multiplayer/Multiplayer.cpp index 8313129..bf3ca49 100644 --- a/src/common/Multiplayer/Multiplayer.cpp +++ b/src/common/Multiplayer/Multiplayer.cpp @@ -115,7 +115,7 @@ namespace Multiplayer for (const auto& iter : player_data_pool[id].getInventory()) { size_t msg_number; - if (player_data.getInventory().count(iter.first) && player_data.getInventory().at(iter.first) >= iter.second) + if (player_data.getInventory().count(iter.first) && player_data.getInventory()[iter.first] >= iter.second) { // now it does nothing, // but it has to send @@ -170,6 +170,7 @@ namespace Multiplayer } switch (event_type) { + #ifndef CLIENT // SERVER case EventType::takeObjectToInventory: { // data >> object_data >> user @@ -207,6 +208,9 @@ namespace Multiplayer } break; } + #endif + + #ifdef CLIENT // CLIENT case EventType::ejectObjectFromInventory: // break; @@ -227,8 +231,9 @@ namespace Multiplayer removeObject(object_data); break; } + #endif + default: - throw; // ??? break; } break; @@ -399,7 +404,7 @@ namespace Multiplayer for (auto x = -Constants::getVIEW_RADIUS(); x < Constants::getVIEW_RADIUS(); ++x) { addObjectByNoise(point + sf::Vector2f(x * 16., y * 16.)); - auto& vec = object_data_pool.at(point + sf::Vector2f(x * 16., y * 16.)); + auto& vec = object_data_pool[point + sf::Vector2f(x * 16., y * 16.)]; for (auto object_data : vec) { data << object_data; } diff --git a/textures/actors/Ted_16x32/back.png b/textures/actors/Ted_16x32/back.png new file mode 100644 index 0000000..93990b2 Binary files /dev/null and b/textures/actors/Ted_16x32/back.png differ diff --git a/textures/actors/Ted_16x32/front.png b/textures/actors/Ted_16x32/front.png new file mode 100644 index 0000000..eb25125 Binary files /dev/null and b/textures/actors/Ted_16x32/front.png differ diff --git a/textures/actors/Ted_16x32/left.png b/textures/actors/Ted_16x32/left.png new file mode 100644 index 0000000..6d1e2ed Binary files /dev/null and b/textures/actors/Ted_16x32/left.png differ diff --git a/textures/actors/Ted_16x32/right.png b/textures/actors/Ted_16x32/right.png new file mode 100644 index 0000000..8746665 Binary files /dev/null and b/textures/actors/Ted_16x32/right.png differ