feat: 支持自动寻路算法

This commit is contained in:
2025-09-21 21:31:54 +08:00
parent 35cfabb66b
commit d6aa74cb9d
10 changed files with 1003 additions and 90 deletions

View File

@@ -0,0 +1,152 @@
import { _decorator, Component, Node, TiledMap, Vec3, Label, input, Input, EventTouch } from 'cc';
import { TiledMapPathfinder } from './TiledMapPathfinder';
const { ccclass, property } = _decorator;
@ccclass('PathfindingTest')
export class PathfindingTest extends Component {
@property(TiledMap)
tiledMap: TiledMap | null = null;
@property(Node)
startPoint: Node | null = null;
@property(Node)
endPoint: Node | null = null;
@property(Label)
infoLabel: Label | null = null;
private pathfinder: TiledMapPathfinder | null = null;
private currentPath: Vec3[] = [];
onLoad() {
input.on(Input.EventType.TOUCH_START, this.onTouch, this);
}
onDestroy() {
input.off(Input.EventType.TOUCH_START, this.onTouch, this);
}
start() {
this.initializePathfinder();
this.runTests();
}
private initializePathfinder() {
if (!this.tiledMap) {
console.error('TiledMap未设置');
return;
}
this.pathfinder = this.tiledMap.node.getComponent(TiledMapPathfinder);
if (!this.pathfinder) {
this.pathfinder = this.tiledMap.node.addComponent(TiledMapPathfinder);
this.pathfinder.tiledMap = this.tiledMap;
this.pathfinder.walkableLayerName = 'WalkableLayer';
this.pathfinder.tileSize = 32;
}
}
private runTests() {
if (!this.pathfinder) {
console.error('寻路器未初始化');
return;
}
// 等待一帧让寻路器完全初始化
this.scheduleOnce(() => {
this.performPathfindingTest();
}, 0.1);
}
private performPathfindingTest() {
if (!this.pathfinder || !this.startPoint || !this.endPoint) {
console.error('测试组件未完整设置');
return;
}
const startPos = this.startPoint.position;
const endPos = this.endPoint.position;
console.log(`测试寻路: 从 (${startPos.x}, ${startPos.y}) 到 (${endPos.x}, ${endPos.y})`);
// 检查位置是否可行走
const startWalkable = this.pathfinder.isWorldPositionWalkable(startPos);
const endWalkable = this.pathfinder.isWorldPositionWalkable(endPos);
console.log(`起点可行走: ${startWalkable}, 终点可行走: ${endWalkable}`);
// 如果位置不可行走,寻找最近的可行走位置
let adjustedStartPos = startPos;
let adjustedEndPos = endPos;
if (!startWalkable) {
const closestStart = this.pathfinder.getClosestWalkablePosition(startPos);
if (closestStart) {
adjustedStartPos = closestStart;
console.log(`调整起点到: (${adjustedStartPos.x}, ${adjustedStartPos.y})`);
}
}
if (!endWalkable) {
const closestEnd = this.pathfinder.getClosestWalkablePosition(endPos);
if (closestEnd) {
adjustedEndPos = closestEnd;
console.log(`调整终点到: (${adjustedEndPos.x}, ${adjustedEndPos.y})`);
}
}
// 执行寻路
this.currentPath = this.pathfinder.findPath(adjustedStartPos, adjustedEndPos);
if (this.currentPath.length > 0) {
console.log(`找到路径,包含 ${this.currentPath.length} 个点:`);
this.currentPath.forEach((point, index) => {
console.log(` 路径点 ${index}: (${point.x.toFixed(2)}, ${point.y.toFixed(2)})`);
});
this.updateInfoLabel(`路径找到!包含 ${this.currentPath.length} 个点`);
} else {
console.log('未找到路径');
this.updateInfoLabel('未找到路径');
}
}
private onTouch(event: EventTouch) {
// 可以通过触摸来动态测试寻路
if (!this.pathfinder || !this.startPoint) return;
const touchLocation = event.getUILocation();
// 这里可以添加触摸点寻路测试的逻辑
}
private updateInfoLabel(text: string) {
if (this.infoLabel) {
this.infoLabel.string = text;
}
}
// 公共方法供外部调用测试
public testPathfinding(startWorldPos: Vec3, endWorldPos: Vec3): Vec3[] {
if (!this.pathfinder) {
console.error('寻路器未初始化');
return [];
}
return this.pathfinder.findPath(startWorldPos, endWorldPos);
}
// 获取当前找到的路径
public getCurrentPath(): Vec3[] {
return this.currentPath.slice(); // 返回副本
}
// 检查位置是否可行走
public isPositionWalkable(worldPos: Vec3): boolean {
if (!this.pathfinder) {
return false;
}
return this.pathfinder.isWorldPositionWalkable(worldPos);
}
}