Commit 6dcdd00f authored by 李维's avatar 李维

feat: 显示加载进度

parent 4f4d5ad9
{
"ver": "1.1.0",
"uuid": "63b4e75f-857e-4577-9e2d-c86d4c05f53a",
"subMetas": {}
}
\ No newline at end of file
{
"ver": "1.0.1",
"uuid": "4251bacf-3f68-475f-b3b3-990fdbfc3991",
"subMetas": {}
}
\ No newline at end of file
# 游戏中心进度条功能说明
## 功能概述
为游戏中心页面添加了进度条功能,在调用`loadPageBundle`加载游戏资源时显示进度条,加载完成后自动隐藏。
## 主要特性
- 自动创建进度条UI组件
- 实时显示加载进度
- 支持通过属性面板自定义进度条样式
- 包含模拟进度功能作为备用方案
- 自动重写middleLayer组件的进度更新方法
## 使用方法
### 1. 自动创建进度条
进度条会在页面初始化时自动创建,无需手动配置。
### 2. 通过属性面板自定义
如果需要在编辑器中自定义进度条样式,可以在属性面板中设置以下属性:
- `progressBarContainer`: 进度条容器节点
- `progressBar`: 进度条组件
- `progressLabel`: 进度文本标签
### 3. 进度条显示时机
- 当用户点击游戏卡片时自动显示
-`loadPageBundle`调用期间保持显示
- 加载完成后自动隐藏
## 技术实现
### 进度条组件结构
```
progress_bar_container (容器)
├── bg_mask (背景遮罩)
├── loading_label (加载提示文本)
├── progress_bg (进度条背景)
├── progress_bar (进度条)
└── progress_label (进度百分比文本)
```
### 关键方法
- `showProgressBar()`: 显示进度条
- `hideProgressBar()`: 隐藏进度条
- `updateProgressBar(progress)`: 更新进度值
- `overrideProgressUpdate()`: 重写middleLayer的进度更新方法
- `startSimulatedProgress()`: 启动模拟进度更新
- `stopSimulatedProgress()`: 停止模拟进度更新
### 进度更新机制
1. **实际进度更新**: 通过重写middleLayer组件的`setLoadingProgressBar`方法
2. **模拟进度更新**: 作为备用方案,确保用户能看到进度变化
3. **自动隐藏**: 在`loadPageBundle`回调中自动隐藏进度条
## 样式配置
- 进度条容器尺寸: 400x120
- 进度条尺寸: 300x20
- 背景遮罩: 半透明黑色
- 进度条颜色: 蓝色
- 文本颜色: 白色
## 注意事项
1. 进度条会在页面初始化时自动创建
2. 模拟进度最多显示到90%,留10%给实际加载完成
3. 如果middleLayer组件没有正确调用进度更新,模拟进度会作为备用方案
4. 进度条会在加载完成后自动清理和隐藏
## 扩展功能
如需添加更多功能,可以考虑:
- 添加取消加载按钮
- 显示预计剩余时间
- 添加加载失败重试机制
- 自定义进度条动画效果
\ No newline at end of file
{
"ver": "2.0.0",
"uuid": "5952eb33-865c-4e39-b156-cd2f1c4ff5a0",
"subMetas": {}
}
\ No newline at end of file
......@@ -82,18 +82,24 @@
},
{
"__id__": 16
},
{
"__id__": 26
},
{
"__id__": 29
}
],
"_active": true,
"_components": [
{
"__id__": 26
"__id__": 34
},
{
"__id__": 27
"__id__": 35
},
{
"__id__": 28
"__id__": 36
}
],
"_prefab": null,
......@@ -1174,6 +1180,367 @@
"_originalHeight": 0,
"_id": "206/llzq5AuIAFBUoktUtK"
},
{
"__type__": "cc.Node",
"_name": "laodingBg",
"_objFlags": 0,
"_parent": {
"__id__": 2
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 27
},
{
"__id__": 28
}
],
"_prefab": null,
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 248,
"g": 246,
"b": 239,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 1280,
"height": 720
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
0,
0,
0,
0,
0,
0,
1,
1,
1,
1
]
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": "90K4JHD7NEaaU5SKwzX44I"
},
{
"__type__": "cc.Sprite",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 26
},
"_enabled": true,
"_materials": [
{
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
}
],
"_srcBlendFactor": 770,
"_dstBlendFactor": 771,
"_spriteFrame": {
"__uuid__": "a23235d1-15db-4b95-8439-a2e005bfff91"
},
"_type": 0,
"_sizeMode": 0,
"_fillType": 0,
"_fillCenter": {
"__type__": "cc.Vec2",
"x": 0,
"y": 0
},
"_fillStart": 0,
"_fillRange": 0,
"_isTrimmedMode": true,
"_atlas": null,
"_id": "50c3gM7ZpL5JfwBWnMQlp6"
},
{
"__type__": "cc.Widget",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 26
},
"_enabled": true,
"alignMode": 1,
"_target": null,
"_alignFlags": 45,
"_left": 0,
"_right": 0,
"_top": 0,
"_bottom": 0,
"_verticalCenter": 0,
"_horizontalCenter": 0,
"_isAbsLeft": true,
"_isAbsRight": true,
"_isAbsTop": true,
"_isAbsBottom": true,
"_isAbsHorizontalCenter": true,
"_isAbsVerticalCenter": true,
"_originalWidth": 1920,
"_originalHeight": 1080,
"_id": "d0SrckxAlP5oOCX5LRLmD4"
},
{
"__type__": "cc.Node",
"_name": "progress_bar_container",
"_objFlags": 0,
"_parent": {
"__id__": 2
},
"_children": [
{
"__id__": 30
},
{
"__id__": 32
}
],
"_active": true,
"_components": [],
"_prefab": null,
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 1000,
"height": 50
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
0,
0,
0,
0,
0,
0,
1,
1,
1,
1
]
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": "f4bE2egm1L+LbM4gBAREiT"
},
{
"__type__": "cc.Node",
"_name": "progress_bar",
"_objFlags": 0,
"_parent": {
"__id__": 29
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 31
}
],
"_prefab": null,
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 255,
"g": 255,
"b": 255,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 1000,
"height": 50
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
0,
0,
0,
0,
0,
0,
1,
1,
1,
1
]
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": "e9N+9yzeFFAadd0iuJD/d8"
},
{
"__type__": "cc.ProgressBar",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 30
},
"_enabled": true,
"_N$totalLength": 100,
"_N$barSprite": null,
"_N$mode": 0,
"_N$progress": 1,
"_N$reverse": false,
"_id": "3fZpJNbOBLaZ9zVt4q4IpX"
},
{
"__type__": "cc.Node",
"_name": "progress_label",
"_objFlags": 0,
"_parent": {
"__id__": 29
},
"_children": [],
"_active": true,
"_components": [
{
"__id__": 33
}
],
"_prefab": null,
"_opacity": 255,
"_color": {
"__type__": "cc.Color",
"r": 0,
"g": 0,
"b": 0,
"a": 255
},
"_contentSize": {
"__type__": "cc.Size",
"width": 1000,
"height": 50.4
},
"_anchorPoint": {
"__type__": "cc.Vec2",
"x": 0.5,
"y": 0.5
},
"_trs": {
"__type__": "TypedArray",
"ctor": "Float64Array",
"array": [
0,
0,
0,
0,
0,
0,
1,
1,
1,
1
]
},
"_eulerAngles": {
"__type__": "cc.Vec3",
"x": 0,
"y": 0,
"z": 0
},
"_skewX": 0,
"_skewY": 0,
"_is3DNode": false,
"_groupIndex": 0,
"groupIndex": 0,
"_id": "55WpQPpihPN7YgDwbwMvKT"
},
{
"__type__": "cc.Label",
"_name": "",
"_objFlags": 0,
"node": {
"__id__": 32
},
"_enabled": true,
"_materials": [
{
"__uuid__": "eca5d2f2-8ef6-41c2-bbe6-f9c79d09c432"
}
],
"_srcBlendFactor": 770,
"_dstBlendFactor": 771,
"_string": "",
"_N$string": "",
"_fontSize": 40,
"_lineHeight": 40,
"_enableWrapText": true,
"_N$file": null,
"_isSystemFontUsed": true,
"_spacingX": 0,
"_batchAsBitmap": false,
"_styleFlags": 0,
"_underlineHeight": 0,
"_N$horizontalAlign": 0,
"_N$verticalAlign": 0,
"_N$fontFamily": "Arial",
"_N$overflow": 0,
"_N$cacheMode": 0,
"_id": "80m6FkQqpBEawmhRv+a78k"
},
{
"__type__": "cc.Canvas",
"_name": "",
......@@ -1235,6 +1602,15 @@
"scrollView": {
"__id__": 24
},
"progressBarContainer": {
"__id__": 29
},
"progressBar": {
"__id__": 31
},
"progressLabel": {
"__id__": 33
},
"_id": "36tZootWRFMaA7LPmJ+XR/"
}
]
\ No newline at end of file
......@@ -28,6 +28,16 @@ export default class GameCenter extends cc.Component {
@property(cc.ScrollView)
scrollView: cc.ScrollView = null;
// 进度条相关属性
@property(cc.Node)
progressBarContainer: cc.Node = null;
@property(cc.ProgressBar)
progressBar: cc.ProgressBar = null;
@property(cc.Label)
progressLabel: cc.Label = null;
private gameDataList: GameData[] = [];
// LIFE-CYCLE CALLBACKS:
......@@ -88,11 +98,155 @@ export default class GameCenter extends cc.Component {
}
}
// 初始化进度条组件
this.initProgressBar();
console.log('=== 初始化组件完成 ===');
console.log('gameListContainer:', this.gameListContainer);
console.log('scrollView:', this.scrollView);
}
private initProgressBar() {
// 如果没有通过属性面板设置,则通过代码查找
if (!this.progressBarContainer) {
this.progressBarContainer = this.node.getChildByName('progress_bar_container');
}
if (!this.progressBar) {
const progressBarNode = this.progressBarContainer?.getChildByName('progress_bar');
if (progressBarNode) {
this.progressBar = progressBarNode.getComponent(cc.ProgressBar);
}
}
if (!this.progressLabel) {
const progressLabelNode = this.progressBarContainer?.getChildByName('progress_label');
if (progressLabelNode) {
this.progressLabel = progressLabelNode.getComponent(cc.Label);
}
}
// 如果进度条容器不存在,则创建一个
if (!this.progressBarContainer) {
this.createProgressBar();
}
// 初始时隐藏进度条
this.hideProgressBar();
}
private createProgressBar() {
// 创建进度条容器
this.progressBarContainer = new cc.Node('progress_bar_container');
this.node.addChild(this.progressBarContainer);
// 设置进度条容器位置和大小
this.progressBarContainer.setPosition(0, 0);
this.progressBarContainer.width = 400;
this.progressBarContainer.height = 120;
// 创建背景遮罩
const bgMask = new cc.Node('bg_mask');
this.progressBarContainer.addChild(bgMask);
const bgSprite = bgMask.addComponent(cc.Sprite);
bgMask.color = cc.Color.BLACK;
bgMask.opacity = 150;
bgMask.width = 400;
bgMask.height = 120;
// 创建加载提示文本
const loadingLabel = new cc.Node('loading_label');
this.progressBarContainer.addChild(loadingLabel);
const loadingLabelComp = loadingLabel.addComponent(cc.Label);
loadingLabelComp.string = '正在加载游戏资源...';
loadingLabelComp.fontSize = 18;
loadingLabelComp.node.color = cc.Color.WHITE;
loadingLabel.setPosition(0, 40);
// 创建进度条背景
const progressBg = new cc.Node('progress_bg');
this.progressBarContainer.addChild(progressBg);
const progressBgSprite = progressBg.addComponent(cc.Sprite);
progressBg.color = cc.Color.GRAY;
progressBg.width = 300;
progressBg.height = 20;
progressBg.setPosition(0, 0);
// 创建进度条
const progressBarNode = new cc.Node('progress_bar');
this.progressBarContainer.addChild(progressBarNode);
this.progressBar = progressBarNode.addComponent(cc.ProgressBar);
progressBarNode.color = cc.Color.BLUE;
progressBarNode.width = 300;
progressBarNode.height = 20;
progressBarNode.setPosition(0, 0);
// 设置进度条属性
this.progressBar.progress = 0;
this.progressBar.barSprite = progressBarNode.getComponent(cc.Sprite);
// 创建进度文本
const progressLabelNode = new cc.Node('progress_label');
this.progressBarContainer.addChild(progressLabelNode);
this.progressLabel = progressLabelNode.addComponent(cc.Label);
this.progressLabel.string = '0%';
this.progressLabel.fontSize = 16;
this.progressLabel.node.color = cc.Color.WHITE;
progressLabelNode.setPosition(0, -30);
console.log('进度条组件创建完成');
}
// 显示进度条
private showProgressBar() {
cc.find("Canvas/laodingBg").active = true;
if (this.progressBarContainer) {
this.progressBarContainer.active = true;
console.log('进度条已显示');
}
}
// 隐藏进度条
private hideProgressBar() {
cc.find("Canvas/laodingBg").active = false;
if (this.progressBarContainer) {
this.progressBarContainer.active = false;
console.log('进度条已隐藏');
}
}
// 更新进度条
private updateProgressBar(progress: number) {
if (this.progressBar && this.progressLabel) {
this.progressBar.progress = progress / 100;
this.progressLabel.string = `${Math.floor(progress)}%`;
console.log(`进度条更新: ${progress}%`);
}
}
// 模拟进度更新(作为备用方案)
private simulatedProgressInterval: number = null;
private currentSimulatedProgress: number = 0;
private startSimulatedProgress() {
this.currentSimulatedProgress = 0;
this.simulatedProgressInterval = setInterval(() => {
if (this.currentSimulatedProgress < 90) { // 最多到90%,留10%给实际加载完成
this.currentSimulatedProgress += Math.random() * 10;
this.updateProgressBar(this.currentSimulatedProgress);
}
}, 200);
console.log('模拟进度更新已启动');
}
private stopSimulatedProgress() {
if (this.simulatedProgressInterval) {
clearInterval(this.simulatedProgressInterval);
this.simulatedProgressInterval = null;
console.log('模拟进度更新已停止');
}
}
getGameList() {
console.log('=== 开始获取游戏列表 ===');
const course_id = 39657;
......@@ -317,19 +471,50 @@ export default class GameCenter extends cc.Component {
if (middleLayerComp && typeof middleLayerComp.loadPageBundle === 'function') {
console.log("loadPageBundle");
console.log(gameData);
// 显示进度条
this.showProgressBar();
this.updateProgressBar(0);
// 重写middleLayer的进度更新方法,以便监听进度
this.overrideProgressUpdate(middleLayerComp);
// 启动模拟进度更新(作为备用方案)
this.startSimulatedProgress();
middleLayerComp.setCourseData(JSON.parse(gameData.data));
middleLayerComp.loadPageBundle(gameData,()=>{
middleLayerComp.loadPageBundle(gameData, () => {
console.log('loadPageBundle success');
// 加载完成,隐藏进度条
this.stopSimulatedProgress();
this.hideProgressBar();
});
middleLayerComp.showCloseGameBtn();
} else {
console.error('middleLayer 组件未找到或 handleSubSceneEvent 方法不存在');
}
} else {
console.error('middleLayer 节点未找到');
}
}
// 重写middleLayer的进度更新方法
private overrideProgressUpdate(middleLayerComp: any) {
// 保存原始的setLoadingProgressBar方法
const originalSetLoadingProgressBar = middleLayerComp.setLoadingProgressBar;
// 重写setLoadingProgressBar方法
middleLayerComp.setLoadingProgressBar = (progress: number) => {
console.log('进度更新:', progress);
// 更新我们的进度条
this.updateProgressBar(progress);
// 调用原始方法(如果存在)
if (originalSetLoadingProgressBar) {
originalSetLoadingProgressBar.call(middleLayerComp, progress);
}
};
console.log('进度更新方法已重写');
}
onClickBack() {
......
......@@ -482,17 +482,16 @@ export default class middleLayer extends cc.Component {
sceneName,
null,
(finish, total, item) => {
// this.setLoadingProgressBar(Math.floor(finish / total * 100));
this.setLoadingProgressBar(Math.floor(finish / total * 100));
},
(err, scene) => {
cc.director.runScene(scene, null, () => {
console.log("sceneName1 = " + sceneName);
// const canvas = cc.find("Canvas");
const middleLayer = cc.find("middleLayer");
middleLayer.getComponent(cc.Widget).updateAlignment();
// middleLayer.scale = canvas.width / middleLayer.width;
this.showCloseGameBtn();
callback && callback();
});
}
......@@ -534,8 +533,15 @@ export default class middleLayer extends cc.Component {
closeGameBtn.active = false;
}
// 设置加载进度条
setLoadingProgressBar(progress: number) {
console.log('middleLayer setLoadingProgressBar:', progress);
// 这个方法会被gamecenter组件重写,用于更新进度条
}
onExitGame() {
this.hideCloseGameBtn();
cc.audioEngine.stopAll();
cc.director.loadScene("gamecenter");
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment