Files
cocos/assets/scripts/ui/GameplayDebugBar.ts
刘宇飞 d393302388 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>
2026-06-16 15:30:58 +08:00

152 lines
5.5 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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);
}
}