import { EventTouch, tween, UITransform, v3, Vec2, Vec3 } from 'cc'; import { _decorator, Component, Node, SystemEventType } from 'cc'; import { GeometryUtils } from '../core/utils/GeometryUtils'; import { Utils } from '../core/utils/Utils'; const { ccclass, property } = _decorator; /** * @description 地图移动控制器 * @author Soonsky */ @ccclass('MapMove') export class MapMove extends Component { @property({ type: UITransform, tooltip: "画布,用与判断地图移动边界" }) canvas: UITransform; @property({ type: Node, tooltip: "地图容器" }) map: Node; private startPoint: Vec3; private transform: UITransform; start() { this.transform = this.map.getComponent("cc.UITransform") as UITransform; this.node.on(SystemEventType.TOUCH_START, this.onMapTouchBegin, this); } onDestroy() { this.node.off(SystemEventType.TOUCH_START, this.onMapTouchBegin, this); } private isDoubleTouch = false; private onMapTouchBegin(e: EventTouch): void { this.startPoint = GeometryUtils.V2ToV3(e.getUILocation()); this.node.on(SystemEventType.TOUCH_MOVE, this.onTouchMove, this); this.node.on(SystemEventType.TOUCH_END, this.onTouchEnd, this); this.node.on(SystemEventType.TOUCH_CANCEL, this.onTouchEnd, this); } private onTouchMove(e: EventTouch): void { let touches = e.getAllTouches(); if (touches.length == 1) { if (this.isDoubleTouch) { return; } let point = GeometryUtils.V2ToV3(e.getUILocation()); let offsetX = point.x - this.startPoint.x; let offsetY = point.y - this.startPoint.y; this.move(new Vec3(offsetX, offsetY, 0)); this.startPoint = point; } else if (touches.length == 2) { this.isDoubleTouch = true; let b_distance = Vec2.distance(touches[0].getStartLocation(), touches[1].getStartLocation()); let e_distance = Vec2.distance(touches[0].getLocation(), touches[1].getLocation()); let target = this.map.scale.x; if (b_distance > e_distance) { target = GeometryUtils.clamp(target - 0.01, 1.3, 1.7); } else { target = GeometryUtils.clamp(target + 0.01, 1.3, 1.7); } this.map.scale = v3(target, target, 1); // this.move(this.node.position); } } private onTouchEnd(e: EventTouch): void { this.startPoint = Vec3.ZERO; this.node.off(SystemEventType.TOUCH_MOVE, this.onTouchMove, this); this.node.off(SystemEventType.TOUCH_END, this.onTouchEnd, this); this.node.off(SystemEventType.TOUCH_CANCEL, this.onTouchEnd, this); if (e.getAllTouches().length == 0) { this.isDoubleTouch = false; } } update() { let target = this.map.scale.x; if (target < 1.5) { target += 0.001; } else { target -= 0.001; } this.map.scale = v3(target, target, 1); } private move(offset: Vec3): void { this.startPoint = Vec3.ZERO; this.node.setPosition(this.confirmPosition(new Vec3(this.node.position.x + offset.x, this.node.position.y + offset.y, 0))); } /**确认移动到的坐标是否合法 */ private confirmPosition(pos: Vec3): Vec3 { let clampX = GeometryUtils.clamp(pos.x, -(this.transform.width * (this.map.scale.x - 0.2) / 2 - this.canvas.width / 2), this.transform.width * (this.map.scale.x - 0.2) / 2 - this.canvas.width / 2); let clampY = GeometryUtils.clamp(pos.y, -(this.transform.height * (this.map.scale.y - 0.2) / 2 - this.canvas.height / 2), this.transform.height * (this.map.scale.y - 0.2) / 2 - this.canvas.height / 2); return new Vec3(clampX, clampY, 0); } /**将视角中心移动到指定位置 */ public moveTo(pos: Vec3): void { let toPoint = new Vec3(-pos.x * this.map.scale.x, -pos.y * this.map.scale.y, 0); tween(this.node).to(0.5, { position: this.confirmPosition(toPoint) }, { easing: "sineOut" }).start(); } }