Moved path finding logic from Player to Character.
This commit is contained in:
parent
f0753b4a3a
commit
2be3f13810
4 changed files with 62 additions and 35 deletions
|
@ -10,10 +10,14 @@
|
|||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
|
||||
#include <Thor/Vectors.hpp>
|
||||
|
||||
#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*> Character::mCharacterInstances = std::vector<Character*>();
|
||||
|
||||
/**
|
||||
|
@ -26,7 +30,8 @@ Character::Character(const Instances& instances, const String& texturePath,
|
|||
mCurrentHealth(mMaxHealth),
|
||||
mMovementSpeed(config.get<float>(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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Character*> mCharacterInstances;
|
||||
|
||||
|
@ -54,6 +58,8 @@ private:
|
|||
const float mMovementSpeed;
|
||||
Weapon mWeapon;
|
||||
Instances mInstances;
|
||||
std::vector<Vector2f> mPath; //< Contains nodes to reach a set destination.
|
||||
bool mStartPathfinding; //< True if a movement destination was just set.
|
||||
};
|
||||
|
||||
#endif /* DG_ACTOR_H_ */
|
||||
|
|
|
@ -13,16 +13,13 @@
|
|||
#include "../items/Weapon.h"
|
||||
#include "../util/String.h"
|
||||
|
||||
const float Player::POINT_REACHED_DISTANCE = 1.0f;
|
||||
|
||||
/**
|
||||
* Initializes Sprite.
|
||||
*/
|
||||
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<Vector2f>()) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Vector2f> mPath;
|
||||
};
|
||||
|
||||
#endif /* DG_PLAYER_H_ */
|
||||
|
|
Reference in a new issue