98 lines
3.0 KiB
TypeScript
98 lines
3.0 KiB
TypeScript
import { _decorator, Component, instantiate, Node, Vec3 } from "cc";
|
|
import { DialogManager } from "../../manager/DialogManager";
|
|
import { DialogBubble } from "./DialogBubble";
|
|
import { Dialog } from "../../data/DialogData";
|
|
const { ccclass, property } = _decorator;
|
|
|
|
const BUTTOM_Y = -955.571;
|
|
|
|
@ccclass("ChatContentsLayout")
|
|
export class ChatContentsLayout extends Component {
|
|
manager: DialogManager = null;
|
|
|
|
@property(DialogBubble)
|
|
lBubble: DialogBubble = null;
|
|
@property(DialogBubble)
|
|
rBubble: DialogBubble = null;
|
|
|
|
bubbles: DialogBubble[] = [];
|
|
cachedBubbles: DialogBubble[] = [];
|
|
|
|
protected start(): void {
|
|
this.lBubble.node.active = false;
|
|
this.rBubble.node.active = false;
|
|
}
|
|
|
|
protected onEnable(): void {
|
|
if (!this.manager) this.manager = DialogManager.getInstance();
|
|
|
|
this.manager.layoutout = this;
|
|
}
|
|
|
|
UpdateDialog(dialogs: Dialog[]) {
|
|
// 隐藏当前使用的气泡并放入缓存
|
|
for (let i = 0; i < this.bubbles.length; i++) {
|
|
if (this.bubbles[i].node) {
|
|
this.bubbles[i].node.active = false;
|
|
this.cachedBubbles.push(this.bubbles[i]);
|
|
}
|
|
}
|
|
this.bubbles = [];
|
|
|
|
let initPosY: number = BUTTOM_Y;
|
|
for (let i = dialogs.length - 1; i >= 0; i--) {
|
|
const dialog = dialogs[i]; //倒序
|
|
let newBubble: DialogBubble = null;
|
|
|
|
// 尝试从缓存中获取合适的气泡
|
|
const isPlayerBubble = dialog.isPlayer;
|
|
for (let j = 0; j < this.cachedBubbles.length; j++) {
|
|
const cached = this.cachedBubbles[j];
|
|
if (cached && cached.node) {
|
|
// 检查气泡类型是否匹配(通过位置判断左右气泡)
|
|
const isRightBubble = cached.node.position.x > 0;
|
|
if ((isPlayerBubble && isRightBubble) || (!isPlayerBubble && !isRightBubble)) {
|
|
newBubble = cached;
|
|
this.cachedBubbles.splice(j, 1);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 如果缓存中没有合适的气泡,创建新的
|
|
if (!newBubble) {
|
|
let newBubbleNode = isPlayerBubble
|
|
? instantiate(this.rBubble.node)
|
|
: instantiate(this.lBubble.node);
|
|
newBubble = newBubbleNode.getComponent(DialogBubble);
|
|
newBubbleNode.setParent(this.node);
|
|
}
|
|
|
|
newBubble.node.active = true;
|
|
let offset = newBubble.updateBubbleContent(dialog.content);
|
|
|
|
let pos = newBubble.node.position;
|
|
newBubble.node.position = new Vec3(pos.x, initPosY, pos.z);
|
|
|
|
initPosY += offset + 20;
|
|
this.bubbles.push(newBubble);
|
|
}
|
|
|
|
// 清理多余的缓存气泡,避免内存泄漏
|
|
this.cleanupExcessCachedBubbles();
|
|
}
|
|
|
|
private cleanupExcessCachedBubbles() {
|
|
const maxCachedBubbles = 20; // 最大缓存数量
|
|
if (this.cachedBubbles.length > maxCachedBubbles) {
|
|
const excessCount = this.cachedBubbles.length - maxCachedBubbles;
|
|
for (let i = 0; i < excessCount; i++) {
|
|
const bubble = this.cachedBubbles.shift();
|
|
if (bubble && bubble.node) {
|
|
bubble.node.destroy();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|