feat: 添加微信SDK和关卡页面,重构预制体结构

- 新增 WxSDK 微信SDK工具类
- 新增 PageLevel 关卡选择页面组件
- 将 prefabs 目录从 resources 移至根目录
- 更新 ViewManager 支持预制体属性引用
- 添加 BaseView 页面基类

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
richarjiang
2026-03-11 10:35:21 +08:00
parent 8986d8d8f2
commit 0bda6904fa
18 changed files with 1149 additions and 1646 deletions

221
assets/prefabs/PageLevel.ts Normal file
View 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();
}
}