go
// endnode是终点(目标格子)
while (currentNode) { // 只要还有父节点,就继续回溯
path.unshift({x: currentNode.x, y: currentNode.y}); // 从头部插入
currentNode = currentNode.parent; // 指向父节点(上一个格子)
}
这个过程:
终点 → 父节点 → 父节点的父节点 → ... → 起点
例如路径:起点(0,0) → (1,0) → (2,0) → 终点(3,0)
A*算法链接:终点.parent = (2,0), (2,0).parent = (1,0), (1,0).parent = (0,0)
用 unshift() 插入后得到的 path:
go
JAVASCRIPT
[
{x:0, y:0}, // 起点(因为unshift,最早插入的最后在数组开头)
{x:1, y:0},
{x:2, y:0},
{x:3, y:0} // 终点(第一个插入的)
]
- 路径存储与初始化
go
TYPESCRIPT
this.path = path; // 存储整个路径数组
this.currentPathIndex = 1; // 从索引1开始移动
为什么要从1而不是0开始?
索引0:角色的当前起点位置
索引1:要移动到的第一个格子
索引2:第二个格子
...
最后一个索引:终点
go
例如:path = [(0,0), (1,0), (2,0), (3,0)]
JAVASCRIPT
// currentPathIndex = 1 意味着:
path[0] = (0,0) ← 角色就在这里(跳过)
path[1] = (1,0) ← 这是第一个要移动到的点 ⭐
- 发送路径到网格显示
go
TYPESCRIPT
this.sendPathToGrid(path); // 让gezi组件把路径画出来(显示为9)
- 延迟启动移动
go
TYPESCRIPT
this.scheduleOnce(() => {
this.startMoving(); // 延迟一帧后调用startMoving
}, 0);
为什么要延迟?
确保路径数据已经完全处理
给gezi组件时间绘制路径
Cocos更新机制需要
后续流程(不在这个代码段中)
- startMoving() 方法
go
TYPESCRIPT
startMoving() {
if (this.path.length <= 1) { // 检查路径是否有效
console.log("没有找到路径或路径太短");
return;
}
console.log(`开始移动,路径共有 ${this.path.length} 个点`);
this.moveToNextPoint(); // 调用移动方法
}
- moveToNextPoint() 方法
TYPESCRIPT
go
moveToNextPoint() {
if (this.currentPathIndex >= this.path.length) {
console.log("到达目的地!");
return;
}
const target = this.path[this.currentPathIndex]; // 获取当前目标点
console.log(`移动到第 ${this.currentPathIndex} 个点:[${target.x}, ${target.y}]`);
// 转换为世界坐标并移动
const worldPos = this.gridComponent.gridToWorldPosition(target.x, target.y);
this.moveNodeTo(worldPos);
}
- moveNodeTo() 方法(执行移动动画)
go
TYPESCRIPT
moveNodeTo(targetPosition: Vec3) {
tween(this.node) // 播放Tween动画
.to(duration, {
worldPosition: targetPosition
})
.call(() => {
// 动画完成后,继续下一个点
this.currentPathIndex++; // ⭐ 关键:增加索引
if (this.currentPathIndex < this.path.length) {
this.moveToNextPoint(); // 递归调用
}
})
.start();
}
完整移动流程图示
TEXT
fujiedian() → 构建路径回溯
↓
存储路径 this.path = [...]
↓
currentPathIndex = 1 // 跳过起点
↓
this.startMoving()
↓
this.moveToNextPoint()
↓
获取目标点 this.path[1] → 坐标转换
↓
this.moveNodeTo(坐标) // 移动动画
↓ ↑
完成回调 |
↓ |
this.currentPathIndex++ (→2)
↓
if (索引 < 路径长度)
↓
再次调用 moveToNextPoint() // 处理第2个点
↓
获取目标点 this.path[2] → 坐标转换
↓
继续移动...