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:
161
assets/scripts/ui/LevelSwitchBar.ts
Normal file
161
assets/scripts/ui/LevelSwitchBar.ts
Normal file
@@ -0,0 +1,161 @@
|
||||
import {
|
||||
_decorator, Component, Node, Label, EditBox, Button, UITransform, Color, Widget,
|
||||
} from 'cc';
|
||||
import { GameManager } from '../manager/GameManager';
|
||||
import { getMaxLevelId, getMinLevelId } from '../level/LevelRegistry';
|
||||
|
||||
const { ccclass } = _decorator;
|
||||
|
||||
/**
|
||||
* 预览/运行时的关卡切换条(真实 Button,不依赖 Inspector 扩展)
|
||||
*/
|
||||
@ccclass('LevelSwitchBar')
|
||||
export class LevelSwitchBar extends Component {
|
||||
private editBox: EditBox | null = null;
|
||||
|
||||
static ensure(parent: Node): LevelSwitchBar {
|
||||
let bar = parent.getChildByName('LevelSwitchBar');
|
||||
if (!bar) {
|
||||
bar = new Node('LevelSwitchBar');
|
||||
bar.parent = parent;
|
||||
bar.addComponent(LevelSwitchBar);
|
||||
}
|
||||
return bar.getComponent(LevelSwitchBar)!;
|
||||
}
|
||||
|
||||
onLoad() {
|
||||
this.buildUI();
|
||||
}
|
||||
|
||||
private buildUI() {
|
||||
const rootUi = this.node.getComponent(UITransform) || this.node.addComponent(UITransform);
|
||||
rootUi.setContentSize(520, 48);
|
||||
|
||||
const hint = this.node.getChildByName('HintLabel') ?? new Node('HintLabel');
|
||||
hint.parent = this.node;
|
||||
const hintUi = hint.getComponent(UITransform) || hint.addComponent(UITransform);
|
||||
hintUi.setContentSize(200, 36);
|
||||
hint.setPosition(-160, 0, 0);
|
||||
const hintLabel = hint.getComponent(Label) || hint.addComponent(Label);
|
||||
hintLabel.string = `关卡 ${getMinLevelId()}–${getMaxLevelId()}`;
|
||||
hintLabel.fontSize = 18;
|
||||
hintLabel.color = new Color(200, 220, 255);
|
||||
|
||||
let inputNode = this.node.getChildByName('LevelInput');
|
||||
if (!inputNode) {
|
||||
inputNode = new Node('LevelInput');
|
||||
inputNode.parent = this.node;
|
||||
}
|
||||
inputNode.setPosition(-20, 0, 0);
|
||||
const inputUi = inputNode.getComponent(UITransform) || inputNode.addComponent(UITransform);
|
||||
inputUi.setContentSize(80, 36);
|
||||
this.editBox = inputNode.getComponent(EditBox) || inputNode.addComponent(EditBox);
|
||||
this.editBox.placeholder = '关卡号';
|
||||
this.editBox.string = '1';
|
||||
this.editBox.fontSize = 20;
|
||||
this.editBox.textLabel = this.ensureEditLabel(inputNode);
|
||||
this.editBox.placeholderLabel = this.ensurePlaceholderLabel(inputNode);
|
||||
|
||||
let btnNode = this.node.getChildByName('BtnSwitchLevel');
|
||||
if (!btnNode) {
|
||||
btnNode = new Node('BtnSwitchLevel');
|
||||
btnNode.parent = this.node;
|
||||
}
|
||||
btnNode.setPosition(120, 0, 0);
|
||||
const btnUi = btnNode.getComponent(UITransform) || btnNode.addComponent(UITransform);
|
||||
btnUi.setContentSize(140, 40);
|
||||
const btn = btnNode.getComponent(Button) || btnNode.addComponent(Button);
|
||||
btn.transition = Button.Transition.SCALE;
|
||||
const btnLabel = this.ensureButtonLabel(btnNode);
|
||||
btnLabel.string = '切换关卡';
|
||||
btnLabel.fontSize = 20;
|
||||
btnLabel.color = new Color(255, 255, 255);
|
||||
btn.node.off(Button.EventType.CLICK);
|
||||
btn.node.on(Button.EventType.CLICK, this.onClickSwitch, this);
|
||||
|
||||
let prevNode = this.node.getChildByName('BtnPrev');
|
||||
if (!prevNode) {
|
||||
prevNode = new Node('BtnPrev');
|
||||
prevNode.parent = this.node;
|
||||
}
|
||||
prevNode.setPosition(200, 0, 0);
|
||||
prevNode.getComponent(UITransform) || prevNode.addComponent(UITransform).setContentSize(56, 36);
|
||||
const prevBtn = prevNode.getComponent(Button) || prevNode.addComponent(Button);
|
||||
const prevLbl = this.ensureButtonLabel(prevNode);
|
||||
prevLbl.string = '◀';
|
||||
prevLbl.fontSize = 22;
|
||||
prevNode.off(Button.EventType.CLICK);
|
||||
prevNode.on(Button.EventType.CLICK, () => GameManager.instance?.prevLevel(), this);
|
||||
|
||||
let nextNode = this.node.getChildByName('BtnNext');
|
||||
if (!nextNode) {
|
||||
nextNode = new Node('BtnNext');
|
||||
nextNode.parent = this.node;
|
||||
}
|
||||
nextNode.setPosition(248, 0, 0);
|
||||
nextNode.getComponent(UITransform) || nextNode.addComponent(UITransform).setContentSize(56, 36);
|
||||
const nextBtn = nextNode.getComponent(Button) || nextNode.addComponent(Button);
|
||||
const nextLbl = this.ensureButtonLabel(nextNode);
|
||||
nextLbl.string = '▶';
|
||||
nextLbl.fontSize = 22;
|
||||
nextNode.off(Button.EventType.CLICK);
|
||||
nextNode.on(Button.EventType.CLICK, () => GameManager.instance?.nextLevel(), this);
|
||||
|
||||
const widget = this.node.getComponent(Widget) || this.node.addComponent(Widget);
|
||||
widget.isAlignTop = true;
|
||||
widget.top = 12;
|
||||
widget.isAlignHorizontalCenter = true;
|
||||
widget.alignMode = Widget.AlignMode.ON_WINDOW_RESIZE;
|
||||
}
|
||||
|
||||
syncFromManager() {
|
||||
const gm = GameManager.instance;
|
||||
if (!gm || !this.editBox) return;
|
||||
this.editBox.string = gm.inputLevel || String(gm.curLevelID);
|
||||
}
|
||||
|
||||
private onClickSwitch() {
|
||||
const gm = GameManager.instance;
|
||||
if (!gm) {
|
||||
console.warn('[LevelSwitchBar] GameManager 未就绪');
|
||||
return;
|
||||
}
|
||||
if (this.editBox) {
|
||||
gm.inputLevel = this.editBox.string.trim();
|
||||
}
|
||||
gm.clickSwitchLevel();
|
||||
this.syncFromManager();
|
||||
}
|
||||
|
||||
private ensureButtonLabel(btnNode: Node): Label {
|
||||
let t = btnNode.getChildByName('Label');
|
||||
if (!t) {
|
||||
t = new Node('Label');
|
||||
t.parent = btnNode;
|
||||
t.addComponent(UITransform).setContentSize(140, 40);
|
||||
}
|
||||
return t.getComponent(Label) || t.addComponent(Label);
|
||||
}
|
||||
|
||||
private ensureEditLabel(parent: Node): Label {
|
||||
let t = parent.getChildByName('TEXT_LABEL');
|
||||
if (!t) {
|
||||
t = new Node('TEXT_LABEL');
|
||||
t.parent = parent;
|
||||
t.addComponent(UITransform).setContentSize(80, 36);
|
||||
}
|
||||
return t.getComponent(Label) || t.addComponent(Label);
|
||||
}
|
||||
|
||||
private ensurePlaceholderLabel(parent: Node): Label {
|
||||
let t = parent.getChildByName('PLACEHOLDER_LABEL');
|
||||
if (!t) {
|
||||
t = new Node('PLACEHOLDER_LABEL');
|
||||
t.parent = parent;
|
||||
t.addComponent(UITransform).setContentSize(80, 36);
|
||||
}
|
||||
const lb = t.getComponent(Label) || t.addComponent(Label);
|
||||
lb.color = new Color(160, 160, 160);
|
||||
return lb;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user