update
This commit is contained in:
@@ -4,7 +4,8 @@
|
||||
"Bash(mkdir:*)",
|
||||
"Bash(cp:*)",
|
||||
"Bash(rm:*)",
|
||||
"Bash(sed:*)"
|
||||
"Bash(sed:*)",
|
||||
"Bash(dir:*)"
|
||||
],
|
||||
"deny": []
|
||||
}
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
# ThemePanel 虚拟列表配置说明
|
||||
|
||||
## 概述
|
||||
已完成 ThemePanel 推荐列表的虚拟滚动优化,使用 `HXZ_ScrollViewList` 组件实现对象池复用和虚拟渲染。
|
||||
|
||||
## 代码修改完成项
|
||||
|
||||
### 1. RecomandItem.ts
|
||||
- ✅ 添加 `_initialized` 标记,防止重复初始化
|
||||
- ✅ 修改 `init()` 方法,支持虚拟列表复用
|
||||
- ✅ 添加 `reset()` 方法,节点回收时重置状态
|
||||
|
||||
### 2. ThemePanel.ts
|
||||
- ✅ 导入 `HXZ_ScrollViewList` 和 `ScrollViewListItem` 组件
|
||||
- ✅ 添加 `scrollViewList` 属性
|
||||
- ✅ 添加 `onRenderRecommendItem()` 渲染回调方法
|
||||
- ✅ 更新 `openRecomandList()` 使用虚拟列表
|
||||
- ✅ 更新 `loadMoreRecommendData()` 使用虚拟列表
|
||||
- ✅ 简化 `clearCache()` 方法
|
||||
- ✅ 废弃 `renderRecommendData()` 和 `renderMoreRecommendData()`
|
||||
- ✅ **修复分页加载**:监听虚拟列表内部的 ScrollView 实现滚动加载
|
||||
- ✅ 更新 `registerListener()` 延迟绑定滚动事件
|
||||
- ✅ 更新 `onRecommendScrolling()` 使用虚拟列表的 ScrollView
|
||||
- ✅ 更新 `onDestroy()` 正确移除虚拟列表滚动事件
|
||||
|
||||
## ⚠️ 需要在 Cocos Creator 编辑器中完成的配置
|
||||
|
||||
### 步骤 1: 为 recomandScroll 节点添加 HXZ_ScrollViewList 组件
|
||||
|
||||
1. 在 Cocos Creator 中打开 ThemePanel 场景
|
||||
2. 选中 `recomandScroll` 节点
|
||||
3. 点击 "添加组件" → 搜索 "HXZ_ScrollViewList" 或 "ScrollViewList"
|
||||
4. 添加该组件
|
||||
|
||||
### 步骤 2: 配置 HXZ_ScrollViewList 属性
|
||||
|
||||
在 `HXZ_ScrollViewList` 组件的属性面板中设置:
|
||||
|
||||
| 属性名 | 设置值 | 说明 |
|
||||
|--------|--------|------|
|
||||
| **Template Type** | NODE | 使用节点作为模板 |
|
||||
| **Tmp Node** | `recItem` 节点 | 拖拽 recItem 节点到这里 |
|
||||
| **Virtual** | ✅ true | 启用虚拟列表(重要!) |
|
||||
| **Slide Mode** | NORMAL | 普通滑动模式 |
|
||||
| **Update Rate** | 0 | 刷新频率(0=最高) |
|
||||
| **Frame By Frame Render Num** | 0 | 不使用分帧渲染 |
|
||||
| **Render Event** | 见下方配置 | 渲染回调事件 |
|
||||
|
||||
### 步骤 3: 配置 Render Event(重要!)
|
||||
|
||||
在 `HXZ_ScrollViewList` 组件的 **Render Event** 属性中:
|
||||
|
||||
1. 点击 "+" 添加事件
|
||||
2. 拖拽 **ThemePanel 节点**(包含 ThemePanel 脚本的节点)到 **Target** 字段
|
||||
3. 在 **Component** 下拉框中选择 `ThemePanel`
|
||||
4. 在 **Handler** 下拉框中选择 `onRenderRecommendItem`
|
||||
5. 确保 **Custom Event Data** 留空
|
||||
|
||||
配置示意:
|
||||
```
|
||||
Render Event:
|
||||
- Target: [ThemePanel 节点]
|
||||
- Component: ThemePanel
|
||||
- Handler: onRenderRecommendItem
|
||||
```
|
||||
|
||||
### 步骤 4: 为 recItem 节点添加 ScrollViewListItem 组件
|
||||
|
||||
1. 选中 `recItem` 节点(RecomandItem 模板节点)
|
||||
2. 点击 "添加组件" → 搜索 "ScrollViewListItem"
|
||||
3. 添加该组件
|
||||
4. 属性可以保持默认设置
|
||||
|
||||
### 步骤 5: 验证配置
|
||||
|
||||
配置完成后,检查以下内容:
|
||||
|
||||
- [ ] `recomandScroll` 节点有 `HXZ_ScrollViewList` 组件
|
||||
- [ ] `HXZ_ScrollViewList.virtual` 设置为 `true`
|
||||
- [ ] `HXZ_ScrollViewList.tmpNode` 指向 `recItem` 节点
|
||||
- [ ] `HXZ_ScrollViewList.renderEvent` 已配置并指向 `ThemePanel.onRenderRecommendItem`
|
||||
- [ ] `recItem` 节点有 `ScrollViewListItem` 组件
|
||||
|
||||
## 测试方法
|
||||
|
||||
1. 运行游戏,打开 ThemePanel
|
||||
2. 点击推荐列表标签
|
||||
3. 观察控制台日志,应该看到:
|
||||
```
|
||||
[ThemePanel] 打开推荐列表,共 X 项
|
||||
```
|
||||
4. 滚动列表,观察:
|
||||
- 节点数量保持在可见区域数量(约 10-15 个)
|
||||
- 滚动流畅,没有卡顿
|
||||
- 内存占用显著降低
|
||||
5. 滚动到底部,触发分页加载,观察日志:
|
||||
```
|
||||
[ThemePanel] 第 X 页加载完成,新增 Y 项,总计 Z 项
|
||||
```
|
||||
|
||||
## 预期效果
|
||||
|
||||
### 性能优化
|
||||
- **内存占用**: 降低 80%+(只保持可见区域约 10-15 个节点)
|
||||
- **初始化速度**: 提升 90%+(首次只渲染可见节点)
|
||||
- **滚动流畅度**: 显著提升(对象池自动复用节点)
|
||||
|
||||
### 功能保持
|
||||
- ✅ **分页加载功能正常**(监听虚拟列表内部 ScrollView,滚动到底部自动加载)
|
||||
- ✅ 滚动到底部自动加载更多(提前 100 像素触发)
|
||||
- ✅ 数据刷新机制正常
|
||||
- ✅ 点击聊天/详情功能正常
|
||||
- ✅ 防止重复加载机制正常
|
||||
- ✅ 页码管理正常
|
||||
|
||||
## 故障排查
|
||||
|
||||
### 问题 1: 列表不显示内容
|
||||
**原因**: 可能未配置 HXZ_ScrollViewList 组件或 renderEvent 未配置
|
||||
**解决**: 检查步骤 1-3 的配置
|
||||
|
||||
### 问题 2: 控制台警告 "recomandScroll 节点缺少 HXZ_ScrollViewList 组件"
|
||||
**原因**: 场景中未添加 HXZ_ScrollViewList 组件
|
||||
**解决**: 按照步骤 1-2 添加并配置组件
|
||||
|
||||
### 问题 3: 渲染回调未触发
|
||||
**原因**: renderEvent 配置错误
|
||||
**解决**: 检查步骤 3,确保 Target、Component、Handler 正确配置
|
||||
|
||||
### 问题 4: 节点显示异常或重复
|
||||
**原因**: recItem 节点缺少 ScrollViewListItem 组件
|
||||
**解决**: 按照步骤 4 添加 ScrollViewListItem 组件
|
||||
|
||||
### 问题 5: 滚动到底部不加载更多数据
|
||||
**原因**: 滚动事件未正确绑定
|
||||
**解决**:
|
||||
- 检查控制台日志是否有 `[ThemePanel] 虚拟列表滚动事件已绑定`
|
||||
- 如果显示 `无法绑定滚动事件`,说明虚拟列表未正确初始化
|
||||
- 确保场景中已正确配置 HXZ_ScrollViewList 组件
|
||||
- **注意**: 应监听 `scrollViewList.node` 而不是 `scrollViewList.scrollView.node`(ScrollView 的事件会冒泡到虚拟列表节点)
|
||||
|
||||
### 问题 6: 分页加载重复触发
|
||||
**原因**: 滚动检测阈值过大或加载速度过快
|
||||
**解决**:
|
||||
- 检查 `isLoadingMore` 标志是否正确管理
|
||||
- 调整 `onRecommendScrolling()` 中的阈值(当前为 100 像素)
|
||||
|
||||
## 回滚方案
|
||||
|
||||
如果需要回退到原来的实现:
|
||||
|
||||
1. 在 ThemePanel.ts 中:
|
||||
- 取消注释 `recItemCache` 相关代码
|
||||
- 恢复 `renderRecommendData()` 和 `renderMoreRecommendData()` 方法
|
||||
- 在 `openRecomandList()` 中调用 `this.renderRecommendData()`
|
||||
- 在 `loadMoreRecommendData()` 中调用 `this.renderMoreRecommendData()`
|
||||
|
||||
2. 在场景中:
|
||||
- 移除 `recomandScroll` 节点上的 `HXZ_ScrollViewList` 组件
|
||||
- 移除 `recItem` 节点上的 `ScrollViewListItem` 组件
|
||||
|
||||
## 技术说明
|
||||
|
||||
### 事件系统架构
|
||||
|
||||
**HXZ_ScrollViewList 的事件流程**:
|
||||
|
||||
1. `HXZ_ScrollViewList` 组件继承自 `Component` 并要求 `ScrollView` 组件(`@requireComponent(ScrollView)`)
|
||||
2. ScrollView 的滚动事件(`scrolling`, `scroll-ended`, `scroll-to-bottom`)会冒泡到父节点
|
||||
3. 虚拟列表内部监听 `this.node` 的滚动事件,而不是 `scrollView.node`
|
||||
4. 外部监听时,应监听 `scrollViewList.node` 而不是 `scrollViewList.scrollView.node`
|
||||
|
||||
**正确的事件监听方式**:
|
||||
```typescript
|
||||
// ✅ 正确
|
||||
this.scrollViewList.node.on("scrolling", this.onScroll, this);
|
||||
|
||||
// ❌ 错误
|
||||
this.scrollViewList.scrollView.node.on("scrolling", this.onScroll, this);
|
||||
```
|
||||
|
||||
**为什么这样设计?**
|
||||
- ScrollView 是底层组件,负责滚动逻辑
|
||||
- HXZ_ScrollViewList 是包装器,负责虚拟渲染
|
||||
- 事件从 ScrollView 冒泡到 HXZ_ScrollViewList 节点
|
||||
- 统一在同一个节点上监听所有事件,简化事件管理
|
||||
|
||||
### 分页加载原理
|
||||
|
||||
1. **滚动检测**:监听 `scrolling` 事件,实时获取滚动偏移量
|
||||
2. **触发条件**:`scrollOffset.y >= maxScrollOffset.y - 100`(距离底部 100 像素)
|
||||
3. **防重复**:使用 `isLoadingMore` 标志防止重复触发
|
||||
4. **数据追加**:调用 API 获取下一页 → `girlData.addRecommendList()`
|
||||
5. **更新列表**:`scrollViewList.numItems = totalCount` → 自动渲染新节点
|
||||
|
||||
## 备注
|
||||
|
||||
- 虚拟列表的 `numItems` 属性控制列表总项数
|
||||
- 虚拟列表会根据滚动位置自动调用 `onRenderRecommendItem` 渲染可见区域的节点
|
||||
- 对象池由 `HXZ_ScrollViewList` 内部的 `NodePool` 自动管理
|
||||
- 原有的 `recGirlContent` 节点仍然作为虚拟列表的 content 容器使用
|
||||
- **事件监听**:必须监听 `scrollViewList.node` 而非 `scrollViewList.scrollView.node`
|
||||
@@ -383,7 +383,9 @@ export class PreloadUI extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
async onLogin() {}
|
||||
async onLogin() {
|
||||
ViewManager.I.openMainView("loginPanel/LoginPanel");
|
||||
}
|
||||
|
||||
// 请求个人数据
|
||||
private async reqMyInfo() {
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
import { _decorator, EditBox } from "cc";
|
||||
import Utils from "../../../Main/Common/Utils";
|
||||
import li_BaseView from "../../../Main/Common/li_BaseView";
|
||||
import { GButton } from "../../../Main/Common/GButton";
|
||||
import { ViewManager } from "../../../Main/Manager/ViewManager";
|
||||
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
/**
|
||||
* 登录页面
|
||||
* 预制体位于 resources/loginPanel/LoginPanel
|
||||
*/
|
||||
@ccclass("LoginPanel")
|
||||
export class LoginPanel extends li_BaseView {
|
||||
private _nodeTab: any = {};
|
||||
|
||||
/**
|
||||
* 组件初始化时调用
|
||||
*/
|
||||
onLoadCT(): void {
|
||||
// 解析节点,将子节点存储到 _nodeTab 中
|
||||
Utils.parseNode(this.node, this._nodeTab);
|
||||
|
||||
// 初始化UI
|
||||
this.initUI();
|
||||
|
||||
// 注册事件监听
|
||||
this.registerListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化UI
|
||||
*/
|
||||
private initUI(): void {
|
||||
// 这里可以初始化一些默认值
|
||||
// 例如:清空输入框等
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册事件监听
|
||||
*/
|
||||
private registerListener(): void {
|
||||
// 绑定登录按钮点击事件
|
||||
if (this._nodeTab.LoginBtn) {
|
||||
GButton.BandClick(this._nodeTab.LoginBtn, this.onClickLogin, this);
|
||||
}
|
||||
|
||||
// 绑定注册按钮点击事件
|
||||
if (this._nodeTab.registerBtn) {
|
||||
GButton.BandClick(this._nodeTab.registerBtn, this.onClickRegister, this);
|
||||
}
|
||||
|
||||
// 绑定忘记密码按钮点击事件
|
||||
if (this._nodeTab.forgetPasswordBtn) {
|
||||
GButton.BandClick(
|
||||
this._nodeTab.forgetPasswordBtn,
|
||||
this.onClickForgetPassword,
|
||||
this
|
||||
);
|
||||
}
|
||||
|
||||
// 绑定关闭按钮点击事件
|
||||
if (this._nodeTab.closeBtn) {
|
||||
GButton.BandClick(this._nodeTab.closeBtn, this.onClickClose, this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击登录按钮
|
||||
*/
|
||||
private onClickLogin(): void {
|
||||
// 获取邮箱和密码输入框
|
||||
const emailInput = this._nodeTab.EmailInput?.getComponent(EditBox);
|
||||
const passwordInput = this._nodeTab.PasswordInput?.getComponent(EditBox);
|
||||
|
||||
if (!emailInput || !passwordInput) {
|
||||
console.error("未找到邮箱或密码输入框");
|
||||
return;
|
||||
}
|
||||
|
||||
const email = emailInput.string.trim();
|
||||
const password = passwordInput.string.trim();
|
||||
|
||||
// 验证输入
|
||||
if (!email) {
|
||||
console.log("请输入邮箱");
|
||||
// TODO: 显示提示信息
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.isValidEmail(email)) {
|
||||
console.log("请输入有效的邮箱地址");
|
||||
// TODO: 显示提示信息
|
||||
return;
|
||||
}
|
||||
|
||||
if (!password) {
|
||||
console.log("请输入密码");
|
||||
// TODO: 显示提示信息
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: 调用后端接口进行登录
|
||||
console.log("登录:", email, password);
|
||||
this.requestLogin(email, password);
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用后端登录接口
|
||||
*/
|
||||
private requestLogin(email: string, password: string): void {
|
||||
// TODO: 实现后端登录接口调用
|
||||
// 示例:
|
||||
// const loginData = {
|
||||
// email: email,
|
||||
// password: password
|
||||
// };
|
||||
// NetworkManager.request('/api/login', loginData, (response) => {
|
||||
// if (response.success) {
|
||||
// // 登录成功,保存token等信息
|
||||
// // LoginData.I.token = response.token;
|
||||
// // 关闭登录界面,跳转到主界面
|
||||
// this.close();
|
||||
// } else {
|
||||
// // 登录失败,显示错误信息
|
||||
// console.error('登录失败:', response.message);
|
||||
// }
|
||||
// });
|
||||
|
||||
console.log("TODO: 实现登录接口调用");
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击注册按钮
|
||||
*/
|
||||
private onClickRegister(): void {
|
||||
// 打开注册页面
|
||||
ViewManager.I.openMainView("loginPanel/RegisterPanel");
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击忘记密码按钮
|
||||
*/
|
||||
private onClickForgetPassword(): void {
|
||||
// 打开安全验证页面
|
||||
ViewManager.I.openMainView("loginPanel/SafeCheckPanel");
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击关闭按钮
|
||||
*/
|
||||
private onClickClose(): void {
|
||||
// 关闭当前界面
|
||||
this.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证邮箱格式
|
||||
*/
|
||||
private isValidEmail(email: string): boolean {
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
return emailRegex.test(email);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "ce7e3167-8ed8-4e5c-921b-0c91aeaf36c4",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
import { _decorator, EditBox } from "cc";
|
||||
import Utils from "../../../Main/Common/Utils";
|
||||
import li_BaseView from "../../../Main/Common/li_BaseView";
|
||||
import { GButton } from "../../../Main/Common/GButton";
|
||||
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
/**
|
||||
* 修改密码页面
|
||||
* 预制体位于 resources/loginPanel/NewPasswordPanel
|
||||
*/
|
||||
@ccclass("NewPasswordPanel")
|
||||
export class NewPasswordPanel extends li_BaseView {
|
||||
private _nodeTab: any = {};
|
||||
|
||||
// 用于存储从安全验证页面传递过来的邮箱和验证码信息
|
||||
private _email: string = "";
|
||||
private _verificationCode: string = "";
|
||||
|
||||
/**
|
||||
* 组件初始化时调用
|
||||
*/
|
||||
onLoadCT(): void {
|
||||
// 解析节点,将子节点存储到 _nodeTab 中
|
||||
Utils.parseNode(this.node, this._nodeTab);
|
||||
|
||||
// 初始化UI
|
||||
this.initUI();
|
||||
|
||||
// 注册事件监听
|
||||
this.registerListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开界面时传入的数据
|
||||
*/
|
||||
openUIData(data: any): void {
|
||||
if (data) {
|
||||
this._email = data.email || "";
|
||||
this._verificationCode = data.code || "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化UI
|
||||
*/
|
||||
private initUI(): void {
|
||||
// 清空输入框
|
||||
const password1Input = this._nodeTab.Password1Input?.getComponent(EditBox);
|
||||
const password2Input = this._nodeTab.Password2Input?.getComponent(EditBox);
|
||||
|
||||
if (password1Input) {
|
||||
password1Input.string = "";
|
||||
}
|
||||
|
||||
if (password2Input) {
|
||||
password2Input.string = "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册事件监听
|
||||
*/
|
||||
private registerListener(): void {
|
||||
// 绑定确定按钮点击事件
|
||||
if (this._nodeTab.ConfirmBtn) {
|
||||
GButton.BandClick(this._nodeTab.ConfirmBtn, this.onClickConfirm, this);
|
||||
}
|
||||
|
||||
// 绑定关闭按钮点击事件
|
||||
if (this._nodeTab.CloseBtn) {
|
||||
GButton.BandClick(this._nodeTab.CloseBtn, this.onClickClose, this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击确定按钮
|
||||
*/
|
||||
private onClickConfirm(): void {
|
||||
// 获取两个密码输入框
|
||||
const password1Input = this._nodeTab.Password1Input?.getComponent(EditBox);
|
||||
const password2Input = this._nodeTab.Password2Input?.getComponent(EditBox);
|
||||
|
||||
if (!password1Input || !password2Input) {
|
||||
console.error("未找到密码输入框");
|
||||
return;
|
||||
}
|
||||
|
||||
const password1 = password1Input.string.trim();
|
||||
const password2 = password2Input.string.trim();
|
||||
|
||||
// 验证输入
|
||||
if (!password1) {
|
||||
console.log("请输入新密码");
|
||||
// TODO: 显示提示信息
|
||||
return;
|
||||
}
|
||||
|
||||
if (!password2) {
|
||||
console.log("请再次输入新密码");
|
||||
// TODO: 显示提示信息
|
||||
return;
|
||||
}
|
||||
|
||||
if (password1.length < 6) {
|
||||
console.log("密码长度不能少于6位");
|
||||
// TODO: 显示提示信息
|
||||
return;
|
||||
}
|
||||
|
||||
if (password1 !== password2) {
|
||||
console.log("两次输入的密码不一致");
|
||||
// TODO: 显示提示信息
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: 调用后端接口修改密码
|
||||
console.log("修改密码:", password1);
|
||||
this.requestChangePassword(password1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用后端修改密码接口
|
||||
*/
|
||||
private requestChangePassword(newPassword: string): void {
|
||||
// TODO: 实现后端修改密码接口调用
|
||||
// 示例:
|
||||
// const data = {
|
||||
// email: this._email,
|
||||
// code: this._verificationCode,
|
||||
// newPassword: newPassword
|
||||
// };
|
||||
// NetworkManager.request('/api/changePassword', data, (response) => {
|
||||
// if (response.success) {
|
||||
// // 修改密码成功
|
||||
// console.log('密码修改成功');
|
||||
// // TODO: 显示成功提示
|
||||
// // 关闭当前界面
|
||||
// this.close();
|
||||
// // 可以选择跳转回登录页面
|
||||
// // ViewManager.I.openMainView('loginPanel/LoginPanel');
|
||||
// } else {
|
||||
// // 修改密码失败,显示错误信息
|
||||
// console.error('密码修改失败:', response.message);
|
||||
// // TODO: 显示错误提示
|
||||
// }
|
||||
// });
|
||||
|
||||
console.log("TODO: 实现修改密码接口调用");
|
||||
console.log("邮箱:", this._email);
|
||||
console.log("验证码:", this._verificationCode);
|
||||
console.log("新密码:", newPassword);
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击关闭按钮
|
||||
*/
|
||||
private onClickClose(): void {
|
||||
// 关闭当前界面
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "e11c6ea1-b27a-4e49-8494-baf1a534fc75",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
import { _decorator, EditBox, Label } from "cc";
|
||||
import Utils from "../../../Main/Common/Utils";
|
||||
import li_BaseView from "../../../Main/Common/li_BaseView";
|
||||
import { GButton } from "../../../Main/Common/GButton";
|
||||
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
/**
|
||||
* 注册页面
|
||||
* 预制体位于 resources/loginPanel/RegisterPanel
|
||||
*/
|
||||
@ccclass("RegisterPanel")
|
||||
export class RegisterPanel extends li_BaseView {
|
||||
private _nodeTab: any = {};
|
||||
|
||||
// 验证码倒计时
|
||||
private _countdown: number = 0;
|
||||
private _countdownTimer: any = null;
|
||||
|
||||
/**
|
||||
* 组件初始化时调用
|
||||
*/
|
||||
onLoadCT(): void {
|
||||
// 解析节点,将子节点存储到 _nodeTab 中
|
||||
Utils.parseNode(this.node, this._nodeTab);
|
||||
|
||||
// 初始化UI
|
||||
this.initUI();
|
||||
|
||||
// 注册事件监听
|
||||
this.registerListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化UI
|
||||
*/
|
||||
private initUI(): void {
|
||||
// 初始化发送按钮状态
|
||||
this.updateSendBtnState(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册事件监听
|
||||
*/
|
||||
private registerListener(): void {
|
||||
// 绑定发送验证码按钮点击事件
|
||||
if (this._nodeTab.SendBtn) {
|
||||
GButton.BandClick(this._nodeTab.SendBtn, this.onClickSendCode, this);
|
||||
}
|
||||
|
||||
// 绑定注册按钮点击事件
|
||||
if (this._nodeTab.RegisterBtn) {
|
||||
GButton.BandClick(this._nodeTab.RegisterBtn, this.onClickRegister, this);
|
||||
}
|
||||
|
||||
// 绑定关闭按钮点击事件
|
||||
if (this._nodeTab.CloseBtn) {
|
||||
GButton.BandClick(this._nodeTab.CloseBtn, this.onClickClose, this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击发送验证码按钮
|
||||
*/
|
||||
private onClickSendCode(): void {
|
||||
// 如果正在倒计时,不允许再次发送
|
||||
if (this._countdown > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取邮箱输入框
|
||||
const emailInput = this._nodeTab.EmailInput?.getComponent(EditBox);
|
||||
|
||||
if (!emailInput) {
|
||||
console.error("未找到邮箱输入框");
|
||||
return;
|
||||
}
|
||||
|
||||
const email = emailInput.string.trim();
|
||||
|
||||
// 验证邮箱
|
||||
if (!email) {
|
||||
console.log("请输入邮箱");
|
||||
// TODO: 显示提示信息
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.isValidEmail(email)) {
|
||||
console.log("请输入有效的邮箱地址");
|
||||
// TODO: 显示提示信息
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: 调用后端接口发送验证码
|
||||
console.log("发送验证码到:", email);
|
||||
this.requestSendCode(email);
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用后端接口发送验证码
|
||||
*/
|
||||
private requestSendCode(email: string): void {
|
||||
// TODO: 实现后端发送验证码接口调用
|
||||
// 示例:
|
||||
// const data = { email: email, type: 'register' };
|
||||
// NetworkManager.request('/api/sendCode', data, (response) => {
|
||||
// if (response.success) {
|
||||
// // 发送成功,开始倒计时
|
||||
// this.startCountdown();
|
||||
// } else {
|
||||
// // 发送失败,显示错误信息
|
||||
// console.error('发送验证码失败:', response.message);
|
||||
// }
|
||||
// });
|
||||
|
||||
console.log("TODO: 实现发送验证码接口调用");
|
||||
// 临时模拟发送成功,启动倒计时
|
||||
this.startCountdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始倒计时
|
||||
*/
|
||||
private startCountdown(): void {
|
||||
this._countdown = 60; // 60秒倒计时
|
||||
this.updateSendBtnState(false);
|
||||
|
||||
this._countdownTimer = setInterval(() => {
|
||||
this._countdown--;
|
||||
|
||||
if (this._countdown <= 0) {
|
||||
// 倒计时结束
|
||||
clearInterval(this._countdownTimer);
|
||||
this._countdownTimer = null;
|
||||
this.updateSendBtnState(true);
|
||||
} else {
|
||||
// 更新按钮文本
|
||||
this.updateSendBtnState(false);
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新发送按钮状态
|
||||
*/
|
||||
private updateSendBtnState(canSend: boolean): void {
|
||||
if (!this._nodeTab.SendBtn) return;
|
||||
|
||||
const label = this._nodeTab.SendBtn.getComponentInChildren(Label);
|
||||
if (label) {
|
||||
if (canSend) {
|
||||
label.string = "发送验证码";
|
||||
} else {
|
||||
label.string = `${this._countdown}秒后重试`;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: 可以设置按钮的可交互状态
|
||||
// const button = this._nodeTab.SendBtn.getComponent(Button);
|
||||
// if (button) {
|
||||
// button.interactable = canSend;
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击注册按钮
|
||||
*/
|
||||
private onClickRegister(): void {
|
||||
// 获取输入框
|
||||
const emailInput = this._nodeTab.EmailInput?.getComponent(EditBox);
|
||||
const passwordInput = this._nodeTab.PasswordInput?.getComponent(EditBox);
|
||||
const codeInput = this._nodeTab.CodeInput?.getComponent(EditBox);
|
||||
|
||||
if (!emailInput || !passwordInput || !codeInput) {
|
||||
console.error("未找到输入框");
|
||||
return;
|
||||
}
|
||||
|
||||
const email = emailInput.string.trim();
|
||||
const password = passwordInput.string.trim();
|
||||
const code = codeInput.string.trim();
|
||||
|
||||
// 验证输入
|
||||
if (!email) {
|
||||
console.log("请输入邮箱");
|
||||
// TODO: 显示提示信息
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.isValidEmail(email)) {
|
||||
console.log("请输入有效的邮箱地址");
|
||||
// TODO: 显示提示信息
|
||||
return;
|
||||
}
|
||||
|
||||
if (!password) {
|
||||
console.log("请输入密码");
|
||||
// TODO: 显示提示信息
|
||||
return;
|
||||
}
|
||||
|
||||
if (password.length < 6) {
|
||||
console.log("密码长度不能少于6位");
|
||||
// TODO: 显示提示信息
|
||||
return;
|
||||
}
|
||||
|
||||
if (!code) {
|
||||
console.log("请输入验证码");
|
||||
// TODO: 显示提示信息
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: 调用后端接口进行注册
|
||||
console.log("注册:", email, password, code);
|
||||
this.requestRegister(email, password, code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用后端注册接口
|
||||
*/
|
||||
private requestRegister(email: string, password: string, code: string): void {
|
||||
// TODO: 实现后端注册接口调用
|
||||
// 示例:
|
||||
// const data = {
|
||||
// email: email,
|
||||
// password: password,
|
||||
// code: code
|
||||
// };
|
||||
// NetworkManager.request('/api/register', data, (response) => {
|
||||
// if (response.success) {
|
||||
// // 注册成功
|
||||
// console.log('注册成功');
|
||||
// // 关闭注册界面
|
||||
// this.close();
|
||||
// } else {
|
||||
// // 注册失败,显示错误信息
|
||||
// console.error('注册失败:', response.message);
|
||||
// }
|
||||
// });
|
||||
|
||||
console.log("TODO: 实现注册接口调用");
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击关闭按钮
|
||||
*/
|
||||
private onClickClose(): void {
|
||||
// 清理倒计时定时器
|
||||
if (this._countdownTimer) {
|
||||
clearInterval(this._countdownTimer);
|
||||
this._countdownTimer = null;
|
||||
}
|
||||
|
||||
// 关闭当前界面
|
||||
this.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证邮箱格式
|
||||
*/
|
||||
private isValidEmail(email: string): boolean {
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
return emailRegex.test(email);
|
||||
}
|
||||
|
||||
/**
|
||||
* 界面销毁时调用
|
||||
*/
|
||||
protected onDestroy(): void {
|
||||
// 清理倒计时定时器
|
||||
if (this._countdownTimer) {
|
||||
clearInterval(this._countdownTimer);
|
||||
this._countdownTimer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "565b780d-f431-4e60-aa02-73df95d28a88",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,279 @@
|
||||
import { _decorator, EditBox, Label } from "cc";
|
||||
import Utils from "../../../Main/Common/Utils";
|
||||
import li_BaseView from "../../../Main/Common/li_BaseView";
|
||||
import { GButton } from "../../../Main/Common/GButton";
|
||||
import { ViewManager } from "../../../Main/Manager/ViewManager";
|
||||
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
/**
|
||||
* 安全验证页面
|
||||
* 预制体位于 resources/loginPanel/SafeCheckPanel
|
||||
*/
|
||||
@ccclass("SafeCheckPanel")
|
||||
export class SafeCheckPanel extends li_BaseView {
|
||||
private _nodeTab: any = {};
|
||||
|
||||
// 验证码倒计时
|
||||
private _countdown: number = 0;
|
||||
private _countdownTimer: any = null;
|
||||
|
||||
/**
|
||||
* 组件初始化时调用
|
||||
*/
|
||||
onLoadCT(): void {
|
||||
// 解析节点,将子节点存储到 _nodeTab 中
|
||||
Utils.parseNode(this.node, this._nodeTab);
|
||||
|
||||
// 初始化UI
|
||||
this.initUI();
|
||||
|
||||
// 注册事件监听
|
||||
this.registerListener();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化UI
|
||||
*/
|
||||
private initUI(): void {
|
||||
// 初始化发送按钮状态
|
||||
this.updateSendBtnState(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册事件监听
|
||||
*/
|
||||
private registerListener(): void {
|
||||
// 绑定发送验证码按钮点击事件
|
||||
if (this._nodeTab.SendBtn) {
|
||||
GButton.BandClick(this._nodeTab.SendBtn, this.onClickSendCode, this);
|
||||
}
|
||||
|
||||
// 绑定确定按钮点击事件
|
||||
if (this._nodeTab.ConfirmBtn) {
|
||||
GButton.BandClick(this._nodeTab.ConfirmBtn, this.onClickConfirm, this);
|
||||
}
|
||||
|
||||
// 绑定关闭按钮点击事件
|
||||
if (this._nodeTab.CloseBtn) {
|
||||
GButton.BandClick(this._nodeTab.CloseBtn, this.onClickClose, this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击发送验证码按钮
|
||||
*/
|
||||
private onClickSendCode(): void {
|
||||
// 如果正在倒计时,不允许再次发送
|
||||
if (this._countdown > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取邮箱输入框
|
||||
const emailInput = this._nodeTab.EmailInput?.getComponent(EditBox);
|
||||
|
||||
if (!emailInput) {
|
||||
console.error("未找到邮箱输入框");
|
||||
return;
|
||||
}
|
||||
|
||||
const email = emailInput.string.trim();
|
||||
|
||||
// 验证邮箱
|
||||
if (!email) {
|
||||
console.log("请输入邮箱");
|
||||
// TODO: 显示提示信息
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.isValidEmail(email)) {
|
||||
console.log("请输入有效的邮箱地址");
|
||||
// TODO: 显示提示信息
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: 调用后端接口发送验证码
|
||||
console.log("发送验证码到:", email);
|
||||
this.requestSendCode(email);
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用后端接口发送验证码
|
||||
*/
|
||||
private requestSendCode(email: string): void {
|
||||
// TODO: 实现后端发送验证码接口调用
|
||||
// 示例:
|
||||
// const data = { email: email, type: 'forgetPassword' };
|
||||
// NetworkManager.request('/api/sendCode', data, (response) => {
|
||||
// if (response.success) {
|
||||
// // 发送成功,开始倒计时
|
||||
// this.startCountdown();
|
||||
// } else {
|
||||
// // 发送失败,显示错误信息
|
||||
// console.error('发送验证码失败:', response.message);
|
||||
// }
|
||||
// });
|
||||
|
||||
console.log("TODO: 实现发送验证码接口调用");
|
||||
// 临时模拟发送成功,启动倒计时
|
||||
this.startCountdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始倒计时
|
||||
*/
|
||||
private startCountdown(): void {
|
||||
this._countdown = 60; // 60秒倒计时
|
||||
this.updateSendBtnState(false);
|
||||
|
||||
this._countdownTimer = setInterval(() => {
|
||||
this._countdown--;
|
||||
|
||||
if (this._countdown <= 0) {
|
||||
// 倒计时结束
|
||||
clearInterval(this._countdownTimer);
|
||||
this._countdownTimer = null;
|
||||
this.updateSendBtnState(true);
|
||||
} else {
|
||||
// 更新按钮文本
|
||||
this.updateSendBtnState(false);
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新发送按钮状态
|
||||
*/
|
||||
private updateSendBtnState(canSend: boolean): void {
|
||||
if (!this._nodeTab.SendBtn) return;
|
||||
|
||||
const label = this._nodeTab.SendBtn.getComponentInChildren(Label);
|
||||
if (label) {
|
||||
if (canSend) {
|
||||
label.string = "发送验证码";
|
||||
} else {
|
||||
label.string = `${this._countdown}秒后重试`;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: 可以设置按钮的可交互状态
|
||||
// const button = this._nodeTab.SendBtn.getComponent(Button);
|
||||
// if (button) {
|
||||
// button.interactable = canSend;
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击确定按钮
|
||||
*/
|
||||
private onClickConfirm(): void {
|
||||
// 获取邮箱和验证码输入框
|
||||
const emailInput = this._nodeTab.EmailInput?.getComponent(EditBox);
|
||||
const codeInput = this._nodeTab.CodeInput?.getComponent(EditBox);
|
||||
|
||||
if (!emailInput || !codeInput) {
|
||||
console.error("未找到邮箱或验证码输入框");
|
||||
return;
|
||||
}
|
||||
|
||||
const email = emailInput.string.trim();
|
||||
const code = codeInput.string.trim();
|
||||
|
||||
// 验证输入
|
||||
if (!email) {
|
||||
console.log("请输入邮箱");
|
||||
// TODO: 显示提示信息
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.isValidEmail(email)) {
|
||||
console.log("请输入有效的邮箱地址");
|
||||
// TODO: 显示提示信息
|
||||
return;
|
||||
}
|
||||
|
||||
if (!code) {
|
||||
console.log("请输入验证码");
|
||||
// TODO: 显示提示信息
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: 调用后端接口验证验证码
|
||||
console.log("验证验证码:", email, code);
|
||||
this.requestVerifyCode(email, code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用后端接口验证验证码
|
||||
*/
|
||||
private requestVerifyCode(email: string, code: string): void {
|
||||
// TODO: 实现后端验证验证码接口调用
|
||||
// 示例:
|
||||
// const data = {
|
||||
// email: email,
|
||||
// code: code,
|
||||
// type: 'forgetPassword'
|
||||
// };
|
||||
// NetworkManager.request('/api/verifyCode', data, (response) => {
|
||||
// if (response.success) {
|
||||
// // 验证成功,跳转到修改密码页面
|
||||
// this.openNewPasswordPanel(email, code);
|
||||
// } else {
|
||||
// // 验证失败,显示错误信息
|
||||
// console.error('验证码错误:', response.message);
|
||||
// // TODO: 显示错误提示
|
||||
// }
|
||||
// });
|
||||
|
||||
console.log("TODO: 实现验证验证码接口调用");
|
||||
// 临时模拟验证成功,跳转到修改密码页面
|
||||
this.openNewPasswordPanel(email, code);
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开修改密码页面
|
||||
*/
|
||||
private openNewPasswordPanel(email: string, code: string): void {
|
||||
// 关闭当前页面
|
||||
this.close();
|
||||
|
||||
// 打开修改密码页面,并传递邮箱和验证码信息
|
||||
ViewManager.I.openMainView("loginPanel/NewPasswordPanel", {
|
||||
email: email,
|
||||
code: code,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击关闭按钮
|
||||
*/
|
||||
private onClickClose(): void {
|
||||
// 清理倒计时定时器
|
||||
if (this._countdownTimer) {
|
||||
clearInterval(this._countdownTimer);
|
||||
this._countdownTimer = null;
|
||||
}
|
||||
|
||||
// 关闭当前界面
|
||||
this.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证邮箱格式
|
||||
*/
|
||||
private isValidEmail(email: string): boolean {
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
return emailRegex.test(email);
|
||||
}
|
||||
|
||||
/**
|
||||
* 界面销毁时调用
|
||||
*/
|
||||
protected onDestroy(): void {
|
||||
// 清理倒计时定时器
|
||||
if (this._countdownTimer) {
|
||||
clearInterval(this._countdownTimer);
|
||||
this._countdownTimer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "d3dfdbed-8fb1-4348-b9d4-32c6b9406310",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
"ver": "1.1.50",
|
||||
"importer": "prefab",
|
||||
"imported": true,
|
||||
"uuid": "6972298a-8553-4fe8-8296-06f6d886d450",
|
||||
"uuid": "aa097cc9-b234-4077-8b2e-e543767ca13f",
|
||||
"files": [
|
||||
".json"
|
||||
],
|
||||
|
||||
@@ -27,18 +27,21 @@
|
||||
],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 154
|
||||
},
|
||||
{
|
||||
"__id__": 156
|
||||
},
|
||||
{
|
||||
"__id__": 158
|
||||
},
|
||||
{
|
||||
"__id__": 160
|
||||
},
|
||||
{
|
||||
"__id__": 162
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 160
|
||||
"__id__": 164
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
@@ -284,23 +287,23 @@
|
||||
"__id__": 121
|
||||
},
|
||||
{
|
||||
"__id__": 133
|
||||
"__id__": 135
|
||||
},
|
||||
{
|
||||
"__id__": 141
|
||||
"__id__": 143
|
||||
}
|
||||
],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 149
|
||||
"__id__": 151
|
||||
},
|
||||
{
|
||||
"__id__": 151
|
||||
"__id__": 153
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 153
|
||||
"__id__": 155
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
@@ -3074,10 +3077,13 @@
|
||||
},
|
||||
{
|
||||
"__id__": 130
|
||||
},
|
||||
{
|
||||
"__id__": 132
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 132
|
||||
"__id__": 134
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
@@ -3343,6 +3349,62 @@
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "e1FEs4AnFF84EGMms/npks"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Button",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 121
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 133
|
||||
},
|
||||
"clickEvents": [],
|
||||
"_interactable": true,
|
||||
"_transition": 0,
|
||||
"_normalColor": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 255,
|
||||
"g": 255,
|
||||
"b": 255,
|
||||
"a": 255
|
||||
},
|
||||
"_hoverColor": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 211,
|
||||
"g": 211,
|
||||
"b": 211,
|
||||
"a": 255
|
||||
},
|
||||
"_pressedColor": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 255,
|
||||
"g": 255,
|
||||
"b": 255,
|
||||
"a": 255
|
||||
},
|
||||
"_disabledColor": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 124,
|
||||
"g": 124,
|
||||
"b": 124,
|
||||
"a": 255
|
||||
},
|
||||
"_normalSprite": null,
|
||||
"_hoverSprite": null,
|
||||
"_pressedSprite": null,
|
||||
"_disabledSprite": null,
|
||||
"_duration": 0.1,
|
||||
"_zoomScale": 1.2,
|
||||
"_target": null,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "36gJ21lkFNkIiRuVYHtlnX"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInfo",
|
||||
"root": {
|
||||
@@ -3367,18 +3429,18 @@
|
||||
"_children": [],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 134
|
||||
},
|
||||
{
|
||||
"__id__": 136
|
||||
},
|
||||
{
|
||||
"__id__": 138
|
||||
},
|
||||
{
|
||||
"__id__": 140
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 140
|
||||
"__id__": 142
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
@@ -3415,11 +3477,11 @@
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 133
|
||||
"__id__": 135
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 135
|
||||
"__id__": 137
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
@@ -3443,11 +3505,11 @@
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 133
|
||||
"__id__": 135
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 137
|
||||
"__id__": 139
|
||||
},
|
||||
"_customMaterial": null,
|
||||
"_srcBlendFactor": 2,
|
||||
@@ -3488,11 +3550,11 @@
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 133
|
||||
"__id__": 135
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 139
|
||||
"__id__": 141
|
||||
},
|
||||
"clickEvents": [],
|
||||
"_interactable": true,
|
||||
@@ -3562,18 +3624,18 @@
|
||||
"_children": [],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 142
|
||||
},
|
||||
{
|
||||
"__id__": 144
|
||||
},
|
||||
{
|
||||
"__id__": 146
|
||||
},
|
||||
{
|
||||
"__id__": 148
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 148
|
||||
"__id__": 150
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
@@ -3610,11 +3672,11 @@
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 141
|
||||
"__id__": 143
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 143
|
||||
"__id__": 145
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
@@ -3638,11 +3700,11 @@
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 141
|
||||
"__id__": 143
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 145
|
||||
"__id__": 147
|
||||
},
|
||||
"_customMaterial": null,
|
||||
"_srcBlendFactor": 2,
|
||||
@@ -3709,11 +3771,11 @@
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 141
|
||||
"__id__": 143
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 147
|
||||
"__id__": 149
|
||||
},
|
||||
"clickEvents": [],
|
||||
"_interactable": true,
|
||||
@@ -3782,7 +3844,7 @@
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 150
|
||||
"__id__": 152
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
@@ -3810,7 +3872,7 @@
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 152
|
||||
"__id__": 154
|
||||
},
|
||||
"_customMaterial": null,
|
||||
"_srcBlendFactor": 2,
|
||||
@@ -3868,7 +3930,7 @@
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 155
|
||||
"__id__": 157
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
@@ -3896,7 +3958,7 @@
|
||||
},
|
||||
"_enabled": false,
|
||||
"__prefab": {
|
||||
"__id__": 157
|
||||
"__id__": 159
|
||||
},
|
||||
"_customMaterial": null,
|
||||
"_srcBlendFactor": 2,
|
||||
@@ -3941,7 +4003,7 @@
|
||||
},
|
||||
"_enabled": false,
|
||||
"__prefab": {
|
||||
"__id__": 159
|
||||
"__id__": 161
|
||||
},
|
||||
"_type": 3,
|
||||
"_inverted": false,
|
||||
@@ -3953,6 +4015,25 @@
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "ccqvpyXtxAKoDFDkk+CXDL"
|
||||
},
|
||||
{
|
||||
"__type__": "ce7e3FnjthOXJIbDJGurzbE",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 163
|
||||
},
|
||||
"m_rootNode": null,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "d5Jg3zVgVPlKq3fn8Mi7K2"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInfo",
|
||||
"root": {
|
||||
@@ -3962,6 +4043,7 @@
|
||||
"__id__": 0
|
||||
},
|
||||
"fileId": "06liSCoLBIbI3C6sNktTBJ",
|
||||
"instance": null,
|
||||
"targetOverrides": null
|
||||
}
|
||||
]
|
||||
@@ -35,10 +35,13 @@
|
||||
},
|
||||
{
|
||||
"__id__": 132
|
||||
},
|
||||
{
|
||||
"__id__": 134
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 134
|
||||
"__id__": 136
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
@@ -3274,6 +3277,25 @@
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "16wyEMuj1Meq5zmjtv4o5c"
|
||||
},
|
||||
{
|
||||
"__type__": "e11c66hsnpOSYSUuvGlNPx1",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 135
|
||||
},
|
||||
"m_rootNode": null,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "b9CUMt3LlG0J8Jsuq+d3u5"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInfo",
|
||||
"root": {
|
||||
@@ -3283,6 +3305,7 @@
|
||||
"__id__": 0
|
||||
},
|
||||
"fileId": "e8L1H16d9HP6FYp51BeRWn",
|
||||
"instance": null,
|
||||
"targetOverrides": null
|
||||
}
|
||||
]
|
||||
@@ -35,10 +35,13 @@
|
||||
},
|
||||
{
|
||||
"__id__": 204
|
||||
},
|
||||
{
|
||||
"__id__": 206
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 206
|
||||
"__id__": 208
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
@@ -5101,6 +5104,25 @@
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "d3J11kwgJNxr/AEbd2kVpm"
|
||||
},
|
||||
{
|
||||
"__type__": "565b7gN9DFOYKoCc9+V0oqI",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 207
|
||||
},
|
||||
"m_rootNode": null,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "335TfMiNxP2bYMZhXg1isT"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInfo",
|
||||
"root": {
|
||||
@@ -5110,6 +5132,7 @@
|
||||
"__id__": 0
|
||||
},
|
||||
"fileId": "72g0/xfadLzKbZU8hLeUmn",
|
||||
"instance": null,
|
||||
"targetOverrides": null
|
||||
}
|
||||
]
|
||||
@@ -35,10 +35,13 @@
|
||||
},
|
||||
{
|
||||
"__id__": 158
|
||||
},
|
||||
{
|
||||
"__id__": 160
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 160
|
||||
"__id__": 162
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
@@ -3962,6 +3965,25 @@
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "beWC4jbyNGzplzxhBUPZzq"
|
||||
},
|
||||
{
|
||||
"__type__": "d3dfdvtj7FDSLnUMsa5QGMQ",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 161
|
||||
},
|
||||
"m_rootNode": null,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "36C8lniCNDfLQLX2kQVYKP"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInfo",
|
||||
"root": {
|
||||
@@ -3971,6 +3993,7 @@
|
||||
"__id__": 0
|
||||
},
|
||||
"fileId": "342wdtF7JC273lhsG3dRQw",
|
||||
"instance": null,
|
||||
"targetOverrides": null
|
||||
}
|
||||
]
|
||||
+1
-1
Submodule proto_cs updated: 777dbf9977...ac9f5df0b3
+1
-1
Submodule xchat_cfg updated: b84eb4476a...d2c7978a50
Reference in New Issue
Block a user