rp_11001/assets/Game/scripts/game/Roller.ts
2025-11-27 14:30:07 +08:00

964 lines
31 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 负责单个滚轮的创建、滚动、停止等逻辑
*/
import {
_decorator,
Node,
UITransform,
Vec2,
v2,
Vec3,
v3,
tween,
Tween,
} from 'cc';
import { IconFactory } from './IconFactory';
import { Icon } from './Icon';
import { BaseRoller, ROLLER_STATE } from './BaseRoller';
import { ICON_MAP, ROLLER_COMBINE_EVENT, ROLLER_EVENT } from './Define';
import { AudioManager } from 'db://assets/Loading/scripts/manager/AudioManager';
let { ccclass, property, executeInEditMode } = _decorator;
/**
* 滚轮组件类
*/
@ccclass('Roller')
@executeInEditMode
export class Roller extends BaseRoller {
// 编辑器属性
@property({ tooltip: '行数' })
row: number = 3;
// 本地格式化相关
@property
private _format = false;
@property({ tooltip: '本地格式化' })
get format(): boolean {
return this._format;
}
set format(b: boolean) {
this._format = b;
this.resizeContentSize();
if (!this.iconFactory) {
console.error('IconFactory没有设置');
return;
}
// 重新创建图标
this._content.removeAllChildren();
this._info.icons = [];
this._allIcons.clear();
this._posToIconKey.clear();
// 清除位置缓存 - 添加这一行
this._positionCache.clear();
for (let i = 0; i < this.row; i++) {
let randomIndex = Math.floor(Math.random() * this.iconFactory.getIconNum());
this.createNormalIcon(i, randomIndex);
}
}
_cachedContentHeight: number = 0;
_cachedAnchorY: number = 0;
/**
* 创建滚轮实例
* @param id 滚轮ID
* @param row 行数
* @param iconWidth 图标宽度
* @param iconHeight 图标高度
* @param iconFactory 图标工厂实例
* @param anchor 锚点位置
* @returns 新创建的滚轮实例
*/
static create(
id: number,
row: number,
iconWidth: number,
iconHeight: number,
iconFactory: IconFactory,
anchor: Vec2 = v2(0.5, 0.5)
): Roller {
let rollerNode = new Node(`Roller${id}`);
rollerNode.addComponent(UITransform);
let roller = rollerNode.addComponent(Roller);
roller._rollerId = id;
roller.row = row;
roller.iconWidth = iconWidth;
roller.iconHeight = iconHeight;
roller.iconFactory = iconFactory;
rollerNode.getComponent(UITransform).setAnchorPoint(anchor);
roller.resizeContentSize();
roller.initRoller(id);
return roller;
}
/**
* 设置节点尺寸和位置
*/
setupNodesSizeAndPosition() {
let totalHeight = this.iconHeight * this.row;
let anchorPoint = this.node.getComponent(UITransform).anchorPoint;
// 设置主节点尺寸
this.node.getComponent(UITransform).setContentSize(this.iconWidth, totalHeight);
// 设置view节点
this._view.setPosition(0, 0);
this._view.getComponent(UITransform).setContentSize(this.iconWidth, totalHeight);
this._view.getComponent(UITransform).setAnchorPoint(anchorPoint);
this._view.getComponent(UITransform).width *= 2;
// 设置content节点
this._content.setPosition(0, 0);
this._content.getComponent(UITransform).setContentSize(this.iconWidth, totalHeight);
this._content.getComponent(UITransform).setAnchorPoint(anchorPoint);
this._content.removeAllChildren();
}
/**
* 获取图标的实际坐标
* @param pos 图标位置索引
* @param size 图标大小
* @returns 图标的世界坐标
*/
getIconPosition(pos: number, size: number = 1): Vec3 {
// 创建缓存键
let cacheKey = size > 1 ? (pos + 1) * 1000 + size : pos;
if (this._positionCache.has(cacheKey)) {
return this._positionCache.get(cacheKey).clone();
}
// 确保缓存数据已初始化
if (!this._cachedContentHeight) {
this._cachedContentHeight = this._content.getComponent(UITransform).height;
this._cachedAnchorY = this._content.getComponent(UITransform).anchorY;
}
// 计算基准位置
let contentHeight = this._cachedContentHeight;
let anchorY = this._cachedAnchorY;
// 计算顶部位置
let topY = contentHeight * (1 - anchorY);
// 计算第一个位置的中心Y坐标
let firstCenterY = topY - this.iconHeight / 2;
// 计算当前位置的中心Y坐标
let centerY = firstCenterY - pos * this.iconHeight;
// 对于大图标,需要调整位置
let finalY = centerY;
if (size > 1) {
// 大图标的中心点应该下移,使其顶部对齐格子
// 对于高度为3的图标中心点应该下移1个格子高度
finalY = centerY - (size - 1) * this.iconHeight / 2;
}
// 创建最终位置
let position = v3(0, finalY, 0);
// 缓存结果
this._positionCache.set(cacheKey, position.clone());
return position;
}
/**
* 初始化性能优化相关的缓存
*/
initCache() {
this._cachedUITransform = this._content.getComponent(UITransform);
this._cachedContentHeight = this._cachedUITransform.height;
this._cachedAnchorY = this._cachedUITransform.anchorY;
}
/**
* 收集现有图标
*/
collectExistingIcons() {
for (let i = 0; i < this.row; i++) {
let icon = this._allIcons.get(this._posToIconKey.get(i));
if (icon) {
this._allIcons.delete(this._posToIconKey.get(i));
this._posToIconKey.delete(i);
this._info.icons.push(icon);
}
}
}
/**
* 手动停止滚动
* @param data 停止时的图标数据
*/
async manualStopScroll(data: number[]) {
if (this._info.isManualStop ||
this._info.state === ROLLER_STATE.STOP) {
return;
}
this._info.resetLxInfo();
this._stopData = data;
this._info.isManualStop = true;
Tween.stopAllByTarget(this._info.speedNode);
// 直接回收所有动态图标
while (this._info.icons.length > 0) {
let icon = this._info.icons.pop();
this.iconFactory.recycleIcon(icon);
}
// 回收固定位置图标
for (let i = 0; i < this.row; i++) {
let icon = this._allIcons.get(this._posToIconKey.get(i));
if (icon) {
this._allIcons.delete(this._posToIconKey.get(i));
this._posToIconKey.delete(i);
this.iconFactory.recycleIcon(icon);
}
}
this._allIcons.clear();
this._posToIconKey.clear();
this.createInitIcons(data);
// 为所有创建的图标播放动画
for (let icon of this._allIcons.values()) {
icon.getComponent(Icon).playSpawnAni();
}
this.changeState(ROLLER_STATE.STOP);
}
/**
* 创建最后一页图标
*/
createLastPage() {
let data = this._stopData;
if (!data) return;
// 计算顶部基准位置
let topY = this.getIconPosition(0).y;
let icons = this._info.icons;
if (icons.length > 0) {
topY = Math.max(topY, this.findHighestIconXorY(icons));
}
// 清除已有的位置映射,准备重新创建
this._allIcons.clear();
this._posToIconKey.clear();
// 从上到下依次创建图标从位置0开始
for (let i = 0; i < data.length; i++) {
// 检查当前位置是否需要创建特殊图标n*1图标
if (this._CroSymbols && this._CroSymbols[i]) {
let iconSpecialMsg = this._CroSymbols[i];
// 检查这个特殊图标是否已经被处理过
let isProcessed = false;
for (let j = 0; j < i; j++) {
if (this._CroSymbols[j] && this._CroSymbols[j].id === iconSpecialMsg.id) {
isProcessed = true;
break;
}
}
// 如果这个特殊图标还没有被处理,创建它
if (!isProcessed) {
let startPos = iconSpecialMsg.startPos;
let endPos = iconSpecialMsg.endPos;
let height = iconSpecialMsg.lHeight;
let iconIndex = iconSpecialMsg.iconIndex;
let frameType = iconSpecialMsg.Type;
// 生成图标ID
let iconKey = this.generateIconKey(startPos, height, endPos);
// 创建图标节点
let icon = this.iconFactory.icfactoryCreateIcon(iconIndex);
icon.getComponent(Icon).initIcon(iconIndex, height, iconKey, frameType, this._rollerId);
// 计算位置
// 计算该位置普通图标应该在的Y坐标
let normalIconY = topY + (this.row - startPos) * this.iconHeight;
// 对于大图标,需要考虑其锚点在中心,向下偏移(height-1)/2个格子高度
let offsetY = (height - 1) * this.iconHeight / 2;
// 最终位置
let y = normalIconY - offsetY;
icon.setPosition(0, y, 0);
this._content.addChild(icon);
// 存储图标节点
this._allIcons.set(iconKey, icon);
// 设置位置映射
for (let i = 0; i < height; i++) {
this._posToIconKey.set(startPos + i, iconKey);
}
}
}
// 如果当前位置已被特殊图标占用,跳过
if (this._posToIconKey.has(i)) continue;
// 生成图标ID
let pos = i;
let iconIndex = data[i];
let iconKey = this.generateIconKey(pos, 1, pos);
// 创建图标节点
let icon = this.iconFactory.icfactoryCreateIcon(iconIndex);
icon.getComponent(Icon).initIcon(iconIndex, 1, iconKey, 0, this._rollerId);
// 计算位置
let y = topY + (this.row - pos) * this.iconHeight;
icon.setPosition(0, y, 0);
this._content.addChild(icon);
// 存储图标节点
this._allIcons.set(iconKey, icon);
this._posToIconKey.set(pos, iconKey);
}
this.node.emit(ROLLER_EVENT.LAST_PAGE_CREATE, this._rollerId);
}
/**
* 检查图标是否超出显示范围
*/
checkDeadLine(icon: Node): boolean {
if (!this._cachedContentHeight) {
this._cachedContentHeight = this._content.getComponent(UITransform).height;
this._cachedAnchorY = this._content.getComponent(UITransform).anchorY;
}
let iconComponent = icon.getComponent(Icon);
let lheight = iconComponent.lHeight;
let iconBody = (lheight - 1) * this.iconHeight + this.iconHeight / 2;
let deadLine = -(this._cachedContentHeight * this._cachedAnchorY) - iconBody;
return icon.position.y <= deadLine;
}
/**
* 补充新的图标
*/
suppleIcon() {
let bornLine = this.getIconPosition(0, 1).y;
let icons = this._info.icons;
// 找到最高的图标Y坐标
let topY = this.findHighestIconXorY(icons);
// 如果最高的图标低于出生线,创建新图标
if (topY < bornLine) {
this.createRandomIcon();
}
}
/**
* 创建随机图标
*/
createRandomIcon() {
let iconIndex = this.getRandomIconIndex();
let newY = this.computeNewIconXorY();
let icon = this.iconFactory.icfactoryCreateIcon(iconIndex);
// 设置快速图标效果
if (this.shouldShowFastIcon()) {
icon.getComponent(Icon).showFastIcon(true);
}
icon.setPosition(0, newY, 0);
this._content.addChild(icon);
this._info.icons.push(icon);
this.node.emit(ROLLER_EVENT.ON_R_ICON_CREATE, this._rollerId, icon);
}
/**
* 找到最高的图标Y坐标
* @param icons 图标数组
* @returns 最高的Y坐标
*/
findHighestIconXorY(icons: Node[]): number {
return icons.reduce((maxY, icon) => {
if (!icon || !icon.active) return maxY;
let iconComponent = icon.getComponent(Icon);
if (!iconComponent) return maxY;
let lHeight = iconComponent.lHeight || 1;
let iconY = icon.position.y;
// 对于高度大于1的图标考虑其顶部位置
if (lHeight > 1) {
// 计算图标顶部位置:当前位置 + 高度差 * 图标高度 / 2
return Math.max(maxY, iconY + (lHeight - 1) * this.iconHeight / 2);
} else {
return Math.max(maxY, iconY);
}
}, -999);
}
/**
* 计算新图标的Y坐标
*/
computeNewIconXorY(): number {
let icons = this._info.icons;
// 如果没有图标,使用初始位置
if (!icons.length) {
return this.getIconPosition(0).y + this.iconHeight;
}
// 找到最高的图标Y坐标
let highestY = this.findHighestIconXorY(icons);
// 新图标位置 = 最高图标位置 + 图标高度
return highestY + this.iconHeight;
}
/**
* 清理资源
*/
onDestroy() {
this._cachedUITransform = null;
this._cachedContentHeight = 0;
this._cachedAnchorY = 0;
this._positionCache.clear();
}
/**
* 滚轮移动
* @param dt 时间增量
*/
rollerMove(dt: number) {
// 计算移动向量
let speed = this._info.speed;
let move = speed * dt;
let moveVec = v3(0, move, 0);
// 更新动态图标位置
this._info.icons.forEach(icon => {
if (!icon || !icon.isValid) return;
if (icon.active) {
let newPosition = icon.position.clone().subtract(moveVec);
icon.setPosition(newPosition);
}
});
// 获取所有图标
let allIcons = Array.from(this._allIcons.values());
allIcons.forEach(icon => {
if (!icon || !icon.isValid) return;
let newPosition = icon.position.clone().subtract(moveVec);
icon.setPosition(newPosition);
});
}
/**
* 回收滚轮图标
*/
recycleRollerIcon() {
// 回收动态图标
let icons = this._info.icons;
for (let i = icons.length - 1; i >= 0; i--) {
let icon = icons[i];
if (!icon || !icon.isValid) {
icons.splice(i, 1);
continue;
}
if (this.checkDeadLine(icon)) {
// 从数组中移除
icons.splice(i, 1);
// 回收图标
this.iconFactory.recycleIcon(icon);
}
}
// 回收固定位置图标(非最后一页创建状态)
if (this._info.state !== ROLLER_STATE.LAST_PAGE_CREATE) {
for (let i = 0; i < this.row; i++) {
let iconKey = this._posToIconKey.get(i);
if (!iconKey) continue;
let icon = this._allIcons.get(iconKey);
if (!icon || !icon.isValid) {
this._posToIconKey.delete(i);
this._allIcons.delete(iconKey);
continue;
}
if (this.checkDeadLine(icon)) {
// 从映射中移除
this._allIcons.delete(iconKey);
this._posToIconKey.delete(i);
// 回收图标
this.iconFactory.recycleIcon(icon);
}
}
}
// 处理特殊图标n*1图标
if (this._info.state !== ROLLER_STATE.LAST_PAGE_CREATE) {
// 获取所有特殊图标的key
let specialIconKeys = Array.from(this._allIcons.keys())
.filter(key => key.startsWith('large_'));
for (let iconKey of specialIconKeys) {
let icon = this._allIcons.get(iconKey);
if (!icon || !icon.isValid) {
this._allIcons.delete(iconKey);
continue;
}
if (this.checkDeadLine(icon)) {
// 从映射中移除
this._allIcons.delete(iconKey);
// 移除所有关联的位置映射
for (let [pos, key] of this._posToIconKey.entries()) {
if (key === iconKey) {
this._posToIconKey.delete(pos);
}
}
// 回收图标
this.iconFactory.recycleIcon(icon);
}
}
}
}
/**
* 停止处理
*/
stopProcess() {
let upIcon = this.getIconPosition(0);
let stopline = upIcon.y - 100; // 偏移量100
let topY = this.findHighestIconXorY(Array.from(this._allIcons.values()));
if (topY <= stopline) {
this.changeState(ROLLER_STATE.BOUNCE);
this.playBounceAnimation();
}
}
/**
* 播放回弹动画
*/
playBounceAnimation() {
let time = 0.1;
let offset = 50;
// 获取所有图标
let allIcons = Array.from(this._allIcons.values());
allIcons.forEach(icon => {
if (!icon || !icon.isValid) return;
let iconComponent = icon.getComponent(Icon);
if (!iconComponent) return;
// 获取图标的起始位置和高度
let startPos = iconComponent.startPos;
let lHeight = iconComponent.lHeight || 1;
// 获取图标应该在的位置
let position = this.getIconPosition(startPos, lHeight);
// 设置初始位置(向下偏移)
// icon.setPosition(position.add(v3(0, -offset, 0)));
icon.setPosition(position);
iconComponent.playSpawnAni();
// // 创建回弹动画
// tween(icon)
// .by(time, { position: v3(0, offset, 0) })
// .start();
});
// 延迟切换到停止状态
this.scheduleOnce(() => {
this.changeState(ROLLER_STATE.STOP);
}, time);
}
// 添加一个集合来追踪已删除的位置
private _deletedPositions = new Set<number>();
/**
* 消除逻辑
* 一定是在静止状态消除的
* @param deleteMsg 删除信息
* */
deleteIconNode(positions: number[]) {
// 记录被处理过的图标键
let processedPos = new Set<number>();
// 处理每个位置
for (let pos of positions) {
// 如果此图标已处理过,跳过
if (processedPos.has(pos)) {
continue;
}
let iconKey = this._posToIconKey.get(pos);
// if (!iconKey) {
// console.error('deleteIconNode iconKey is null', pos);
// continue;
// }
let iconNode = this._allIcons.get(iconKey);
// if (!iconNode || !iconNode.isValid) {
// console.error('deleteIconNode iconNode is null', pos);
// continue;
// }
let iconComponent = iconNode.getComponent(Icon);
// if (!iconComponent) {
// console.error('deleteIconNode iconComponent is null', pos);
// continue;
// }
let startPos = iconComponent.startPos;
// 从allIcons中删除图标
this._allIcons.delete(iconKey);
let height = iconComponent.lHeight || 1;
// 移除所有关联的位置映射
if (height > 1) {
// 对于n*1图标需要清除所有占用的位置
for (let i = 0; i < height; i++) {
this._posToIconKey.delete(startPos + i);
// 标记此图标已处理
processedPos.add(startPos + i);
}
} else {
this._posToIconKey.delete(pos);
// 标记此图标已处理
processedPos.add(pos);
}
iconComponent.playWinAni(true);
iconComponent.playDeleteAni();
this.scheduleOnce(() => {
this.iconFactory.recycleIcon(iconNode);
}, 1.2)
}
this.scheduleOnce(() => {
this.node.emit(ROLLER_EVENT.ICON_DELETED, this._rollerId);
}, 1.2)
}
// 播放动画
playFrameTypeChangeAni(positions: number[]) {
// 记录被处理过的图标键
let processedPos = new Set<number>();
for (let pos of positions) {
// 如果此图标已处理过,跳过
if (processedPos.has(pos)) {
continue;
}
let iconKey = this._posToIconKey.get(pos);
if (!iconKey) continue;
let iconNode = this._allIcons.get(iconKey);
if (!iconNode || !iconNode.isValid) continue;
let iconComponent = iconNode.getComponent(Icon);
if (!iconComponent) continue;
let startPos = iconComponent.startPos;
let height = iconComponent.lHeight || 1;
if (height > 1) {
for (let i = 0; i < height; i++) {
processedPos.add(startPos + i);
}
} else {
processedPos.add(startPos);
}
iconComponent.playWinAni(true);
iconComponent.playChangeAni(true);
}
}
chanegeIconAndFrameType(data: any[]) {
for (let i = 0; i < data.length; i++) {
let oldStartPos = data[i].oldStartPos;
let newIndex = data[i].newIndex;
let newFrameType = data[i].newFrameType;
let lheight = data[i].lheight || 1;
// 获取该位置对应的iconKey
const iconKey = this._posToIconKey.get(oldStartPos);
if (!iconKey) {
console.error('changeIconAndFrameType: iconKey is null for position', oldStartPos);
return;
}
// 获取对应的图标节点
const iconNode = this._allIcons.get(iconKey);
if (!iconNode || !iconNode.isValid) {
console.error('changeIconAndFrameType: iconNode is null or invalid for position', oldStartPos);
return;
}
// 获取Icon组件
const iconComponent = iconNode.getComponent(Icon);
if (!iconComponent) {
console.error('changeIconAndFrameType: iconComponent is null for position', oldStartPos);
return;
}
iconComponent.playChangeAni(false);
// 1. 从数据结构中删除旧图标
this._allIcons.delete(iconKey);
// 回收旧图标节点
this.iconFactory.recycleIcon(iconNode);
// 创建新图标
// 创建新的图标节点
const newIcon = this.iconFactory.icfactoryCreateIcon(newIndex);
// 初始化新的Icon组件
newIcon.getComponent(Icon).initIcon(newIndex, lheight, iconKey, newFrameType, this._rollerId);
// 设置新图标的位置
const newPos = this.getIconPosition(oldStartPos, lheight);
newIcon.setPosition(newPos);
// 添加到场景
this._content.addChild(newIcon);
// 3. 更新Roller的数据结构
// 将新图标添加到_allIcons中
this._allIcons.set(iconKey, newIcon);
}
}
/**
* 创建新icon
* @param createMsg 信息
*/
createNewIconTop(createDatas: number[][], CroSymbols: any) {
// 获取所有图标
let topY = this.getIconPosition(0, 1);
//总共掉落了多少格
let fallDownNum = 0
//已经计算的格数
let nowDownNum = 0
for (let i = 0; i < createDatas.length; i++) {
fallDownNum += createDatas[i].length
}
for (let i = 0; i < createDatas.length; i++) {
let iconHeight = createDatas[i].length
let startPos = nowDownNum - fallDownNum;
let iconIndex = createDatas[i][0];
let iconKey = this.generateIconKey(startPos, iconHeight, startPos - iconHeight + 1);
let icon = this.iconFactory.icfactoryCreateIcon(iconIndex);
let iconFramType = 0
if (CroSymbols) {
for (let key in CroSymbols) {
if (CroSymbols[key].PosFirst / 5 == this._rollerId) {
if (CroSymbols[key].PosFirst % 5 == i) {
iconFramType = CroSymbols[key].Type
}
}
}
}
icon.getComponent(Icon).initIcon(iconIndex, iconHeight, iconKey, iconFramType, this._rollerId);
let y = topY.y + (((fallDownNum - nowDownNum) - 0.5 * (iconHeight - iconHeight > 1 ? 1 : 0)) * this.iconHeight);
icon.setPosition(0, y, 0); this._content.addChild(icon);
this._allIcons.set(iconKey, icon);
this._posToIconKey.set(startPos, iconKey);
nowDownNum += iconHeight
}
this.node.emit(ROLLER_EVENT.ICON_CREATE, this._rollerId);
}
/** icon进行掉落移动 */
iconFallDown(data: number[], CroSymbols: any) {
let updates = [];
let sortNewIconStartPos = this.getNewIconsStartPos(data, CroSymbols);
let sortIcons = this.getSortIcons();
for (let i = 0; i < sortNewIconStartPos.length; i++) {
let newStartPos = sortNewIconStartPos[i];
let oldIcon = sortIcons[i];
let oldIconStartPos = oldIcon.startPos;
if (oldIconStartPos === newStartPos) {
continue;
}
let oldIconNode = oldIcon.icon;
let oldIconComponent = oldIcon.component;
let oldIconkey = oldIconComponent.iconKey;
let lHeight = oldIconComponent.lHeight || 1;
let newIconkey = this.generateIconKey(newStartPos, 1, newStartPos);
let newY = this.getIconPosition(newStartPos, lHeight).y;
let oldY = oldIconNode.position.y;
updates.push({
node: oldIconNode,
component: oldIconComponent,
oldKey: oldIconkey,
oldStartPos: oldIconStartPos,
newStartPos: newStartPos,
newKey: newIconkey,
height: lHeight,
newY: newY,
})
}
let delayBetweenIcons = 0.05; // 每个图标之间的掉落延迟
// 添加依次掉落效果
for (let update of updates) {
let fallDelay = update.index * delayBetweenIcons; // 根据索引计算延迟
let fallTime = 0.3; // 掉落动画时间
// 清除可能存在的动画
tween(update.node).stop();
// 添加延迟和掉落动画
tween(update.node)
.delay(fallDelay) // 添加延迟
.to(fallTime, { position: v3(0, update.newY, 0) }, {
easing: 'quadIn' // 下落加速
})
.start();
}
for (let update of updates) {
this._allIcons.delete(update.oldKey);
for (let i = 0; i < update.height; i++) {
this._posToIconKey.delete(update.oldStartPos + i);
}
}
// 再添加所有新映射
for (let update of updates) {
// 添加新的映射
update.component.iconKey = update.newKey;
this._allIcons.set(update.newKey, update.node);
for (let i = 0; i < update.height; i++) {
this._posToIconKey.set(update.newStartPos + i, update.newKey);
}
}
// 根据最长的动画时间调整音效和事件触发时间
let totalFallTime = updates.length > 0 ?
(updates.length - 1) * delayBetweenIcons + 0.3 : 0.3;
// 在所有图标都完成掉落后触发事件
this.scheduleOnce(() => {
this.node.emit(ROLLER_EVENT.ICON_FALLEN, this._rollerId);
}, totalFallTime + 0.1); // 添加一点额外时间确保所有动画完成
}
getSortIcons() {
let iconInfos: { icon: Node, component: Icon, startPos: number }[] = [];
// 收集所有图标信息
for (let [iconKey, iconNode] of this._allIcons.entries()) {
if (!iconNode || !iconNode.isValid) continue;
let iconComponent = iconNode.getComponent(Icon);
if (!iconComponent) continue;
// 记录图标信息
iconInfos.push({
icon: iconNode,
component: iconComponent,
startPos: iconComponent.startPos
});
}
// 按startPos从小到大排序
iconInfos.sort((a, b) => a.startPos - b.startPos);
return iconInfos;
}
getNewIconsStartPos(data: number[], CroSymbols: any) {
// 存储所有图标的startPos
let startPositions: number[] = [];
// 记录已处理的位置
let processedPositions = new Set<number>();
// 记录已经处理的pos
let processedPos = new Set<number>();
// 首先处理不规则图标n*1图标
if (CroSymbols) {
for (let pos in CroSymbols) {
let id = CroSymbols[pos].id;
if (processedPos.has(id)) continue;
processedPos.add(id);
let iconSpecialMsg = CroSymbols[pos];
let startPos = iconSpecialMsg.startPos;
let endPos = iconSpecialMsg.endPos;
// 添加不规则图标的startPos
startPositions.push(startPos);
// 标记所有被占用的位置
for (let i = startPos; i <= endPos; i++) {
processedPositions.add(i);
}
}
}
// 然后处理常规图标
for (let i = 0; i < data.length; i++) {
// 如果该位置未被处理(不是不规则图标的一部分)
if (!processedPositions.has(i)) {
startPositions.push(i);
}
}
// 从小到大排序
startPositions.sort((a, b) => a - b);
return startPositions;
}
}