339 lines
9.7 KiB
TypeScript
339 lines
9.7 KiB
TypeScript
import {
|
|
_decorator,
|
|
Label,
|
|
Node,
|
|
Sprite,
|
|
VideoPlayer,
|
|
UITransform,
|
|
Size,
|
|
Vec3,
|
|
tween,
|
|
} from "cc";
|
|
import li_BaseView from "db://assets/Scripts/Main/Common/li_BaseView";
|
|
import ResManager from "db://assets/Scripts/Main/Manager/ResManager";
|
|
import { DetailImageItem } from "../../uiitems/DetailImageItem";
|
|
import { NavigationManager, PanelType } from "../../manager/NavigationManager";
|
|
import { DetailImageItemPool } from "../../manager/DetailImageItemPool";
|
|
import { ConfigManager } from "../../manager/ConfigManager";
|
|
import LanguageUtils from "../../../Main/Common/LanguageUtils";
|
|
import Utils from "../../../Main/Common/Utils";
|
|
import { InnerMsgCode } from "../../../Main/Config/InnerMsgCode";
|
|
import { SimpleToggle } from "../components/SimpleToggle";
|
|
import { DataManager, DataId } from "../../data/DataManager";
|
|
import { GirlData } from "../../data/GirlData";
|
|
import { GirlService } from "db://assets/Scripts/chat18x/network/services/GirlService";
|
|
import proto from "db://assets/Scripts/proto/proto.pb.js";
|
|
import { SceneBgVideoLayer } from "../../../Sub/UI/SceneBgVideoLayer";
|
|
|
|
const { ccclass, property } = _decorator;
|
|
|
|
@ccclass("GirlDetailPanel")
|
|
export class GirlDetailPanel extends li_BaseView {
|
|
@property(UITransform)
|
|
videoArea: UITransform;
|
|
// 移除直接的 VideoPlayer 引用,改用 SceneBgVideoLayer 单例
|
|
// @property(VideoPlayer)
|
|
// avatarVideo: VideoPlayer;
|
|
@property(Label)
|
|
girlName: Label;
|
|
|
|
/** 获取 SceneBgVideoLayer 单例实例 */
|
|
private get videoLayer(): SceneBgVideoLayer | null {
|
|
return SceneBgVideoLayer.handle;
|
|
}
|
|
|
|
@property(SimpleToggle)
|
|
imgToggle: SimpleToggle = null;
|
|
@property(SimpleToggle)
|
|
videoToggle: SimpleToggle = null;
|
|
|
|
@property(Node)
|
|
starParent: Node;
|
|
|
|
@property(Label)
|
|
tags: Label;
|
|
|
|
@property(Label)
|
|
descAge: Label;
|
|
@property(Label)
|
|
desc: Label;
|
|
|
|
@property(Node)
|
|
chatBtn: Node;
|
|
|
|
@property(Node)
|
|
descContent: Node;
|
|
id = 0;
|
|
|
|
@property(DetailImageItem)
|
|
imgItemInst: DetailImageItem;
|
|
|
|
@property(Node)
|
|
imgsLayout: Node;
|
|
|
|
videoAreaPos;
|
|
|
|
protected onEnable(): void {
|
|
this.refresh();
|
|
}
|
|
|
|
onLoadCT() {
|
|
super.onLoadCT();
|
|
|
|
//this.refresh();
|
|
|
|
DetailImageItemPool.Instance.setTemplate(this.imgItemInst.node);
|
|
|
|
Utils.addInnerEL(InnerMsgCode.LanguageChange, this, () => {
|
|
this.girlName.string = LanguageUtils.getText(this.nameKey);
|
|
let desc = "";
|
|
const tags = LanguageUtils.getText(this.tagKey).split("|");
|
|
for (let i = 0; i < tags.length; i++) {
|
|
if (i != 0) desc += "\n";
|
|
desc += tags[i];
|
|
}
|
|
this.tags.string = desc;
|
|
this.desc.string = LanguageUtils.getText(this.descKey);
|
|
});
|
|
|
|
this.imgToggle.callback = this.bindImgToggle.bind(this);
|
|
this.videoToggle.callback = this.bindVideoToggle.bind(this);
|
|
}
|
|
|
|
setVideEnable(enable: boolean) {
|
|
if (!this.videoLayer) {
|
|
console.error("GirlDetailPanel: SceneBgVideoLayer 不可用");
|
|
return;
|
|
}
|
|
|
|
if (enable) {
|
|
// 恢复播放
|
|
this.videoLayer.resume();
|
|
console.log("GirlDetailPanel: 开启视频播放");
|
|
} else {
|
|
// 暂停播放
|
|
this.videoLayer.pause();
|
|
console.log("GirlDetailPanel: 暂停视频播放");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 获取目标视频尺寸
|
|
* 从 videoArea 获取实际需要填充的区域尺寸
|
|
*/
|
|
private getTargetVideoSize(): Size | null {
|
|
// 从 videoArea 获取目标尺寸
|
|
if (this.videoArea) {
|
|
return new Size(this.videoArea.width, this.videoArea.height);
|
|
}
|
|
|
|
// 如果没有 videoArea,使用默认尺寸
|
|
console.warn("GirlDetailPanel: videoArea 未设置,使用默认尺寸");
|
|
return new Size(600, 800);
|
|
}
|
|
nameKey: string;
|
|
tagKey: string;
|
|
descKey: string;
|
|
category: number;
|
|
async refresh() {
|
|
this.id = NavigationManager.Instance.getSelectedGirlId();
|
|
this.category = NavigationManager.Instance.getSelectedCategoryId();
|
|
this.imgItemInst.node.active = false;
|
|
this.videoAreaPos = new Vec3(540, 1384);
|
|
|
|
const pos = new Vec3(
|
|
this.descContent.position.x,
|
|
this.descContent.position.y,
|
|
this.descContent.position.z
|
|
);
|
|
this.descContent.position = new Vec3(pos.x, pos.y - 1000, pos.z);
|
|
//this.node.scale = Vec3.ZERO;
|
|
tween(this.descContent)
|
|
.to(0.3, { position: pos }, { easing: "quadOut" })
|
|
.start();
|
|
|
|
// 检查 SceneBgVideoLayer 是否可用
|
|
if (!this.videoLayer) {
|
|
console.error("GirlDetailPanel: SceneBgVideoLayer.handle 未初始化");
|
|
} else {
|
|
console.log("GirlDetailPanel: 成功获取 SceneBgVideoLayer 实例");
|
|
// 初始化视频显示位置
|
|
//this.initVideoPosition();
|
|
}
|
|
|
|
const girlData = DataManager.I.getDataById<GirlData>(DataId.Girl);
|
|
// 请求详细数据
|
|
const reqData = {
|
|
id: this.id,
|
|
};
|
|
let res = await GirlService.I.reqGetGirlDetail(reqData);
|
|
if (res && res.code === proto.cs.EnmRetCode.SUCCESS) {
|
|
// 保存数据
|
|
girlData.setGirlDetailData(this.category.toString(), res.data);
|
|
// 根据数据,刷新界面
|
|
this.nameKey = girlData.getGrilName(this.category.toString(), this.id);
|
|
this.girlName.string = LanguageUtils.getText(this.nameKey);
|
|
this.descKey = girlData.getGrilDesc(this.category.toString(), this.id);
|
|
this.desc.string = LanguageUtils.getText(this.descKey);
|
|
|
|
let desc = "";
|
|
this.tagKey = girlData.getGrilTagKey(this.category.toString(), this.id);
|
|
const tags = LanguageUtils.getText(this.tagKey).split("|");
|
|
for (let i = 0; i < tags.length; i++) {
|
|
if (i != 0) desc += "\n";
|
|
desc += tags[i];
|
|
}
|
|
this.tags.string = desc;
|
|
for (let i = 0; i < 5; i++) {
|
|
this.starParent.children[i].active = i < 5;
|
|
}
|
|
let age = girlData.getGrilAge(this.category.toString(), this.id);
|
|
this.descAge.string =
|
|
LanguageUtils.getText("girldetailpanel.age") + age.toString();
|
|
|
|
const firstPath = girlData.getFirstGrilVideoPath(
|
|
this.category.toString(),
|
|
this.id
|
|
);
|
|
|
|
// 使用 SceneBgVideoLayer 加载并播放视频
|
|
if (this.videoLayer && firstPath) {
|
|
console.log(`GirlDetailPanel: 加载视频 ${firstPath}`);
|
|
|
|
// 获取 videoArea 的尺寸和位置
|
|
const targetSize = this.videoArea
|
|
? new Size(this.videoArea.width, this.videoArea.height)
|
|
: new Size(600, 800);
|
|
|
|
// 获取 videoArea 的中心位置,确保使用正确的世界坐标
|
|
const videoAreaPos = this.videoAreaPos;
|
|
if (this.videoArea) {
|
|
// 获取 videoArea 的世界坐标
|
|
this.videoAreaPos = this.videoArea.node.getWorldPosition();
|
|
|
|
// 也检查 videoLayer 的父节点信息,确保坐标系统一致
|
|
if (this.videoLayer && this.videoLayer.getVideoPlayer()) {
|
|
const videoPlayerParent =
|
|
this.videoLayer.getVideoPlayer().node.parent;
|
|
if (videoPlayerParent) {
|
|
const parentWorldPos = videoPlayerParent.getWorldPosition();
|
|
console.log(
|
|
`GirlDetailPanel: VideoPlayer 父节点世界位置: (${parentWorldPos.x}, ${parentWorldPos.y}, ${parentWorldPos.z})`
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 使用新的统一 playVideo 方法
|
|
this.videoLayer.playVideo(firstPath, {
|
|
loop: true,
|
|
size: targetSize,
|
|
position: videoAreaPos,
|
|
});
|
|
}
|
|
|
|
let resIds = girlData.getAllDisplayGrilPhotoId(
|
|
this.category.toString(),
|
|
this.id
|
|
);
|
|
this.refreshImgs(
|
|
proto.cs.EnmResType.ERT_Image,
|
|
this.category,
|
|
this.id,
|
|
resIds
|
|
);
|
|
}
|
|
}
|
|
|
|
bindImgToggle() {
|
|
const girlData = DataManager.I.getDataById<GirlData>(DataId.Girl);
|
|
let resIds = girlData.getAllDisplayGrilPhotoId(
|
|
this.category.toString(),
|
|
this.id
|
|
);
|
|
this.refreshImgs(
|
|
proto.cs.EnmResType.ERT_Image,
|
|
this.category,
|
|
this.id,
|
|
resIds
|
|
);
|
|
}
|
|
|
|
bindVideoToggle() {
|
|
const girlData = DataManager.I.getDataById<GirlData>(DataId.Girl);
|
|
let resIds = girlData.getAllDisplayGrilVideoId(
|
|
this.category.toString(),
|
|
this.id
|
|
);
|
|
this.refreshImgs(
|
|
proto.cs.EnmResType.ERT_Video,
|
|
this.category,
|
|
this.id,
|
|
resIds
|
|
);
|
|
}
|
|
|
|
refreshImgs(
|
|
type: proto.cs.EnmResType,
|
|
category: number,
|
|
id: number,
|
|
resIds: number[]
|
|
) {
|
|
for (let i = this.imgsLayout.children.length - 1; i >= 0; i--) {
|
|
DetailImageItemPool.Instance.put(this.imgsLayout.children[i]);
|
|
}
|
|
|
|
let count = resIds.length;
|
|
for (let i = 0; i < count; i++) {
|
|
let newNode = DetailImageItemPool.Instance.get();
|
|
if (newNode) {
|
|
let item = newNode.getComponent(DetailImageItem);
|
|
let resId = resIds[i];
|
|
item.refresh(this, type, category, id, resId);
|
|
newNode.active = true;
|
|
this.imgsLayout.addChild(newNode);
|
|
}
|
|
}
|
|
}
|
|
|
|
OnClickChatBtn() {
|
|
// 使用带过渡动画的导航方法
|
|
NavigationManager.Instance.switchToPanel(PanelType.CHAT);
|
|
}
|
|
|
|
returnBtn() {
|
|
NavigationManager.Instance.switchToPanel(PanelType.THEME);
|
|
}
|
|
|
|
/**
|
|
* 面板关闭时的清理工作
|
|
*/
|
|
onClose() {
|
|
// 停止视频播放,释放资源
|
|
if (this.videoLayer) {
|
|
//this.videoLayer.stop();
|
|
//console.log("GirlDetailPanel: 停止视频播放");
|
|
}
|
|
|
|
super.onClose();
|
|
}
|
|
|
|
/**
|
|
* 面板销毁时的清理工作
|
|
*/
|
|
onDestroy() {
|
|
// 确保视频资源被释放
|
|
if (this.videoLayer) {
|
|
//this.videoLayer.stop();
|
|
//console.log("GirlDetailPanel: 销毁时停止视频播放");
|
|
}
|
|
|
|
// 回收所有使用中的节点到对象池
|
|
for (let i = this.imgsLayout.children.length - 1; i >= 0; i--) {
|
|
DetailImageItemPool.Instance.put(this.imgsLayout.children[i]);
|
|
}
|
|
|
|
super.onDestroy();
|
|
}
|
|
}
|