152 lines
4.8 KiB
TypeScript
152 lines
4.8 KiB
TypeScript
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);
|
|
}
|
|
} |