diff --git a/source/abstract/Character.cpp b/source/abstract/Character.cpp index 4c3d071..c92102b 100644 --- a/source/abstract/Character.cpp +++ b/source/abstract/Character.cpp @@ -10,10 +10,14 @@ #include #include +#include + #include "../sprite/Body.h" +#include "../util/Log.h" const String Character::KEY_HEALTH = "health"; const String Character::KEY_SPEED = "speed"; +const float Character::POINT_REACHED_DISTANCE = 1.0f; std::vector Character::mCharacterInstances = std::vector(); /** @@ -26,7 +30,8 @@ Character::Character(const Instances& instances, const String& texturePath, mCurrentHealth(mMaxHealth), mMovementSpeed(config.get(KEY_SPEED)), mWeapon(instances, *this, Yaml("weapon.yaml")), - mInstances(instances) { + mInstances(instances), + mStartPathfinding(false) { mCharacterInstances.push_back(this); } @@ -102,3 +107,46 @@ void Character::fire() { mWeapon.fire(); } + +/** + * Set a destination to be walked to. Call move() for the actual movement. + * + * @param destination An absolute point to move towards. + * @return True if a path was found. + */ +bool +Character::setDestination(const Vector2f& destination) { + mPath = mInstances.pathfinder.getPath(*this, destination); + // Make sure we found a path. + if (mPath.empty()) { + LOG_I("No path found to destination."); + } else { + mStartPathfinding = true; + } + return mStartPathfinding; +} + +/** + * Move towards a destination. Call setDestination() for setting the destination. + * This should be called from think(). + */ +void +Character::move() { + if (!mPath.empty()) { + if (mStartPathfinding) { + setSpeed(*mPath.end() - getPosition(), mMovementSpeed); + } + if (thor::length(*mPath.end() - getPosition()) < POINT_REACHED_DISTANCE) { + // Reached a path node. + mPath.pop_back(); + if (!mPath.empty()) { + // Move to next path node. + setSpeed(*mPath.end() - getPosition(), mMovementSpeed); + } + else { + LOG_I("Reached destination."); + setSpeed(Vector2f(), 0); + } + } + } +} diff --git a/source/abstract/Character.h b/source/abstract/Character.h index 95c2669..c7e1ee1 100644 --- a/source/abstract/Character.h +++ b/source/abstract/Character.h @@ -41,11 +41,15 @@ protected: virtual void onDeath(); float getMovementSpeed() const; void fire(); + bool setDestination(const Vector2f& destination); + void move(); // Private variables. private: static const String KEY_HEALTH; static const String KEY_SPEED; + /// The distance to a point where it is considered reached. + static const float POINT_REACHED_DISTANCE; static std::vector mCharacterInstances; @@ -54,6 +58,8 @@ private: const float mMovementSpeed; Weapon mWeapon; Instances mInstances; + std::vector mPath; //< Contains nodes to reach a set destination. + bool mStartPathfinding; //< True if a movement destination was just set. }; #endif /* DG_ACTOR_H_ */ diff --git a/source/sprite/Player.cpp b/source/sprite/Player.cpp index 3070ab9..ea89a35 100644 --- a/source/sprite/Player.cpp +++ b/source/sprite/Player.cpp @@ -11,9 +11,7 @@ #include "../util/Vector.h" #include "../items/Weapon.h" -#include "../util/String.h" - -const float Player::POINT_REACHED_DISTANCE = 1.0f; +#include "../util/String.h" /** * Initializes Sprite. @@ -21,8 +19,7 @@ const float Player::POINT_REACHED_DISTANCE = 1.0f; Player::Player(const Instances& instances, const Vector2f& position, const Yaml& config) : Character(instances, "player.png", PhysicalData(position, instances.world, CATEGORY_ACTOR, MASK_ALL, true, false, true), config), - mDirection(0), - mPathfinder(instances.pathfinder) { + mDirection(0) { } /** @@ -51,15 +48,7 @@ Player::fire() { */ void Player::move(const Vector2f& destination) { - mPath = mPathfinder.getPath(*this, destination); - // Make sure we found a path. - if (mPath != std::vector()) { - setSpeed(*mPath.end() - getPosition(), getMovementSpeed()); - } - // Otherwise stop (in case this was called during movement). - else { - setSpeed(Vector2f(), 0); - } + setDestination(destination); } /** @@ -98,20 +87,9 @@ Player::setDirection(Direction direction, bool unset) { */ void Player::onThink(float elapsedTime) { - // Stop if we are close enough to destination. - if (!mPath.empty()) { - // Reached a point. - if (thor::length(*mPath.end() - getPosition()) < POINT_REACHED_DISTANCE) { - mPath.pop_back(); - if (!mPath.empty()) { - // Move to next. - setSpeed(*mPath.end() - getPosition(), getMovementSpeed()); - } - else { - // Reached destination. - setSpeed(Vector2f(), 0); - } - } + if (!mDirection) { + // Only use path finding movement if no direct input movement active. + Character::move(); } // Look towards crosshair. setAngle(angle(mCrosshairPosition)); @@ -123,6 +101,6 @@ Player::onThink(float elapsedTime) { void Player::onCollide(Physical& other, uint16 category) { if (category != CATEGORY_PARTICLE) { - mPath.clear(); + setDestination(getPosition()); } } diff --git a/source/sprite/Player.h b/source/sprite/Player.h index bdd0efb..03c2960 100644 --- a/source/sprite/Player.h +++ b/source/sprite/Player.h @@ -56,13 +56,8 @@ private: // Private variables. private: - /// The distance to a point where it is considered reached. - static const float POINT_REACHED_DISTANCE; - Vector2f mCrosshairPosition; //< Relative position of the point to fire at (mouse cursor). uint8 mDirection; //< Current movement direction for direct control. - Pathfinder& mPathfinder; - std::vector mPath; }; #endif /* DG_PLAYER_H_ */