Complete Cocos Creator port with level bundles, themes, and tooling.
Adds level prefabs, theme assets, audio, extensions, and deployment scripts for the Unity WebGL migration. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
136
assets/scripts/controller/ViewController.ts
Normal file
136
assets/scripts/controller/ViewController.ts
Normal file
@@ -0,0 +1,136 @@
|
||||
import {
|
||||
_decorator, Camera, Component, EventMouse, EventTouch, Input, input, Vec2, view,
|
||||
} from 'cc';
|
||||
import { CAMERA_ORTHO_HALF, DESIGN_WIDTH } from '../core/GridConstants';
|
||||
import { getEmbeddedOrthoHalf } from '../core/EmbeddedView';
|
||||
|
||||
const { ccclass } = _decorator;
|
||||
|
||||
/** 对齐 Unity ViewController:Orthographic 缩放与拖拽 */
|
||||
@ccclass('ViewController')
|
||||
export class ViewController extends Component {
|
||||
static instance: ViewController | null = null;
|
||||
|
||||
/** Unity zoomSpeed=2 → 世界半高步进 200 */
|
||||
zoomSpeed = 200;
|
||||
/** Unity minZoom=3, maxZoom=10(×100 世界单位) */
|
||||
minOrtho = 300;
|
||||
maxOrtho = 1000;
|
||||
|
||||
private camera: Camera | null = null;
|
||||
private dragOrigin = new Vec2();
|
||||
private dragging = false;
|
||||
|
||||
onLoad() {
|
||||
if (ViewController.instance && ViewController.instance !== this) {
|
||||
this.destroy();
|
||||
return;
|
||||
}
|
||||
ViewController.instance = this;
|
||||
this.camera = this.getComponent(Camera);
|
||||
if (this.camera && this.camera.orthoHeight <= 0) {
|
||||
this.camera.orthoHeight = CAMERA_ORTHO_HALF;
|
||||
}
|
||||
input.on(Input.EventType.TOUCH_START, this.onTouchStart, this);
|
||||
input.on(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
|
||||
input.on(Input.EventType.TOUCH_END, this.onTouchEnd, this);
|
||||
input.on(Input.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
|
||||
input.on(Input.EventType.MOUSE_DOWN, this.onMouseDown, this);
|
||||
input.on(Input.EventType.MOUSE_MOVE, this.onMouseMove, this);
|
||||
input.on(Input.EventType.MOUSE_UP, this.onMouseUp, this);
|
||||
}
|
||||
|
||||
onDestroy() {
|
||||
if (ViewController.instance === this) ViewController.instance = null;
|
||||
input.off(Input.EventType.TOUCH_START, this.onTouchStart, this);
|
||||
input.off(Input.EventType.TOUCH_MOVE, this.onTouchMove, this);
|
||||
input.off(Input.EventType.TOUCH_END, this.onTouchEnd, this);
|
||||
input.off(Input.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
|
||||
input.off(Input.EventType.MOUSE_DOWN, this.onMouseDown, this);
|
||||
input.off(Input.EventType.MOUSE_MOVE, this.onMouseMove, this);
|
||||
input.off(Input.EventType.MOUSE_UP, this.onMouseUp, this);
|
||||
}
|
||||
|
||||
zoomIn() {
|
||||
const cam = this.camera;
|
||||
if (!cam || cam.orthoHeight <= this.minOrtho) return;
|
||||
cam.orthoHeight = Math.max(this.minOrtho, cam.orthoHeight - this.zoomSpeed);
|
||||
}
|
||||
|
||||
zoomOut() {
|
||||
const cam = this.camera;
|
||||
if (!cam || cam.orthoHeight >= this.maxOrtho) return;
|
||||
cam.orthoHeight = Math.min(this.maxOrtho, cam.orthoHeight + this.zoomSpeed);
|
||||
}
|
||||
|
||||
resetZoom() {
|
||||
const cam = this.camera;
|
||||
if (!cam) return;
|
||||
cam.orthoHeight = getEmbeddedOrthoHalf();
|
||||
cam.node.setPosition(0, 0, cam.node.position.z);
|
||||
}
|
||||
|
||||
private onTouchStart(e: EventTouch) {
|
||||
if (this.isPointerOnUI(e.getLocation())) return;
|
||||
this.dragging = true;
|
||||
e.getLocation(this.dragOrigin);
|
||||
}
|
||||
|
||||
private onTouchEnd() {
|
||||
this.dragging = false;
|
||||
}
|
||||
|
||||
private onTouchMove(e: EventTouch) {
|
||||
if (!this.dragging) return;
|
||||
const cur = new Vec2();
|
||||
e.getLocation(cur);
|
||||
this.applyDrag(cur);
|
||||
e.getLocation(this.dragOrigin);
|
||||
}
|
||||
|
||||
private onMouseDown(e: EventMouse) {
|
||||
if (this.isPointerOnUI(new Vec2(e.getLocationX(), e.getLocationY()))) return;
|
||||
this.dragging = true;
|
||||
this.dragOrigin.set(e.getLocationX(), e.getLocationY());
|
||||
}
|
||||
|
||||
private onMouseUp() {
|
||||
this.dragging = false;
|
||||
}
|
||||
|
||||
private onMouseMove(e: EventMouse) {
|
||||
if (!this.dragging) return;
|
||||
this.applyDrag(new Vec2(e.getLocationX(), e.getLocationY()));
|
||||
this.dragOrigin.set(e.getLocationX(), e.getLocationY());
|
||||
}
|
||||
|
||||
private applyDrag(cur: Vec2) {
|
||||
if (!this.camera) return;
|
||||
const delta = cur.subtract(this.dragOrigin);
|
||||
|
||||
const ortho = this.camera.orthoHeight;
|
||||
const { width, height } = view.getVisibleSize();
|
||||
const worldPerPixelX = (2 * ortho * (width / height)) / width;
|
||||
const worldPerPixelY = (2 * ortho) / height;
|
||||
|
||||
const pos = this.camera.node.position;
|
||||
let nx = pos.x - delta.x * worldPerPixelX;
|
||||
let ny = pos.y - delta.y * worldPerPixelY;
|
||||
|
||||
const limit = ortho - 20;
|
||||
if (Math.abs(nx) > limit) nx = pos.x;
|
||||
if (Math.abs(ny) > limit) ny = pos.y;
|
||||
|
||||
this.camera.node.setPosition(nx, ny, pos.z);
|
||||
}
|
||||
|
||||
/** 右侧 UIMain 区域不拖拽镜头(与 UIMain 边距一致) */
|
||||
private isPointerOnUI(loc: Vec2): boolean {
|
||||
const vis = view.getVisibleSize();
|
||||
const margin = Math.max(96, (DESIGN_WIDTH * 0.5) * 0.14);
|
||||
const right = vis.width > DESIGN_WIDTH
|
||||
? DESIGN_WIDTH * 0.5
|
||||
: vis.width * 0.5;
|
||||
return loc.x >= right - margin;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user