a星学习记录 通过父节点从目的地格子坐标回溯起点

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}   // 终点(第一个插入的)
]
  1. 路径存储与初始化
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)  ← 这是第一个要移动到的点 ⭐
  1. 发送路径到网格显示
go 复制代码
TYPESCRIPT
this.sendPathToGrid(path);  // 让gezi组件把路径画出来(显示为9)
  1. 延迟启动移动
go 复制代码
TYPESCRIPT
this.scheduleOnce(() => {
    this.startMoving();  // 延迟一帧后调用startMoving
}, 0);

为什么要延迟?

确保路径数据已经完全处理

给gezi组件时间绘制路径

Cocos更新机制需要

后续流程(不在这个代码段中)

  1. startMoving() 方法
go 复制代码
TYPESCRIPT
startMoving() {
    if (this.path.length <= 1) {  // 检查路径是否有效
        console.log("没有找到路径或路径太短");
        return;
    }
    
    console.log(`开始移动,路径共有 ${this.path.length} 个点`);
    this.moveToNextPoint();  // 调用移动方法
}
  1. 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);
}
  1. 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] → 坐标转换

继续移动...

相关推荐
西岸行者3 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意3 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码3 天前
嵌入式学习路线
学习
毛小茛3 天前
计算机系统概论——校验码
学习
babe小鑫3 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms3 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下3 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。3 天前
2026.2.25监控学习
学习
im_AMBER3 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J3 天前
从“Hello World“ 开始 C++
c语言·c++·学习