import { _decorator, Component, Label, Node, Overflow, Size, Sprite, UITransform, view, } from "cc"; import Tools from "../../utils/tools"; import { GirlData } from "../../data/GirlData"; import { DataId, DataManager } from "../../data/DataManager"; import { NavigationManager } from "../../manager/NavigationManager"; import ResManager from "../../../Main/Manager/ResManager"; import { EnvData } from "../../data/EnvData"; import { WalletData } from "../../data/WalletData"; const { ccclass, property } = _decorator; @ccclass("DialogBubble") export class DialogBubble extends Component { @property(Sprite) avatar: Sprite = null; @property(UITransform) bg: UITransform = null; @property(Label) content: Label = null; @property(UITransform) contentT: UITransform = null; @property(Node) vipFrame: Node = null; fixMaxWidth: number; uiTransform: UITransform; init(maxWidth?: number) { this.uiTransform = this.node.getComponent(UITransform); // 如果没有提供maxWidth,使用屏幕宽度的80% if (maxWidth === undefined) { this.fixMaxWidth = view.getVisibleSize().width * 0.8; } else { this.fixMaxWidth = maxWidth; } } updateBubbleContent( str: string, isPlayer: boolean = false, callback?: (actualHeight: number) => void, isLoading: boolean = false ) { // 停止之前的加载动画 this.stopLoadingAnimation(); this.content.overflow = Overflow.NONE; let isVip = false; //设置头像 if (isPlayer) { const walletData = DataManager.I.getDataById(DataId.Wallet); isVip = walletData.isVip; //获取玩家头像,等接入luffa } else { const girlData = DataManager.I.getDataById(DataId.Girl); const path = girlData.getGrilAvatar( NavigationManager.Instance.getSelectedCategoryId().toString(), NavigationManager.Instance.getSelectedGirlId() ); // 加载远程资源 const envData = DataManager.I.getDataById(DataId.Env); let newPath = envData.cdn + "/" + "Girls/" + path + ".png"; ResManager.I.changeRemoteSpriteFrame(this.avatar, newPath, () => { this.scaleToFillItem(this.avatar, new Size(90, 90)); }); } // 如果是加载状态,使用固定的"..." if (isLoading) { this.content.string = "..."; // 设置固定尺寸用于加载显示 const contentWidth = 60; this.contentT.setContentSize(new Size(contentWidth, 40)); this.bg.setContentSize(new Size(contentWidth + 30, 50)); if (callback) { callback(40); // 返回固定高度 } return; } if (this.vipFrame) this.vipFrame.active = isVip; // 设置文本内容 this.content.string = str; // 计算最大宽度(估算) const lines = str.split("\n"); let maxWidth = 0; for (const line of lines) { let lineWidth = 0; if (Tools.IsChinese(line)) { lineWidth = 30 * line.length; } else { lineWidth = 18 * line.length; } maxWidth = Math.max(maxWidth, lineWidth); } if (maxWidth > this.fixMaxWidth) this.content.overflow = Overflow.RESIZE_HEIGHT; // 限制最大宽度 const contentWidth = Math.min(maxWidth, this.fixMaxWidth); // 设置内容区域宽度,让Label自动计算高度 this.contentT.setContentSize(new Size(contentWidth, 0)); this.bg.setContentSize(new Size(contentWidth + 37, 0)); this.uiTransform.setContentSize(new Size(contentWidth + 37, 0)); // 强制更新Label的渲染数据以获取正确的高度 this.content.updateRenderData(true); // 等待一帧后获取Label的实际高度 this.scheduleOnce(() => { const actualSize = this.content.node.getComponent(UITransform).contentSize; // 更新内容区域的实际大小 //this.contentT.setContentSize(new Size(contentWidth, actualHeight)); // 根据内容大小调整背景大小,添加适当的内边距 //const bgHeight = actualHeight + 17; this.bg.setContentSize(new Size(actualSize.x + 40, actualSize.y + 30)); this.uiTransform.setContentSize( new Size( actualSize.x + 40, actualSize.y + 30 > 110 ? actualSize.y + 30 : 110 ) ); // 回调通知实际高度 if (callback) { callback(actualSize.y > 110 ? actualSize.y : 110); } }, 0); // 返回预估的背景高度(用于同步计算) const estimatedHeight = Math.max(lines.length * 35 + 20, 110); // 最小高度60 return estimatedHeight; } scaleToFillItem(img: Sprite, size: Size) { if (!img || !img.spriteFrame) return; // 延迟一帧确保UI布局完成 this.doScaleToFill(img, size); } doScaleToFill(img: Sprite, size: Size) { if (!img || !img.spriteFrame) return; const itemSize = size; const imageSize = img.spriteFrame.originalSize; if ( itemSize.width === 0 || itemSize.height === 0 || imageSize.width === 0 || imageSize.height === 0 ) { return; } const scaleX = itemSize.width / imageSize.width; const scaleY = itemSize.height / imageSize.height; const scale = Math.max(scaleX, scaleY); // 设置Sprite的sizeMode为CUSTOM,允许自定义大小 img.sizeMode = Sprite.SizeMode.CUSTOM; // 获取图片节点的UITransform并设置大小 const imgTransform = img.node.getComponent(UITransform); if (imgTransform) { imgTransform.setContentSize( imageSize.width * scale, imageSize.height * scale ); } } private stopLoadingAnimation() { // 预留方法,当前实现中不需要动画,但保留接口以备将来使用 } }