import { _decorator, Component, EventTouch, Input, Node, Vec2, Vec3 } from 'cc'; import { MapGrid } from './MapGrid'; import { MapObstacle } from './MapObstacle'; const { ccclass } = _decorator; @ccclass('ObstacleBrushController') export class ObstacleBrushController extends Component { private _isDragging = false; private _hasMoved = false; private _startUiPos: Vec2 = new Vec2(); private _lastGrid: MapGrid = null; private _visited: Set = new Set(); private _tmpTouchWorld: Vec3 = new Vec3(); private _lastMoveTs = 0; onEnable(): void { this.node.on(Input.EventType.TOUCH_START, this.onTouchStart, this); this.node.on(Input.EventType.TOUCH_MOVE, this.onTouchMove, this); this.node.on(Input.EventType.TOUCH_END, this.onTouchEnd, this); this.node.on(Input.EventType.TOUCH_CANCEL, this.onTouchEnd, this); } onDisable(): void { this.node.off(Input.EventType.TOUCH_START, this.onTouchStart, this); this.node.off(Input.EventType.TOUCH_MOVE, this.onTouchMove, this); this.node.off(Input.EventType.TOUCH_END, this.onTouchEnd, this); this.node.off(Input.EventType.TOUCH_CANCEL, this.onTouchEnd, this); this.stopBrush(); } private onTouchStart(event: EventTouch) { if (!gg.game.CurentBattle?.IsEdit) return; this._isDragging = true; this._hasMoved = false; const p = event.getUILocation(); this._startUiPos.set(p.x, p.y); this._lastMoveTs = Date.now(); this._visited.clear(); this._lastGrid = this.getGridFromUiPos(p); MapObstacle.consumeOpenedCoinPanelByEditAction(); } private onTouchMove(event: EventTouch) { if (!this._isDragging || !gg.game.CurentBattle?.IsEdit) return; const now = Date.now(); if (now - this._lastMoveTs < 28) return; this._lastMoveTs = now; const p = event.getUILocation(); const dx = p.x - this._startUiPos.x; const dy = p.y - this._startUiPos.y; if (!this._hasMoved && (dx * dx + dy * dy) < 144) { return; } this._hasMoved = true; const curGrid = this.getGridFromUiPos(p); if (!curGrid) return; if (!this._lastGrid) { this.tryPlaceOnGrid(curGrid); this._lastGrid = curGrid; return; } if (curGrid.Index === this._lastGrid.Index) return; this.tryPlaceOnGrid(curGrid); this._lastGrid = curGrid; } private onTouchEnd(_event: EventTouch) { this.stopBrush(); } private stopBrush() { this._isDragging = false; this._hasMoved = false; this._visited.clear(); this._lastGrid = null; MapObstacle.consumeOpenedCoinPanelByEditAction(); } private getGridFromUiPos(p: Vec2): MapGrid | null { const map = gg.game.CurentBattle?.Map; if (!map) return null; this._tmpTouchWorld.set(p.x, p.y, 0); return map.getMapGridByWorldPos(this._tmpTouchWorld); } private tryPlaceOnGrid(grid: MapGrid) { if (!grid || this._visited.has(grid.Index)) return; this._visited.add(grid.Index); // 按需求:滑动时只在“可放置格子”尝试放置,不做移除 if (!grid.isCanPutObstacle || !grid.isCanWalk) return; grid.node.getComponent(MapObstacle)?.tryEditAction(false); if (MapObstacle.consumeOpenedCoinPanelByEditAction()) { this.stopBrush(); } } }