// /** // * 负责单个滚轮的创建、滚动、停止等逻辑 // */ // import { // _decorator, // Node, // UITransform, // Vec2, // v2, // Vec3, // v3, // tween, // Tween, // Mask, // } from 'cc'; // import { IconFactory } from './IconFactory'; // import { Icon } from './Icon'; // import { BaseRoller, ROLLER_STATE } from './BaseRoller'; // import { ROLLER_EVENT } from './Define'; // import { callGameApi } from 'db://assets/Loading/scripts/comm'; // let { ccclass, property, executeInEditMode } = _decorator; // /** // * 滚轮组件类 // */ // @ccclass('HRoller') // @executeInEditMode // export class HRoller extends BaseRoller { // // 编辑器属性 // @property({ tooltip: '列数' }) // col: number = 3; // // 本地格式化相关 // @property // _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.col; i++) { // let randomIndex = Math.floor(Math.random() * this.iconFactory.getIconNum()); // this.createNormalIcon(i, randomIndex); // } // } // _cachedContentWidth: number = 0; // _cachedAnchorX: number = 0; // /** // * 创建滚轮实例 // * @param id 滚轮ID // * @param row 行数 // * @param iconWidth 图标宽度 // * @param iconHeight 图标高度 // * @param iconFactory 图标工厂实例 // * @param anchor 锚点位置 // * @returns 新创建的滚轮实例 // */ // static create( // id: number, // col: number, // iconWidth: number, // iconHeight: number, // iconFactory: IconFactory, // anchor: Vec2 = v2(0.5, 0.5) // ): HRoller { // let rollerNode = new Node(`Roller${id}`); // rollerNode.addComponent(UITransform); // let roller = rollerNode.addComponent(HRoller); // roller._rollerId = id; // roller.col = col; // roller.iconWidth = iconWidth; // roller.iconHeight = iconHeight; // roller.iconFactory = iconFactory; // rollerNode.getComponent(UITransform).setAnchorPoint(anchor); // roller.resizeContentSize(); // roller.initRoller(id); // return roller; // } // /** // * 设置节点尺寸和位置 // */ // setupNodesSizeAndPosition() { // let totalWidth = this.iconWidth * this.col; // let anchorPoint = this.node.getComponent(UITransform).anchorPoint; // // 设置主节点尺寸 // this.node.getComponent(UITransform).setContentSize(totalWidth, this.iconHeight); // // 设置view节点 // this._view.setPosition(0, 0); // this._view.getComponent(UITransform).setContentSize(totalWidth, this.iconHeight); // this._view.getComponent(UITransform).setAnchorPoint(anchorPoint); // this._view.getComponent(UITransform).height *= 2; // // 设置content节点 // this._content.setPosition(0, 0); // this._content.getComponent(UITransform).setContentSize(totalWidth, this.iconHeight); // this._content.getComponent(UITransform).setAnchorPoint(anchorPoint); // this._content.removeAllChildren(); // } // /** // * 获取图标的实际坐标 // * @param pos 图标位置索引 // * @param height 图标高度 // * @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._cachedContentWidth) { // this._cachedContentWidth = this._content.getComponent(UITransform).width; // this._cachedAnchorX = this._content.getComponent(UITransform).anchorX; // } // // 计算基准位置 // let contentWidth = this._cachedContentWidth; // let anchorX = this._cachedAnchorX; // // 计算最左边位置 // let leftX = -contentWidth * (1 - anchorX); // // 计算第一个位置的中心x坐标 // let firstCenterX = leftX + this.iconWidth / 2; // // 计算当前位置的中心X坐标 // let centerX = firstCenterX + pos * this.iconWidth; // // 对于大图标,需要调整位置 // let finalX = centerX; // if (size > 1) { // // 大图标的中心点应该下移,使其顶部对齐格子 // // 对于高度为3的图标,中心点应该下移1个格子高度 // finalX = centerX + (size - 1) * this.iconWidth / 2; // } // // 创建最终位置 // let position = v3(finalX, 0, 0); // // 缓存结果 // this._positionCache.set(cacheKey, position.clone()); // return position; // } // /** // * 初始化性能优化相关的缓存 // */ // initCache() { // this._cachedUITransform = this._content.getComponent(UITransform); // this._cachedContentWidth = this._cachedUITransform.width; // this._cachedAnchorX = this._cachedUITransform.anchorX; // } // /** // * 收集现有图标 // */ // collectExistingIcons() { // for (let i = 0; i < this.col; 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.changeState(ROLLER_STATE.STOP); // 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.col; 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(); // } // } // /** // * 创建最后一页图标 // */ // createLastPage() { // let data = this._stopData; // if (!data) return; // // 计算最右边icon基准位置 // let rightX = this.getIconPosition(this.col - 1).x; // let icons = this._info.icons; // if (icons.length > 0) { // rightX = Math.max(rightX, this.findHighestIconXorY(icons)); // } // // 清除已有的位置映射,准备重新创建 // this._allIcons.clear(); // this._posToIconKey.clear(); // // 从左到右依次创建图标(从位置0开始) // for (let i = 0; i < data.length; i++) { // // 如果当前位置已被特殊图标占用,跳过 // 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 x = rightX + (pos + 1) * this.iconWidth; // icon.setPosition(x, 0, 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._cachedContentWidth) { // this._cachedContentWidth = this._content.getComponent(UITransform).width; // this._cachedAnchorX = this._content.getComponent(UITransform).anchorX; // } // let iconComponent = icon.getComponent(Icon); // let lheight = iconComponent.lHeight; // let iconBody = (lheight - 1) * this.iconWidth + this.iconWidth / 2; // let deadLine = -(this._cachedContentWidth * this._cachedAnchorX) - iconBody; // return icon.position.x <= deadLine; // } // /** // * 补充新的图标 // */ // suppleIcon() { // let bornLine = this.getIconPosition(this.col - 1).x; // let icons = this._info.icons; // // 找到最右边的的图标X坐标 // let rightX = this.findHighestIconXorY(icons); // // 如果最右边的图标低于出生线,创建新图标 // if (rightX < bornLine) { // this.createRandomIcon(); // } // } // /** // * 创建随机图标 // */ // createRandomIcon() { // let iconIndex = this.getRandomIconIndex(); // let newX = this.computeNewIconXorY(); // let icon = this.iconFactory.icfactoryCreateIcon(iconIndex); // // 设置快速图标效果 // if (this.shouldShowFastIcon()) { // icon.getComponent(Icon).showFastIcon(true); // } // icon.setPosition(newX, 0, 0); // this._content.addChild(icon); // this._info.icons.push(icon); // this.node.emit(ROLLER_EVENT.ON_R_ICON_CREATE, this._rollerId, icon); // } // /** // * 找到最右边的图标X坐标 // * @param icons 图标数组 // * @returns 最右边的X坐标 // */ // findHighestIconXorY(icons: Node[]): number { // return icons.reduce((maxX, icon) => { // if (!icon || !icon.active) return maxX; // let iconComponent = icon.getComponent(Icon); // if (!iconComponent) return maxX; // let lHeight = iconComponent.lHeight || 1; // let iconX = icon.position.x; // // 对于高度大于1的图标,考虑其顶部位置 // if (lHeight > 1) { // // 计算图标顶部位置:当前位置 + 高度差 * 图标高度 / 2 // return Math.max(maxX, iconX + (lHeight - 1) * this.iconWidth / 2); // } else { // return Math.max(maxX, iconX); // } // }, -999); // } // /** // * 计算新图标的X坐标 // */ // computeNewIconXorY(): number { // let icons = this._info.icons; // // 如果没有图标,使用初始位置 // if (!icons.length) { // return this.getIconPosition(this.col - 1).x + this.iconWidth; // } // // 找到最右边的图标X坐标 // let rightX = this.findHighestIconXorY(icons); // // 新图标位置 = 最高图标位置 + 图标高度 // return rightX + this.iconWidth; // } // /** // * 清理资源 // */ // onDestroy() { // this._cachedUITransform = null; // this._cachedContentWidth = 0; // this._cachedAnchorX = 0; // this._positionCache.clear(); // } // /** // * 滚轮移动 // * @param dt 时间增量 // */ // rollerMove(dt: number) { // // 计算移动向量 // let speed = this._info.speed; // let move = speed * dt; // let moveVec = v3(move, 0, 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.col; 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 rightIcon = this.getIconPosition(this.col - 1); // let stopline = rightIcon.x - 100; // 偏移量100 // let topX = this.findHighestIconXorY(Array.from(this._allIcons.values())); // if (topX <= 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(-offset, 0, 0))); // icon.setPosition(position); // iconComponent.playSpawnAni(); // // 创建回弹动画 // // tween(icon) // // .by(time, { position: v3(offset, 0, 0) }) // // .start(); // }); // // 延迟切换到停止状态 // this.scheduleOnce(() => { // this.changeState(ROLLER_STATE.STOP); // }, time); // } // /** // * 消除逻辑 // * 一定是在静止状态消除的 // * @param deleteMsg 删除信息 // * */ // deleteIconNode(positions: number[]) { // // 记录被处理过的图标键 // let processedPos = new Set(); // // 处理每个位置 // 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.node.emit(ROLLER_EVENT.ICON_DELETED, this._rollerId); // } // playFrameTypeChangeAni(positions: number[]): void { // for (let pos of positions) { // 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; // iconComponent.playWinAni(true); // } // } // chanegeIconAndFrameType(data: any[]): void { // return; // } // /** // * 创建新icon // * @param createMsg 信息 // */ // createNewIconTop(createDatas: number[]) { // // 获取所有图标 // let rightX = this.getIconPosition(this.col - 1, 1).x; // for (let i = 0; i < createDatas.length; i++) { // let pos = this.col + i + 1; // let iconIndex = createDatas[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 x = rightX + (i + 1) * this.iconWidth; // icon.setPosition(x, 0, 0); // this._content.addChild(icon); // this._allIcons.set(iconKey, icon); // this._posToIconKey.set(pos, iconKey); // } // this.node.emit(ROLLER_EVENT.ICON_CREATE, this._rollerId); // } // /** icon进行掉落移动 */ // iconFallDown(data: number[], CroSymbols: any) { // // 更新所有icon的iconKey和posToIconKey // 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 newX = this.getIconPosition(newStartPos, lHeight).x; // let oldX = oldIconNode.position.x; // updates.push({ // node: oldIconNode, // component: oldIconComponent, // oldKey: oldIconkey, // oldStartPos: oldIconStartPos, // newStartPos: newStartPos, // newKey: newIconkey, // height: lHeight // }) // let time = 0.3; // tween(oldIconNode) // .to(time, { position: v3(newX, 0, 0) }) // .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); // } // } // this.scheduleOnce(() => { // this.node.emit(ROLLER_EVENT.ICON_FALLEN, this._rollerId); // }, 0.5) // } // 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(); // // 记录已经处理的pos // let processedPos = new Set(); // // 首先处理不规则图标(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; // } // }