Adds level prefabs, theme assets, audio, extensions, and deployment scripts for the Unity WebGL migration. Co-authored-by: Cursor <cursoragent@cursor.com>
152 lines
5.5 KiB
TypeScript
152 lines
5.5 KiB
TypeScript
import {
|
||
_decorator, Component, Node, Label, EditBox, Button, UITransform, Color, Widget, Graphics, Layers,
|
||
} from 'cc';
|
||
import { EDITOR, PREVIEW } from 'cc/env';
|
||
import { GameManager } from '../manager/GameManager';
|
||
|
||
const { ccclass } = _decorator;
|
||
|
||
const HUD_LAYER = Layers.Enum.UI_3D;
|
||
|
||
/** 预览模式下调试条(对齐 Unity Editor/TestPlayer) */
|
||
@ccclass('GameplayDebugBar')
|
||
export class GameplayDebugBar extends Component {
|
||
private stepBox: EditBox | null = null;
|
||
|
||
static shouldShow(): boolean {
|
||
return EDITOR && PREVIEW;
|
||
}
|
||
|
||
static ensure(parent: Node): GameplayDebugBar | null {
|
||
if (!GameplayDebugBar.shouldShow()) return null;
|
||
let bar = parent.getChildByName('GameplayDebugBar');
|
||
if (!bar) {
|
||
bar = new Node('GameplayDebugBar');
|
||
bar.parent = parent;
|
||
bar.layer = HUD_LAYER;
|
||
bar.addComponent(GameplayDebugBar);
|
||
}
|
||
bar.setSiblingIndex(parent.children.length - 1);
|
||
console.log('[GameplayDebugBar] 已显示(左下角)');
|
||
return bar.getComponent(GameplayDebugBar)!;
|
||
}
|
||
|
||
onLoad() {
|
||
this.node.layer = HUD_LAYER;
|
||
this.buildUI();
|
||
}
|
||
|
||
private gm() {
|
||
return GameManager.instance;
|
||
}
|
||
|
||
private buildUI() {
|
||
const rootUi = this.node.getComponent(UITransform) || this.node.addComponent(UITransform);
|
||
rootUi.setContentSize(680, 52);
|
||
rootUi.setAnchorPoint(0, 0);
|
||
|
||
const bg = this.node.getComponent(Graphics) || this.node.addComponent(Graphics);
|
||
bg.fillColor = new Color(0, 0, 0, 160);
|
||
bg.clear();
|
||
bg.rect(0, 0, 680, 52);
|
||
bg.fill();
|
||
|
||
this.mkLabel('Title', '调试', 8, 26, 14, new Color(255, 220, 120));
|
||
|
||
this.stepBox = this.mkEdit('StepInput', '1', 52, 8, 40);
|
||
this.mkBtn('前', 100, 8, 44, () => this.act('debugMove', this.step()));
|
||
this.mkBtn('后', 150, 8, 44, () => this.act('debugMove', -this.step()));
|
||
this.mkBtn('跳', 200, 8, 40, () => this.act('debugJump'));
|
||
this.mkBtn('←', 246, 8, 36, () => this.act('debugRotateLeft', 1));
|
||
this.mkBtn('→', 288, 8, 36, () => this.act('debugRotateRight', 1));
|
||
this.mkBtn('坐标', 330, 8, 52, () => this.act('debugPlayerInfo'));
|
||
this.mkBtn('结束', 388, 8, 52, () => this.act('debugInputEnd'));
|
||
this.mkBtn('载具', 446, 8, 52, () => this.act('debugVehicleMove', 1));
|
||
|
||
const widget = this.node.getComponent(Widget) || this.node.addComponent(Widget);
|
||
widget.isAlignBottom = true;
|
||
widget.bottom = 12;
|
||
widget.isAlignLeft = true;
|
||
widget.left = 12;
|
||
widget.alignMode = Widget.AlignMode.ON_WINDOW_RESIZE;
|
||
}
|
||
|
||
private step(): number {
|
||
const n = parseInt(this.stepBox?.string ?? '1', 10);
|
||
return Number.isNaN(n) || n === 0 ? 1 : n;
|
||
}
|
||
|
||
private act(method: string, arg?: number) {
|
||
const gm = this.gm();
|
||
if (!gm) {
|
||
console.warn('[GameplayDebugBar] GameController 未就绪');
|
||
return;
|
||
}
|
||
const fn = (gm as unknown as Record<string, unknown>)[method];
|
||
if (typeof fn !== 'function') {
|
||
console.warn(`[GameplayDebugBar] 无方法 ${method}`);
|
||
return;
|
||
}
|
||
if (arg === undefined) (fn as () => void).call(gm);
|
||
else (fn as (n: number) => void).call(gm, arg);
|
||
}
|
||
|
||
private mkLabel(name: string, text: string, x: number, y: number, size: number, color: Color): Label {
|
||
const n = new Node(name);
|
||
n.parent = this.node;
|
||
n.layer = HUD_LAYER;
|
||
n.setPosition(x, y, 0);
|
||
n.addComponent(UITransform).setContentSize(80, 24);
|
||
const lb = n.addComponent(Label);
|
||
lb.string = text;
|
||
lb.fontSize = size;
|
||
lb.color = color;
|
||
return lb;
|
||
}
|
||
|
||
private mkEdit(name: string, value: string, x: number, y: number, w: number): EditBox {
|
||
const n = new Node(name);
|
||
n.parent = this.node;
|
||
n.layer = HUD_LAYER;
|
||
n.setPosition(x, y, 0);
|
||
n.addComponent(UITransform).setContentSize(w, 32);
|
||
const box = n.addComponent(EditBox);
|
||
box.string = value;
|
||
box.fontSize = 16;
|
||
const tl = new Node('TEXT_LABEL');
|
||
tl.parent = n;
|
||
tl.layer = HUD_LAYER;
|
||
tl.addComponent(UITransform).setContentSize(w, 32);
|
||
box.textLabel = tl.addComponent(Label);
|
||
box.textLabel.fontSize = 16;
|
||
box.textLabel.color = new Color(255, 255, 255);
|
||
const pl = new Node('PLACEHOLDER_LABEL');
|
||
pl.parent = n;
|
||
pl.layer = HUD_LAYER;
|
||
pl.addComponent(UITransform).setContentSize(w, 32);
|
||
box.placeholderLabel = pl.addComponent(Label);
|
||
box.placeholderLabel.fontSize = 16;
|
||
box.placeholderLabel.color = new Color(140, 140, 140);
|
||
return box;
|
||
}
|
||
|
||
private mkBtn(caption: string, x: number, y: number, w: number, handler: () => void) {
|
||
const n = new Node(`Btn_${caption}`);
|
||
n.parent = this.node;
|
||
n.layer = HUD_LAYER;
|
||
n.setPosition(x, y, 0);
|
||
n.addComponent(UITransform).setContentSize(w, 32);
|
||
const btn = n.addComponent(Button);
|
||
btn.transition = Button.Transition.SCALE;
|
||
const tl = new Node('Label');
|
||
tl.parent = n;
|
||
tl.layer = HUD_LAYER;
|
||
tl.addComponent(UITransform).setContentSize(w, 32);
|
||
const lb = tl.addComponent(Label);
|
||
lb.string = caption;
|
||
lb.fontSize = 15;
|
||
lb.color = new Color(255, 255, 255);
|
||
n.on(Button.EventType.CLICK, handler, this);
|
||
}
|
||
}
|