256 lines
6.4 KiB
TypeScript
256 lines
6.4 KiB
TypeScript
import { _decorator, Node, EditBox, instantiate, Vec3, Button } from 'cc';
|
||
import { BaseView } from 'db://assets/scripts/core/BaseView';
|
||
import { ViewManager } from 'db://assets/scripts/core/ViewManager';
|
||
const { ccclass, property } = _decorator;
|
||
|
||
/**
|
||
* 关卡配置接口
|
||
*/
|
||
export interface LevelConfig {
|
||
/** 需要的输入框数量 */
|
||
inputCount: number;
|
||
/** 题目文本 */
|
||
questionText?: string;
|
||
}
|
||
|
||
/**
|
||
* 关卡页面组件
|
||
* 继承 BaseView,实现页面生命周期
|
||
*/
|
||
@ccclass('PageLevel')
|
||
export class PageLevel extends BaseView {
|
||
// ========== 节点引用 ==========
|
||
@property(Node)
|
||
inputLayout: Node | null = null;
|
||
|
||
@property(Node)
|
||
submitButton: Node | null = null;
|
||
|
||
@property(Node)
|
||
inputTemplate: Node | null = null;
|
||
|
||
@property(Node)
|
||
actionNode: Node | null = null;
|
||
|
||
@property(Node)
|
||
iconSetting: Node | null = null;
|
||
|
||
// ========== 配置属性 ==========
|
||
@property({
|
||
tooltip: '默认输入框数量',
|
||
min: 1,
|
||
max: 10
|
||
})
|
||
defaultInputCount: number = 2;
|
||
|
||
// ========== 内部状态 ==========
|
||
/** 当前输入框数量 */
|
||
private _inputCount: number = 0;
|
||
|
||
/** 当前创建的输入框节点数组 */
|
||
private _inputNodes: Node[] = [];
|
||
|
||
/** 当前关卡配置 */
|
||
private _levelConfig: LevelConfig | null = null;
|
||
|
||
/**
|
||
* 页面首次加载时调用
|
||
*/
|
||
onViewLoad(): void {
|
||
console.log('[PageLevel] onViewLoad');
|
||
this.initLevel();
|
||
this.initIconSetting();
|
||
}
|
||
|
||
/**
|
||
* 页面每次显示时调用
|
||
*/
|
||
onViewShow(): void {
|
||
console.log('[PageLevel] onViewShow');
|
||
}
|
||
|
||
/**
|
||
* 页面隐藏时调用
|
||
*/
|
||
onViewHide(): void {
|
||
console.log('[PageLevel] onViewHide');
|
||
}
|
||
|
||
/**
|
||
* 页面销毁时调用
|
||
*/
|
||
onViewDestroy(): void {
|
||
console.log('[PageLevel] onViewDestroy');
|
||
this.clearInputNodes();
|
||
}
|
||
|
||
/**
|
||
* 设置关卡配置
|
||
*/
|
||
setLevelConfig(config: LevelConfig): void {
|
||
this._levelConfig = config;
|
||
this.initLevel();
|
||
}
|
||
|
||
/**
|
||
* 初始化关卡
|
||
*/
|
||
private initLevel(): void {
|
||
// 使用配置或默认值
|
||
const inputCount = this._levelConfig?.inputCount ?? this.defaultInputCount;
|
||
|
||
// 隐藏提交按钮
|
||
if (this.submitButton) {
|
||
this.submitButton.active = false;
|
||
}
|
||
|
||
// 创建输入框
|
||
this.createInputs(inputCount);
|
||
}
|
||
|
||
/**
|
||
* 动态创建输入框
|
||
*/
|
||
private createInputs(count: number): void {
|
||
if (!this.inputLayout || !this.inputTemplate) {
|
||
console.error('[PageLevel] inputLayout 或 inputTemplate 未设置');
|
||
return;
|
||
}
|
||
|
||
// 清理现有输入框
|
||
this.clearInputNodes();
|
||
|
||
this._inputCount = count;
|
||
|
||
// 隐藏模板节点
|
||
this.inputTemplate.active = false;
|
||
|
||
// 创建指定数量的输入框
|
||
for (let i = 0; i < count; i++) {
|
||
const inputNode = instantiate(this.inputTemplate);
|
||
inputNode.active = true;
|
||
inputNode.name = `input${i}`;
|
||
|
||
// 设置位置(Layout 会自动排列)
|
||
inputNode.setPosition(new Vec3(0, 0, 0));
|
||
|
||
// 获取 EditBox 组件并监听事件
|
||
const editBox = inputNode.getComponent(EditBox);
|
||
if (editBox) {
|
||
// 清空输入内容
|
||
editBox.string = '';
|
||
// 监听文本变化事件
|
||
editBox.node.on(EditBox.EventType.TEXT_CHANGED, this.onInputTextChanged, this);
|
||
// 监听编辑结束事件
|
||
editBox.node.on(EditBox.EventType.EDITING_DID_ENDED, this.onInputEditingEnded, this);
|
||
}
|
||
|
||
this.inputLayout.addChild(inputNode);
|
||
this._inputNodes.push(inputNode);
|
||
}
|
||
|
||
console.log(`[PageLevel] 创建了 ${count} 个输入框`);
|
||
}
|
||
|
||
/**
|
||
* 清理所有输入框节点
|
||
*/
|
||
private clearInputNodes(): void {
|
||
for (const node of this._inputNodes) {
|
||
if (node.isValid) {
|
||
node.destroy();
|
||
}
|
||
}
|
||
this._inputNodes = [];
|
||
this._inputCount = 0;
|
||
}
|
||
|
||
/**
|
||
* 检查所有输入框是否都已填写
|
||
*/
|
||
private checkAllInputsFilled(): void {
|
||
let allFilled = true;
|
||
|
||
for (const node of this._inputNodes) {
|
||
const editBox = node.getComponent(EditBox);
|
||
if (!editBox || editBox.string.trim() === '') {
|
||
allFilled = false;
|
||
break;
|
||
}
|
||
}
|
||
|
||
// 根据填写状态显示/隐藏提交按钮
|
||
if (this.submitButton) {
|
||
this.submitButton.active = allFilled;
|
||
}
|
||
|
||
console.log(`[PageLevel] 检查输入状态: ${allFilled ? '全部已填写' : '未全部填写'}`);
|
||
}
|
||
|
||
/**
|
||
* 获取所有输入框的值
|
||
*/
|
||
getInputValues(): string[] {
|
||
const values: string[] = [];
|
||
for (const node of this._inputNodes) {
|
||
const editBox = node.getComponent(EditBox);
|
||
values.push(editBox?.string ?? '');
|
||
}
|
||
return values;
|
||
}
|
||
|
||
/**
|
||
* 获取拼接后的答案字符串
|
||
*/
|
||
getAnswer(): string {
|
||
return this.getInputValues().join('');
|
||
}
|
||
|
||
// ========== EditBox 事件回调 ==========
|
||
|
||
/**
|
||
* 输入框文本变化回调
|
||
*/
|
||
private onInputTextChanged(editBox: EditBox): void {
|
||
this.checkAllInputsFilled();
|
||
}
|
||
|
||
/**
|
||
* 输入框编辑结束回调
|
||
*/
|
||
private onInputEditingEnded(editBox: EditBox): void {
|
||
this.checkAllInputsFilled();
|
||
}
|
||
|
||
// ========== IconSetting 按钮相关 ==========
|
||
|
||
/**
|
||
* 初始化 IconSetting 按钮事件
|
||
*/
|
||
private initIconSetting(): void {
|
||
if (!this.iconSetting) {
|
||
console.warn('[PageLevel] iconSetting 节点未设置');
|
||
return;
|
||
}
|
||
|
||
const button = this.iconSetting.getComponent(Button);
|
||
if (!button) {
|
||
console.warn('[PageLevel] iconSetting 节点缺少 Button 组件');
|
||
return;
|
||
}
|
||
|
||
this.iconSetting.on(Node.EventType.TOUCH_END, this.onIconSettingClick, this);
|
||
console.log('[PageLevel] IconSetting 按钮事件已绑定');
|
||
}
|
||
|
||
/**
|
||
* IconSetting 按钮点击回调
|
||
*/
|
||
private onIconSettingClick(): void {
|
||
console.log('[PageLevel] IconSetting 点击,返回主页');
|
||
ViewManager.instance.back();
|
||
}
|
||
}
|
||
|
||
|