设置页、弹窗逻辑、跳转逻辑

视频播放逻辑优化
This commit is contained in:
2025-09-11 00:03:22 +08:00
parent a6b15778a8
commit 7dedbf124c
24 changed files with 2338 additions and 1381 deletions
@@ -6,6 +6,7 @@ import {
VideoPlayer,
instantiate,
UITransform,
Size,
} from "cc";
import li_BaseView from "db://assets/Scripts/Main/Common/li_BaseView";
import ResManager from "db://assets/Scripts/Main/Manager/ResManager";
@@ -20,18 +21,25 @@ 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(Sprite)
avatar: Sprite;
@property(VideoPlayer)
avatarVideo: VideoPlayer;
@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)
@@ -82,38 +90,76 @@ export class GirlDetailPanel extends li_BaseView {
this.imgToggle.callback = this.bindImgToggle.bind(this);
this.videoToggle.callback = this.bindVideoToggle.bind(this);
// 添加视频加载完成回调
this.avatarVideo.node.on(
VideoPlayer.EventType.READY_TO_PLAY,
() => {
this.adjustVideoScale();
},
this
);
// 检查 SceneBgVideoLayer 是否可用
if (!this.videoLayer) {
console.error("GirlDetailPanel: SceneBgVideoLayer.handle 未初始化");
} else {
console.log("GirlDetailPanel: 成功获取 SceneBgVideoLayer 实例");
// 初始化视频显示位置
this.initVideoPosition();
}
}
setVideEnable(enable: boolean) {
this.avatarVideo.enabled = enable;
if (!this.videoLayer) {
console.error("GirlDetailPanel: SceneBgVideoLayer 不可用");
return;
}
if (enable) {
this.avatarVideo.play();
// 恢复播放
this.videoLayer.resume();
console.log("GirlDetailPanel: 开启视频播放");
} else {
// 暂停播放
this.videoLayer.pause();
console.log("GirlDetailPanel: 暂停视频播放");
}
}
adjustVideoScale() {
if (!this.avatarVideo || !this.avatarVideo.node.parent) {
if (!this.videoLayer) {
console.error("GirlDetailPanel: SceneBgVideoLayer 不可用");
return;
}
// 获取 videoArea 的尺寸
if (!this.videoArea) {
console.error("GirlDetailPanel: videoArea 未设置");
return;
}
// 参考原有逻辑,计算缩放比例使视频高度填满 videoArea
const tryAdjustScale = () => {
const parentTransform =
this.avatarVideo.node.parent.getComponent(UITransform);
const videoTransform = this.avatarVideo.node.getComponent(UITransform);
const videoPlayer = this.videoLayer.getVideoPlayer();
if (!videoPlayer) return false;
const videoTransform = videoPlayer.node.getComponent(UITransform);
if (videoTransform && videoTransform.height > 0) {
// 设置视频锚点为中心 (0.5, 0.5),确保视频的中心点就是定位点
this.videoLayer.setVideoAnchor(0.5, 0.5);
// 计算缩放比例,使视频高度填满 videoArea(保持原有逻辑)
const scale = this.videoArea.height / videoTransform.height;
// 设置视频缩放
this.videoLayer.setVideoScale(scale);
// 获取 videoArea 的世界坐标中心点
const videoAreaWorldPos = this.videoArea.node.getWorldPosition();
// 使用世界坐标设置视频位置,确保正确对齐
this.videoLayer.setVideoWorldPosition(
videoAreaWorldPos.x,
videoAreaWorldPos.y,
videoAreaWorldPos.z
);
if (parentTransform && videoTransform && videoTransform.height > 0) {
const scale = parentTransform.height / videoTransform.height;
this.avatarVideo.node.setScale(scale, scale, 1);
console.log(
`Video scaled to: ${scale}, parent height: ${parentTransform.height}, video height: ${videoTransform.height}`
`GirlDetailPanel: 视频缩放到 ${scale}, videoArea高度: ${this.videoArea.height}, 视频高度: ${videoTransform.height}`
);
console.log(
`GirlDetailPanel: 视频世界位置设置为 (${videoAreaWorldPos.x}, ${videoAreaWorldPos.y})`
);
return true;
}
@@ -122,7 +168,7 @@ export class GirlDetailPanel extends li_BaseView {
// 立即尝试一次
if (!tryAdjustScale()) {
// 如果失败,延迟尝试
// 如果失败,延迟尝试(保持原有的重试机制)
this.scheduleOnce(() => {
if (!tryAdjustScale()) {
// 再次延迟尝试
@@ -133,6 +179,21 @@ export class GirlDetailPanel extends li_BaseView {
}, 0.1);
}
}
/**
* 获取目标视频尺寸
* 从 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;
@@ -173,14 +234,41 @@ export class GirlDetailPanel extends li_BaseView {
this.category.toString(),
this.id
);
ResManager.I.changeBundleVideo(this.avatarVideo, firstPath, "Girls");
// 使用 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 bgFrameNode = this.videoArea ? this.videoArea.node : null;
// 使用 playLocalLoopVideo 方法,保证兼容性
const videoData = {
path: firstPath,
size: targetSize,
bgFrameNode: bgFrameNode, // 传递 videoArea 节点作为位置参考
};
this.videoLayer.playLocalLoopVideo(videoData);
// 延迟调整视频缩放和位置,确保视频加载完成
this.scheduleOnce(() => {
this.adjustVideoScale();
}, 0.1);
} else if (!firstPath) {
console.warn(
`GirlDetailPanel: 未找到视频路径 category=${this.category}, id=${this.id}`
);
}
let resIds = girlData.getAllDisplayGrilPhotoId(
this.category.toString(),
this.id
);
// 也立即尝试调整(以防已经加载完成)
this.adjustVideoScale();
this.refreshImgs(
proto.cs.EnmResType.ERT_Image,
this.category,
@@ -239,6 +327,28 @@ export class GirlDetailPanel extends li_BaseView {
}
}
/**
* 初始化视频位置和属性
*/
private initVideoPosition() {
if (!this.videoLayer || !this.videoArea) return;
// 设置视频锚点为中心 (0.5, 0.5),这样视频的中心点就是定位点
this.videoLayer.setVideoAnchor(0.5, 0.5);
// 使用 videoArea 的世界坐标位置
const videoAreaWorldPos = this.videoArea.node.getWorldPosition();
this.videoLayer.setVideoWorldPosition(
videoAreaWorldPos.x,
videoAreaWorldPos.y,
videoAreaWorldPos.z
);
this.videoLayer.setVideoScale(1);
console.log(
`GirlDetailPanel: 初始化视频世界位置到 (${videoAreaWorldPos.x}, ${videoAreaWorldPos.y})`
);
}
OnClickChatBtn() {
// 使用带过渡动画的导航方法
NavigationManager.Instance.navigateToChatWithTransition(
@@ -254,4 +364,30 @@ export class GirlDetailPanel extends li_BaseView {
NavigationManager.Instance.navigateToGirlList(this.category);
//ViewManager.I.openBundlesView("GirlListPanel");
}
/**
* 面板关闭时的清理工作
*/
onClose() {
// 停止视频播放,释放资源
if (this.videoLayer) {
//this.videoLayer.stop();
//console.log("GirlDetailPanel: 停止视频播放");
}
super.onClose();
}
/**
* 面板销毁时的清理工作
*/
onDestroy() {
// 确保视频资源被释放
if (this.videoLayer) {
//this.videoLayer.stop();
//console.log("GirlDetailPanel: 销毁时停止视频播放");
}
super.onDestroy();
}
}