feat: 添加微信SDK和关卡页面,重构预制体结构
- 新增 WxSDK 微信SDK工具类 - 新增 PageLevel 关卡选择页面组件 - 将 prefabs 目录从 resources 移至根目录 - 更新 ViewManager 支持预制体属性引用 - 添加 BaseView 页面基类 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
221
assets/prefabs/PageLevel.ts
Normal file
221
assets/prefabs/PageLevel.ts
Normal file
@@ -0,0 +1,221 @@
|
||||
import { _decorator, Node, EditBox, instantiate, Vec3 } from 'cc';
|
||||
import { BaseView } from 'db://assets/scripts/core/BaseView';
|
||||
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({
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* 页面每次显示时调用
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user