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 <algorithm>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include <Thor/Vectors.hpp>
|
||||||
|
|
||||||
#include "../sprite/Body.h"
|
#include "../sprite/Body.h"
|
||||||
|
#include "../util/Log.h"
|
||||||
|
|
||||||
const String Character::KEY_HEALTH = "health";
|
const String Character::KEY_HEALTH = "health";
|
||||||
const String Character::KEY_SPEED = "speed";
|
const String Character::KEY_SPEED = "speed";
|
||||||
|
const float Character::POINT_REACHED_DISTANCE = 1.0f;
|
||||||
std::vector<Character*> Character::mCharacterInstances = std::vector<Character*>();
|
std::vector<Character*> Character::mCharacterInstances = std::vector<Character*>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,7 +30,8 @@ Character::Character(const Instances& instances, const String& texturePath,
|
||||||
mCurrentHealth(mMaxHealth),
|
mCurrentHealth(mMaxHealth),
|
||||||
mMovementSpeed(config.get<float>(KEY_SPEED)),
|
mMovementSpeed(config.get<float>(KEY_SPEED)),
|
||||||
mWeapon(instances, *this, Yaml("weapon.yaml")),
|
mWeapon(instances, *this, Yaml("weapon.yaml")),
|
||||||
mInstances(instances) {
|
mInstances(instances),
|
||||||
|
mStartPathfinding(false) {
|
||||||
mCharacterInstances.push_back(this);
|
mCharacterInstances.push_back(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,3 +107,46 @@ void
|
||||||
Character::fire() {
|
Character::fire() {
|
||||||
mWeapon.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();
|
virtual void onDeath();
|
||||||
float getMovementSpeed() const;
|
float getMovementSpeed() const;
|
||||||
void fire();
|
void fire();
|
||||||
|
bool setDestination(const Vector2f& destination);
|
||||||
|
void move();
|
||||||
|
|
||||||
// Private variables.
|
// Private variables.
|
||||||
private:
|
private:
|
||||||
static const String KEY_HEALTH;
|
static const String KEY_HEALTH;
|
||||||
static const String KEY_SPEED;
|
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;
|
static std::vector<Character*> mCharacterInstances;
|
||||||
|
|
||||||
|
@ -54,6 +58,8 @@ private:
|
||||||
const float mMovementSpeed;
|
const float mMovementSpeed;
|
||||||
Weapon mWeapon;
|
Weapon mWeapon;
|
||||||
Instances mInstances;
|
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_ */
|
#endif /* DG_ACTOR_H_ */
|
||||||
|
|
|
@ -13,16 +13,13 @@
|
||||||
#include "../items/Weapon.h"
|
#include "../items/Weapon.h"
|
||||||
#include "../util/String.h"
|
#include "../util/String.h"
|
||||||
|
|
||||||
const float Player::POINT_REACHED_DISTANCE = 1.0f;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes Sprite.
|
* Initializes Sprite.
|
||||||
*/
|
*/
|
||||||
Player::Player(const Instances& instances, const Vector2f& position, const Yaml& config) :
|
Player::Player(const Instances& instances, const Vector2f& position, const Yaml& config) :
|
||||||
Character(instances, "player.png", PhysicalData(position, instances.world,
|
Character(instances, "player.png", PhysicalData(position, instances.world,
|
||||||
CATEGORY_ACTOR, MASK_ALL, true, false, true), config),
|
CATEGORY_ACTOR, MASK_ALL, true, false, true), config),
|
||||||
mDirection(0),
|
mDirection(0) {
|
||||||
mPathfinder(instances.pathfinder) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,15 +48,7 @@ Player::fire() {
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
Player::move(const Vector2f& destination) {
|
Player::move(const Vector2f& destination) {
|
||||||
mPath = mPathfinder.getPath(*this, destination);
|
setDestination(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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -98,20 +87,9 @@ Player::setDirection(Direction direction, bool unset) {
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
Player::onThink(float elapsedTime) {
|
Player::onThink(float elapsedTime) {
|
||||||
// Stop if we are close enough to destination.
|
if (!mDirection) {
|
||||||
if (!mPath.empty()) {
|
// Only use path finding movement if no direct input movement active.
|
||||||
// Reached a point.
|
Character::move();
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Look towards crosshair.
|
// Look towards crosshair.
|
||||||
setAngle(angle(mCrosshairPosition));
|
setAngle(angle(mCrosshairPosition));
|
||||||
|
@ -123,6 +101,6 @@ Player::onThink(float elapsedTime) {
|
||||||
void
|
void
|
||||||
Player::onCollide(Physical& other, uint16 category) {
|
Player::onCollide(Physical& other, uint16 category) {
|
||||||
if (category != CATEGORY_PARTICLE) {
|
if (category != CATEGORY_PARTICLE) {
|
||||||
mPath.clear();
|
setDestination(getPosition());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,13 +56,8 @@ private:
|
||||||
|
|
||||||
// Private variables.
|
// Private variables.
|
||||||
private:
|
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).
|
Vector2f mCrosshairPosition; //< Relative position of the point to fire at (mouse cursor).
|
||||||
uint8 mDirection; //< Current movement direction for direct control.
|
uint8 mDirection; //< Current movement direction for direct control.
|
||||||
Pathfinder& mPathfinder;
|
|
||||||
std::vector<Vector2f> mPath;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* DG_PLAYER_H_ */
|
#endif /* DG_PLAYER_H_ */
|
||||||
|
|
Reference in a new issue