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.
102 lines
3.5 KiB
102 lines
3.5 KiB
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<number> = 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();
|
|
}
|
|
}
|
|
}
|
|
|
|
|