added finding path with A* and json file to know where character can walk

This commit is contained in:
anime committed 2026-04-15 18:36:27 +06:00
1 parent eff7322140
commit 4eaefd25d4
11 files changed
+905 -11

No files matched your search

+57 -4
View File
@@ -22,8 +22,46 @@ void Character::loadAnimation(AnimationState state, const std::string& filename,
void Character::setTarget(const Eigen::Vector3f& target,
std::function<void()> onArrived) {
walkTarget = target;
Eigen::Vector3f normalizedTarget(target.x(), 0.f, target.z());
const bool sameRequestedTarget =
(normalizedTarget - requestedWalkTarget).norm() <= TARGET_REPLAN_THRESHOLD;
const bool alreadyMovingToTarget =
!pathWaypoints.empty() || (walkTarget - normalizedTarget).norm() <= TARGET_REPLAN_THRESHOLD;
const bool stoppedAfterFailedPath =
pathWaypoints.empty() && (walkTarget - position).norm() <= TARGET_REPLAN_THRESHOLD;
if (!onArrived && sameRequestedTarget && (alreadyMovingToTarget || stoppedAfterFailedPath)) {
return;
}
requestedWalkTarget = normalizedTarget;
onArrivedCallback = std::move(onArrived);
if (pathPlanner) {
pathWaypoints = pathPlanner(position, normalizedTarget);
currentWaypointIndex = 0;
if (!pathWaypoints.empty()) {
for (Eigen::Vector3f& waypoint : pathWaypoints) {
waypoint.y() = 0.f;
}
walkTarget = pathWaypoints.back();
return;
}
walkTarget = Eigen::Vector3f(position.x(), 0.f, position.z());
onArrivedCallback = nullptr;
return;
}
pathWaypoints.clear();
currentWaypointIndex = 0;
walkTarget = normalizedTarget;
}
void Character::setPathPlanner(PathPlanner planner) {
pathPlanner = std::move(planner);
}
AnimationState Character::resolveActiveState() const {
@@ -35,7 +73,12 @@ AnimationState Character::resolveActiveState() const {
void Character::update(int64_t deltaMs) {
//std::cout << "update called with deltaMs: " << deltaMs << std::endl;
// Move toward walk target on the XZ plane
Eigen::Vector3f toTarget = walkTarget - position;
Eigen::Vector3f activeTarget = walkTarget;
if (!pathWaypoints.empty() && currentWaypointIndex < pathWaypoints.size()) {
activeTarget = pathWaypoints[currentWaypointIndex];
}
Eigen::Vector3f toTarget = activeTarget - position;
toTarget.y() = 0.f;
float dist = toTarget.norm();
@@ -43,7 +86,7 @@ void Character::update(int64_t deltaMs) {
Eigen::Vector3f dir = toTarget / dist;
float moveAmount = walkSpeed * static_cast<float>(deltaMs) / 1000.f;
if (moveAmount >= dist) {
position = walkTarget;
position = activeTarget;
position.y() = 0.f;
} else {
position += dir * moveAmount;
@@ -60,7 +103,17 @@ void Character::update(int64_t deltaMs) {
{
currentState = AnimationState::STAND;
}
if (onArrivedCallback) {
const bool hasNextWaypoint = !pathWaypoints.empty() && currentWaypointIndex + 1 < pathWaypoints.size();
if (hasNextWaypoint) {
++currentWaypointIndex;
}
else {
pathWaypoints.clear();
currentWaypointIndex = 0;
}
if (!hasNextWaypoint && onArrivedCallback) {
auto cb = std::move(onArrivedCallback);
onArrivedCallback = nullptr;
cb();