Moved path finding logic from Player to Character.

This commit is contained in:
Felix Ableitner 2012-10-13 19:36:33 +02:00
parent f0753b4a3a
commit 2be3f13810
4 changed files with 62 additions and 35 deletions

View file

@ -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);
}
}
}
}

View file

@ -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_ */

View file

@ -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());
}
}

View file

@ -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_ */