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:
151
assets/scripts/ui/GameplayDebugBar.ts
Normal file
151
assets/scripts/ui/GameplayDebugBar.ts
Normal file
@@ -0,0 +1,151 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user