You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
80 lines
2.9 KiB
80 lines
2.9 KiB
|
3 weeks ago
|
import { _decorator, Component, isValid, Node, Vec3 } from 'cc';
|
||
|
|
import type { Cell, EntityId } from 'db://assets/mx/module/battle';
|
||
|
|
import { INVALID_ENTITY_ID, MovementComp } from 'db://assets/mx/module/battle';
|
||
|
|
import { syncMovementNode } from 'db://assets/script/battle/bridge/CocosBattleMovementBridge';
|
||
|
|
import type { CocosMapView } from 'db://assets/script/battle/map/legacy/MapManager';
|
||
|
|
import type { MapGrid } from 'db://assets/script/battle/map/legacy/MapGrid';
|
||
|
|
const { ccclass } = _decorator;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Cocos 格子路径表现层:只同步 MX MovementComp 到 Node,不做寻路/位移计算。
|
||
|
|
* 逻辑:MovementComp + Pathfinder + MovementSystem.tick
|
||
|
|
*/
|
||
|
|
@ccclass('CocosGridPathMover')
|
||
|
|
export class CocosGridPathMover extends Component {
|
||
|
|
private _entityId: EntityId = INVALID_ENTITY_ID;
|
||
|
|
private _onComplete: (() => void) | null = null;
|
||
|
|
private _completed = false;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 为当前节点绑定格路径导航实体
|
||
|
|
* @param target 目标格或 MapGrid
|
||
|
|
* @param speed 逻辑像素/秒
|
||
|
|
* @param onComplete 到达终点回调
|
||
|
|
*/
|
||
|
|
beginPath(target: Cell | MapGrid, speed: number, onComplete?: () => void): void {
|
||
|
|
const battle = gg.game.CurentBattle;
|
||
|
|
const map = battle?.Map as CocosMapView | undefined;
|
||
|
|
const session = battle?.session;
|
||
|
|
if (!map || !session || !isValid(map)) return;
|
||
|
|
|
||
|
|
const targetCell: Cell = 'Row' in target
|
||
|
|
? { row: target.Row, col: target.Col }
|
||
|
|
: target;
|
||
|
|
|
||
|
|
const startGrid = map.getMapGridByWorldPos(this.node.worldPosition);
|
||
|
|
if (!startGrid?.isCanWalk) {
|
||
|
|
console.log('[CocosGridPathMover] start grid invalid');
|
||
|
|
onComplete?.();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
this._entityId = session.movement.createPathFollower(
|
||
|
|
{ row: startGrid.Row, col: startGrid.Col },
|
||
|
|
targetCell,
|
||
|
|
speed,
|
||
|
|
);
|
||
|
|
this._onComplete = onComplete ?? null;
|
||
|
|
this._completed = false;
|
||
|
|
}
|
||
|
|
|
||
|
|
protected update(): void {
|
||
|
|
if (this._entityId === INVALID_ENTITY_ID || this._completed) return;
|
||
|
|
|
||
|
|
const battle = gg.game.CurentBattle;
|
||
|
|
const session = battle?.session;
|
||
|
|
const map = battle?.Map as CocosMapView | undefined;
|
||
|
|
if (!session || !map?.gridsInitialized) return;
|
||
|
|
|
||
|
|
const move = session.world.getComponent(this._entityId, MovementComp);
|
||
|
|
if (!move) return;
|
||
|
|
|
||
|
|
syncMovementNode(session, map, this._entityId, this.node);
|
||
|
|
|
||
|
|
if (move.reachedGoal) {
|
||
|
|
this._completed = true;
|
||
|
|
this._onComplete?.();
|
||
|
|
session.world.destroy(this._entityId);
|
||
|
|
this._entityId = INVALID_ENTITY_ID;
|
||
|
|
this.destroy();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
protected onDestroy(): void {
|
||
|
|
if (this._entityId !== INVALID_ENTITY_ID) {
|
||
|
|
gg.game.CurentBattle?.session?.world.destroy(this._entityId);
|
||
|
|
this._entityId = INVALID_ENTITY_ID;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|