Files
18xchat/assets/Scripts/Sub/UI/PreloadUI.ts
T
2025-10-16 11:19:07 +08:00

431 lines
13 KiB
TypeScript

import {
_decorator,
AssetManager,
AudioClip,
BufferAsset,
Button,
Component,
ImageAsset,
instantiate,
JsonAsset,
Label,
Material,
Node,
Prefab,
ProgressBar,
Sprite,
SpriteFrame,
sys,
Vec3,
VideoPlayer,
} from "cc";
import { GButton } from "../../Main/Common/GButton";
import ResManager from "../../Main/Manager/ResManager";
import { SDKManager } from "../../Main/Channel/SDKManager";
import HttpUnit from "../../Main/Common/HttpUnit";
import GlobalValue from "../../Main/Common/GlobalValue";
import Utils from "../../Main/Common/Utils";
import { InnerMsgCode } from "../../Main/Config/InnerMsgCode";
import { promptItem } from "../Item/promptItem";
import LanguageUtils, { LanguageType } from "../../Main/Common/LanguageUtils";
import { DataId, DataManager } from "../../chat18x/data/DataManager";
import { ConfigManager } from "../../chat18x/manager/ConfigManager";
import { AppConfig } from "db://assets/Scripts/chat18x/config/env/appConfig";
import DeviceIdService from "db://assets/Scripts/chat18x/foundation/identity/DeviceIdService";
import { AccountData } from "../../chat18x/data/AccountData";
import { EnvData } from "../../chat18x/data/EnvData";
import { GlobalData } from "../../chat18x/data/GlobalData";
import { AiCharacterData } from "../../chat18x/data/AiCharacterData";
import { LoginData } from "../../chat18x/data/LoginData";
import { PlayerData } from "../../chat18x/data/PlayerData";
import { WalletData } from "../../chat18x/data/WalletData";
import MachineInfoService from "../../chat18x/foundation/identity/MachineInfoService";
import { AuthService } from "../../chat18x/network/services/AuthService";
import { CommonService } from "../../chat18x/network/services/CommonService";
import { PlayerDataService } from "../../chat18x/network/services/PlayerDataService";
import proto from "db://assets/Scripts/proto/proto.pb.js";
import { ViewManager } from "../../Main/Manager/ViewManager";
import { MainScene } from "../MainScene";
import { prodConfig } from "../../chat18x/config/env/prod";
import { logger } from "db://assets/Scripts/Main/Common/Logger";
import AudioManager from "../../Main/Manager/AudioManager";
import { Config18x } from "../../Main/Config/Config18x";
import { MainController } from "../../chat18x/core/MainController";
import GameRootUI from "../../Main/Common/GameRootUI";
import { TipsPanel } from "../../chat18x/ui/panels/TipsPanel";
const { ccclass, property } = _decorator;
@ccclass("PreloadUI")
export class PreloadUI extends Component {
@property(MainScene)
mainScene: MainScene = null;
private _nodeTab: any = {};
private preloadFinish = false; //资源加载完成
private loginFinish = false; //登录完成
loginBtn: Node;
private jinduBar: Node = null;
private jinduFilled: Sprite = null;
private VideoPlayer: VideoPlayer;
private appVersion: Label;
private progressNode: Node;
private loginLabel: Label;
private desc: Label;
// 视频播放状态跟踪
private videoPlayed: boolean = false;
private videoPlayRetryCount: number = 0;
private maxVideoPlayRetry: number = 3;
start() {
//Utils.addInnerEL(InnerMsgCode.UI_ShowPrompt, this, this.resiveShowPrompt)
Utils.parseNode(this.node, this._nodeTab);
// 添加新的事件监听
this.progressNode = this._nodeTab.progress;
this.appVersion = this._nodeTab.appVersion.getComponent(Label);
this.loginBtn = this._nodeTab.btnLogin;
this.loginBtn.active = false;
this.appVersion.string = `app version: ${prodConfig.appVersion}`;
this.VideoPlayer = this._nodeTab.VideoPlayer.getComponent(VideoPlayer);
this.loginLabel = this._nodeTab.loginLabel.getComponent(Label);
this.desc = this._nodeTab.Desc.getComponent(Label);
// 设置视频为静音,提高移动端自动播放成功率
this.VideoPlayer.mute = true;
this.VideoPlayer.loop = true;
this.VideoPlayer.stayOnBottom = true;
this.VideoPlayer.node.on(
VideoPlayer.EventType.META_LOADED,
this.onVideoReadyToPlay,
this
);
// 监听播放失败事件
this.VideoPlayer.node.on(
VideoPlayer.EventType.PLAYING,
this.onVideoPlaying,
this
);
GButton.BandClick(this.loginBtn, this.onLogin, this);
this.jinduBar = this.node.getChildByName("jinduBar");
this.jinduFilled = this.jinduBar
.getChildByName("jinduFilled")
.getComponent(Sprite);
//适配背景图
//let BG = this.node.getChildByName("BG");
//Utils.adjustBgPixelRatio(BG, 1);
this.jinduFilled.fillRange = 0;
// 移除直接播放调用,等待 META_LOADED 事件后再播放
// if (!this.VideoPlayer.isPlaying) this.VideoPlayer.play();
//初始化显示
switch (LanguageUtils.CurrentLanguage) {
case LanguageType.CN:
this.loginLabel.string = "登录";
this.desc.string = "释放你的所有欲望";
break;
case LanguageType.EN:
this.loginLabel.string = "LOG IN";
this.desc.string = "Unleash All Your Desires";
break;
case LanguageType.HI:
this.loginLabel.string = "लॉग इन";
this.desc.string = "अपनी सारी इच्छाओं को मुक्त करें";
break;
default:
break;
}
// 初始化配置
ConfigManager.I.init();
//logger.log(ConfigManager.tables.TbGlobalConfig.GameName);
// 初始化环境配置
AppConfig.I;
// 初始化数据层
DataManager.I.init();
// 设备号
DeviceIdService.I.init();
AudioManager.I.PlayMusic(Config18x.AudioConfig.MainBGM);
SDKManager.I.init();
this.preloadFiles();
this.mainScene.init();
}
protected onDestroy(): void {
// 清理视频事件监听器
if (this.VideoPlayer && this.VideoPlayer.node) {
this.VideoPlayer.node.off(
VideoPlayer.EventType.META_LOADED,
this.onVideoReadyToPlay,
this
);
this.VideoPlayer.node.off(
VideoPlayer.EventType.PLAYING,
this.onVideoPlaying,
this
);
this.VideoPlayer.stop();
}
}
onVideoReadyToPlay() {
logger.log("PreloadUI: Video metadata loaded, attempting to play");
this.tryPlayVideo();
}
/**
* 尝试播放视频,带重试机制和错误处理
*/
private tryPlayVideo() {
if (this.videoPlayed) {
logger.log("PreloadUI: Video already playing, skip");
return;
}
if (!this.VideoPlayer) {
logger.error("PreloadUI: VideoPlayer not initialized");
return;
}
// 尝试播放视频
try {
this.VideoPlayer.play();
logger.log(
`PreloadUI: Video play attempted (retry: ${this.videoPlayRetryCount}/${this.maxVideoPlayRetry})`
);
// 延迟检查播放状态,如果失败则重试
this.scheduleOnce(() => {
if (
!this.VideoPlayer.isPlaying &&
this.videoPlayRetryCount < this.maxVideoPlayRetry
) {
this.videoPlayRetryCount++;
logger.warn(
`PreloadUI: Video play failed, retrying... (${this.videoPlayRetryCount}/${this.maxVideoPlayRetry})`
);
this.tryPlayVideo();
} else if (!this.VideoPlayer.isPlaying) {
logger.warn(
"PreloadUI: Video autoplay failed after max retries. Will retry on user interaction."
);
}
}, 0.5);
} catch (error) {
logger.error("PreloadUI: Video play error:", error);
if (this.videoPlayRetryCount < this.maxVideoPlayRetry) {
this.videoPlayRetryCount++;
this.scheduleOnce(() => {
this.tryPlayVideo();
}, 1.0);
}
}
}
/**
* 视频开始播放回调
*/
private onVideoPlaying() {
logger.log("PreloadUI: Video is now playing");
this.videoPlayed = true;
}
update(deltaTime: number) {
if (!this.preloadFinish) {
return;
//this.goToLoginScene();
}
if (this.loginFinish) {
this.loginFinish = false;
this.preloadFinish = false;
this.enterGame();
}
}
//预加载文件
preloadFiles() {
let preloadTab = [
{ path: "ChatPanel", bundleName: "Chat18x", ftype: Prefab },
{ path: "GirlDetailPanel", bundleName: "Chat18x", ftype: Prefab },
{ path: "GirlListPanel", bundleName: "Chat18x", ftype: Prefab },
{ path: "tblanguage", bundleName: "DataTable", ftype: BufferAsset },
];
let num_prefab = 0; //已加载数量
let num_succeed = 0; //加载成功数量
let preloadFunc = () => {
if (num_prefab < preloadTab.length) {
let cfg = preloadTab[num_prefab];
ResManager.I.preLoadSubpackageFile(
cfg.path,
cfg.bundleName,
cfg.ftype,
(ret) => {
num_prefab++;
num_succeed++;
let percent = 0.45 * (num_prefab / preloadTab.length);
this.showLoadProgress(0.55 + percent);
logger.log("加载成功:", cfg.path);
preloadFunc();
},
(err) => {
num_prefab++;
logger.log("加载失败:", err);
}
);
} else {
if (num_succeed >= num_prefab) {
this.startloginProcess();
}
}
};
preloadFunc();
}
//加载配置表
startloginProcess() {
this.jinduBar.active = false;
this.preloadFinish = true;
this.loginBtn.active = true;
}
//显示加载进度
showLoadProgress(percent) {
this.jinduFilled.fillRange = percent;
this.progressNode.setPosition(new Vec3(percent * 546, 0, 0));
}
// 跳转到登录场景
// private goToLoginScene() {
// this.jinduBar.active = false;
// ResManager.I.goCustomScene("LoginScene");
// }
async onLogin() {
// 用户交互时尝试播放视频(如果自动播放失败)
if (!this.videoPlayed && this.VideoPlayer) {
logger.log("PreloadUI: User interaction detected, trying to play video");
this.videoPlayRetryCount = 0; // 重置重试计数
this.tryPlayVideo();
}
const deviceId = DeviceIdService.I.id;
const os = MachineInfoService.I.getMachineOs();
// 获取fbCode,如果有则表示从落地页进来的
const qs = new URLSearchParams(window.location.search);
const fbCode = qs.get("fbCode");
// 保存fbCode到本地
if (fbCode) {
sys.localStorage.setItem("fbCode", fbCode);
// 上报事件
const reqData = {
point: 4, // 4: 进入游戏
fbCode: fbCode,
};
AuthService.I.pointEvent(reqData);
}
const reqData = {
platType: "guest",
userId: fbCode ? fbCode : deviceId,
device: deviceId,
os,
};
logger.log("登录请求数据:", reqData);
let res = await AuthService.I.login(reqData);
logger.log("登录响应数据:", res);
if (res && res.code === proto.cs.EnmRetCode.SUCCESS) {
const resData = res.data;
const loginData = DataManager.I.getDataById<LoginData>(DataId.Login);
loginData.token = resData.token;
loginData.refreshToken = resData.refreshToken;
loginData.expire = Number(resData.expire);
const playerData = DataManager.I.getDataById<PlayerData>(DataId.Player);
playerData.name = resData.name;
const accountData = DataManager.I.getDataById<AccountData>(
DataId.Account
);
accountData.accId = resData.accId;
const envData = DataManager.I.getDataById<EnvData>(DataId.Env);
envData.cdn = resData.cdn;
this.loginFinish = true;
this.reqMyInfo();
this.reqGlobalData();
this.reqAiCharacterData();
} else {
TipsPanel.show(LanguageUtils.getText("error_code_" + res.code));
}
}
// 请求个人数据
private async reqMyInfo() {
const reqData = {};
let res = await PlayerDataService.I.reqMyInfo(reqData);
logger.log("个人信息响应数据:", res);
if (res && res.code === proto.cs.EnmRetCode.SUCCESS) {
const resData = res.data;
const walletData = DataManager.I.getDataById<WalletData>(DataId.Wallet);
walletData.balance = Number(resData.balance);
walletData.vipExpire = Number(resData.vipExpire);
} else {
TipsPanel.show(LanguageUtils.getText("error_code_" + res.code));
}
}
// 请求全局数据
private async reqGlobalData() {
const reqData = {
resName: "TbGlobalConfig",
};
let res = await CommonService.I.reqResConfig(reqData);
if (res && res.code === proto.cs.EnmRetCode.SUCCESS) {
// 保存数据
const globalData = DataManager.I.getDataById<GlobalData>(DataId.Global);
globalData.globals = res.data;
} else {
TipsPanel.show(LanguageUtils.getText("error_code_" + res.code));
}
}
// 请求Ai角色配置
private async reqAiCharacterData() {
const reqData = {
resName: "TbAiCharacters",
};
let res = await CommonService.I.reqResConfig(reqData);
if (res && res.code === proto.cs.EnmRetCode.SUCCESS) {
// 保存数据
const aiCharacterData = DataManager.I.getDataById<AiCharacterData>(
DataId.AiCharacter
);
aiCharacterData.aiCharacter = res.data;
} else {
TipsPanel.show(LanguageUtils.getText("error_code_" + res.code));
}
}
private async enterGame() {
await MainController.I.init();
this.node.destroy();
GameRootUI.I.showDefault();
//ResManager.I.goMainScene();
}
}