Commit 6ee14485 authored by louiz’'s avatar louiz’

Re-add simple collision and speed change

parent 8333f784
#include <world/location.hpp>
#include <world/world.hpp>
#include <logging/logging.hpp>
const ComponentType Location::component_type;
Location::Location(const uint8_t width):
Location::Location(const uint8_t width, const bool blocking):
width(width),
pos{}
pos{},
blocking(blocking)
{
}
......@@ -37,7 +41,37 @@ bool Location::contains(const Position&) const
return false;
}
bool Location::is_obstructing_position(const Position&) const
void Location::set_blocking(const bool blocking)
{
this->blocking = blocking;
}
bool Location::is_blocking() const
{
return this->blocking;
}
bool Location::is_obstructing_position(const Position& pos,
const Fix16& width) const
{
if (!this->blocking)
return false;
auto distance = Position::distance(pos, this->pos);
if (distance < width + this->get_width())
return true;
return false;
}
bool Location::is_position_valid(World* world, const Position& pos) const
{
for (const auto& entity: world->entities)
{
Location* location = entity->get<Location>();
if (!location || location == this)
continue;
if (location->is_obstructing_position(pos, this->width) == true)
return false;
}
return true;
}
......@@ -10,25 +10,34 @@ class Location: public Component
{
public:
static const ComponentType component_type = ComponentType::Location;
Location(const uint8_t width);
Location(const uint8_t width, const bool blocking);
~Location() = default;
void tick(Entity*, World*) override final;
Position& position();
const Position& position() const;
Fix16 get_width() const;
void set_width(const Fix16& width);
void set_blocking(const bool blocking);
bool is_blocking() const;
bool contains(const Position&) const;
/**
* Returns weither or not this entity (if not moving) makes it impossible
* for the given unit to reach this Position. This means that this entity
* is OVER the position, or close enough that the moving entity cannot
* reach it because of its width.
* Returns weither or not this entity makes it impossible for the given
* unit to reach this Position. This means that this entity is OVER the
* position, or close enough that the moving entity cannot reach it
* because of its width.
*/
bool is_obstructing_position(const Position&) const;
bool is_obstructing_position(const Position& pos,
const Fix16& width) const;
bool is_position_valid(World* world, const Position& pos) const;
private:
Fix16 width;
Position pos;
/**
* Whether or not this entity should be considered when looking for
* collisions with other entities
*/
bool blocking;
Location(const Location&) = delete;
Location(Location&&) = delete;
......
......@@ -4,6 +4,8 @@
#include <world/mobility.hpp>
#include <world/location.hpp>
#include <logging/logging.hpp>
const ComponentType Mobility::component_type;
Mobility::Mobility(const Fix16& speed):
......@@ -20,7 +22,12 @@ Fix16 Mobility::get_speed() const
return this->speed;
}
void Mobility::follow_path(Path& path, World*, Location* location)
void Mobility::set_speed(const Fix16& speed)
{
this->speed = speed;
}
void Mobility::follow_path(Path& path, World* world, Location* location)
{
Position goal = path.front();
Vec2 movement(goal - location->position());
......@@ -32,7 +39,27 @@ void Mobility::follow_path(Path& path, World*, Location* location)
return ;
}
this->move_towards(goal, location);
if (Position::distance(goal, location->position()) < this->speed)
movement.set_length(Position::distance(goal, location->position()));
else
movement.set_length(this->speed);
auto after_movement = location->position() + movement;
// check for collision with other blocking entities
auto number_of_rotations = 0;
auto angle = 36;
while (!location->is_position_valid(world, after_movement) && number_of_rotations < 360)
{
movement.rotate(angle);
number_of_rotations += angle;
after_movement = location->position() + movement;
}
if (number_of_rotations == 360)
{
log_debug("blocked");
return;
}
location->position() = after_movement;
}
void Mobility::move_towards(const Position& goal, Location* location)
......
......@@ -19,6 +19,7 @@ public:
~Mobility() = default;
void tick(Entity*, World*) override final;
Fix16 get_speed() const;
void set_speed(const Fix16& speed);
/**
* Given a path, change the location and cut down the path (if we moved
* enough) to follow that path
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment