rp_11001/assets/Game/scripts/game/RollerManager.ts
TJH fa4c6036b7
All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 1m13s
节奏调整
2025-12-29 16:28:18 +08:00

846 lines
28 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, Component, Mask, Node, Sprite, SpriteFrame, UITransform, v3, Vec3 } from 'cc';
import { IconFactory } from './IconFactory';
import { Roller } from './Roller';
import { GameData, ICON_HEIGHT, ICON_WIDTH, ROLLER_COMBINE_EVENT, ROLLER_EVENT } from './Define';
import { AudioManager } from '../../../Loading/scripts/manager/AudioManager';
import { BaseRoller } from './BaseRoller';
let { ccclass, property, executeInEditMode } = _decorator;
// 帧到启动ID映射按帧序
let frameOrder = [
{ frame: 1, ids: [5] },
{ frame: 3, ids: [0] },
{ frame: 9, ids: [1, 6] },
{ frame: 14, ids: [2, 7] },
{ frame: 20, ids: [3] },
{ frame: 22, ids: [8] },
{ frame: 27, ids: [4] },
];
let fps = 60;
@ccclass('RollerManager')
@executeInEditMode
export class RollerManager extends Component {
@property({ tooltip: '图标的宽度' })
iconWidth: number = ICON_WIDTH;
@property({ tooltip: '图标的高度' })
iconHeight: number = ICON_HEIGHT;
@property({ tooltip: '图标之间的水平距离' })
iconHMerge: number = 0;
@property({ type: IconFactory, tooltip: '图标工厂' })
iconFactory: IconFactory = null;
rollerMsg: any[] = [
{ row: 5, col: 1 },
{ row: 5, col: 1 },
{ row: 5, col: 1 },
{ row: 5, col: 1 },
{ row: 5, col: 1 },
{ row: 5, col: 1 },
];
// 竖向滚轮数组
vRollers: Roller[] = [];
// 滚轮数组
allRollers: Roller[] = [];
// 是否快速旋转
_isFastSpin: boolean = false;
// 是否手动停止
_isManualStop: boolean = false;
// spinData
_spinData: GameData = null;
/** 分割过的数据,一位数组改为二维数组, 每个元素代表一个滚轮 */
_resultStopData: number[][] = [];
// 是否是免费游戏
_isFreeSpin: boolean = false;
// 不规则图标信息
_CroSymbols: any = null;
// 处理过的不规则icon信息
_processedCroSymbols: any = null;
private vMaskNode: Node = null;
// 添加计数器
private _deletedRollerCount: number = 0;
private _createdRollerCount: number = 0;
private _fallenRollerCount: number = 0;
@property
_format = false;
@property({ tooltip: '格式化' })
get format(): boolean {
return this._format;
}
set format(a: boolean) {
this._format = a;
this.node.removeAllChildren();
this.allRollers = [];
this.vRollers = [];
this.vMaskNode = this.createMaskNode('VMask');
this.node.addChild(this.vMaskNode);
let rollerLength = this.rollerMsg.length;
for (let i = 0; i < rollerLength; i++) {
let rollerMsg = this.rollerMsg[i];
let roller = Roller.create(i, rollerMsg.row, this.iconWidth, this.iconHeight, this.iconFactory);
roller.format = true;
this.vMaskNode.addChild(roller.node);
let rollerPosition = this.getRollerPosition(i);
roller.node.setPosition(rollerPosition);
this.vRollers.push(roller);
this.allRollers.push(roller);
// }
}
}
private createMaskNode(name: string): Node {
let maskNode = new Node();
maskNode.name = name;
let comp = maskNode.addComponent(Mask);
let UIComponent = maskNode.addComponent(UITransform);
comp.type = Mask.Type.GRAPHICS_RECT;
UIComponent.setContentSize(1040, 830)
return maskNode;
}
protected onLoad(): void {
this.format = true;
this.scatterPos = [];
this.registerEvent();
// 重置计数器
this._deletedRollerCount = 0;
this._createdRollerCount = 0;
this._fallenRollerCount = 0;
}
protected update(dt: number): void {
for (let i = 0; i < this.allRollers.length; i++) {
let roller = this.allRollers[i];
roller.localUpdate(dt);
}
}
registerEvent() {
for (let lx = 0; lx < this.allRollers.length; lx++) {
let roller = this.allRollers[lx];
roller.node.on(ROLLER_EVENT.ON_R_ICON_CREATE, this.onRollerRIconCreate, this);
roller.node.on(ROLLER_EVENT.LAST_PAGE_CREATE, this.onRollerLastPageCreate, this);
roller.node.on(ROLLER_EVENT.ROLLER_BOUNCE, this.onRollerBounce, this);
roller.node.on(ROLLER_EVENT.ROLLER_DECELERATE, this.onRollerSlowDown, this);
roller.node.on(ROLLER_EVENT.ROLLER_STOP, this.onRollerStop, this);
roller.node.on(ROLLER_EVENT.ROLLER_UNIFORM, this.onRollerUniform, this);
roller.node.on(ROLLER_EVENT.ICON_DELETED, this.onRollerIconDeleted, this);
roller.node.on(ROLLER_EVENT.ICON_CREATE, this.onRollerIconCreate, this);
roller.node.on(ROLLER_EVENT.ICON_FALLEN, this.onRollerIconFallen, this);
}
}
setFastSpin(isFastSpin: boolean) {
this._isFastSpin = isFastSpin;
this.allRollers.forEach(roller => {
roller.setFastSpin(isFastSpin);
})
}
getIsFastSpin(): boolean {
return this._isFastSpin;
}
setIsFreeSpin(isFreeSpin: boolean) {
this._isFreeSpin = isFreeSpin;
}
changeSpeedFast() {
this.allRollers.forEach(roller => {
if (roller.isScroll()) {
roller.changeSpeed();
}
})
}
// 随机创建ICON回调
onRollerRIconCreate() {
return;
}
// 最后一页创建的回调
onRollerLastPageCreate(rollerId: number) {
if (this._isFastSpin) return;
let isExpect = this.checkNextRollerExpect(rollerId);
let nextStopRollerId = this.getNextRollerIndex(rollerId);
let stopSpeedData = this._isFastSpin ? [[0, 6000]] : [[0.1, 3500]];
if (!this._isFastSpin) {
stopSpeedData = isExpect ? [[1, 4000], [0.5], [0.1, 2500], [0.5], [0.5, 725]] : [[0.1, 3500]];
}
if (nextStopRollerId != -1) {
let nextStopRollerCroSymbols = this._processedCroSymbols[nextStopRollerId];
this.allRollers[nextStopRollerId].setCroSymbols(nextStopRollerCroSymbols);
this.allRollers[nextStopRollerId].stopScroll(this._resultStopData[nextStopRollerId], stopSpeedData);
}
return;
}
scatterPos: number[] = [];
checkNextRollerExpect(rollerId: number, needScatterCount: number = 3) {
let curScatterCount = 0;
this.scatterPos = [];
// 检查所有已经停止的垂直滚轮(包括当前滚轮)
for (let i = 0; i <= rollerId; i++) {
const rollerData = this._resultStopData[i];
if (!rollerData) continue;
// 检查每个位置
for (let j = 0; j < rollerData.length; j++) {
// 检查是否有交叉符号覆盖该位置
if (this._processedCroSymbols &&
this._processedCroSymbols[i] &&
this._processedCroSymbols[i][j]) {
const symbolInfo = this._processedCroSymbols[i][j];
// 只计算开始位置,避免重复计数
if (symbolInfo.isStart && symbolInfo.iconIndex === 1) {
curScatterCount++;
this.scatterPos.push(i * 5 + symbolInfo.startPos);
}
}
// 如果位置没有被交叉符号覆盖且是scatter
else if (rollerData[j] === 1) {
curScatterCount++;
this.scatterPos.push(i * 5 + j);
}
}
}
return curScatterCount >= needScatterCount;
}
getScatterPos(): number[] {
return this.scatterPos;
}
// 滚轮回弹的回调
onRollerBounce(rollerId: number) {
return;
}
// 滚轮减速的回调
onRollerSlowDown() {
return;
}
// 滚轮停止的回调
onRollerStop(rollerId: number) {
this.node.emit(ROLLER_COMBINE_EVENT.ONE_ROLLER_STOP, rollerId);
// 检测当前滚轮的icon下标是否是8
let stopData = this._resultStopData[rollerId];
let isWild = stopData.indexOf(0) !== -1;
let isScatter = stopData.indexOf(1) !== -1;
if (!this._isFreeSpin && !this._isManualStop && !this._isFastSpin) {
if (isWild && !isScatter) {
AudioManager.instance.playSFX('Appear_Wild_Sound');
}
if (isScatter) {
AudioManager.instance.playSFX('Appear_Scatter_Sound');
}
if (!isWild && !isScatter && this._isFastSpin) {
AudioManager.instance.playSFX('Scroll_Stop_Sound');
}
}
let allRollerStop = true;
for (let i = 0; i < this.allRollers.length; i++) {
let roller = this.allRollers[i];
if (roller.isScroll()) allRollerStop = false;
}
if (allRollerStop) {
this.node.emit(ROLLER_COMBINE_EVENT.ALL_ROLLER_STOP);
if (this._isFastSpin || this._isManualStop) {
let hasScatter = this.scatterPos.length > 0;
let hasWild = false;
this._resultStopData.forEach(stopData => {
if (stopData.indexOf(0) !== -1) {
hasWild = true;
}
})
if (hasWild && !hasScatter) {
AudioManager.instance.playSFX('Appear_Wild_Sound');
}
if (hasScatter) {
AudioManager.instance.playSFX('Appear_Scatter_Sound');
}
if (!hasWild && !hasScatter) {
AudioManager.instance.playSFX('Scroll_StopQuick_Sound');
}
}
}
}
// 滚轮匀速时候的回调
onRollerUniform() {
return;
}
// 滚轮icon删除的回调
onRollerIconDeleted(rollerId: number) {
this._deletedRollerCount++;
if (this._deletedRollerCount >= this.allRollers.length) {
this._deletedRollerCount = 0; // 重置计数器
this.node.emit(ROLLER_COMBINE_EVENT.ALL_ROLLER_ICONS_DELETED);
}
}
// 滚轮icon创建的回调
onRollerIconCreate(rollerId: number) {
this._createdRollerCount++;
if (this._createdRollerCount >= this.allRollers.length) {
this._createdRollerCount = 0; // 重置计数器
this.node.emit(ROLLER_COMBINE_EVENT.ALL_ROLLER_ICONS_CREATED);
}
}
// 滚轮icon掉落的回调
onRollerIconFallen(rollerId: number) {
this._fallenRollerCount++;
if (this._fallenRollerCount >= this.allRollers.length) {
this._fallenRollerCount = 0; // 重置计数器
this.node.emit(ROLLER_COMBINE_EVENT.ALL_ROLLER_ICONS_FALLEN);
}
}
// 滚轮是否在滚动
isScroll(): boolean {
for (let lx = 0; lx < this.allRollers.length; lx++) {
let roller = this.allRollers[lx];
if (roller.isScroll()) return true;
}
return false;
}
// 初始化滚轮数据
initRollerWithIcon(data: GameData) {
this._spinData = data;
let bottomData = data.Symbol.Middle;
this._CroSymbols = data.CroSymbols;
// 分割数据
this._resultStopData = [...this.splitArray(bottomData, [5, 5, 5, 5, 5, 5])];
// 处理n*1符号
let processedCroSymbols = this.processCroSymbolsForRollers();
for (let i = 0; i < this.allRollers.length; i++) {
let roller = this.allRollers[i];
let rollerCroSymbols = processedCroSymbols[i];
roller.initRollerWithIcon(i, this._resultStopData[i], rollerCroSymbols);
}
}
/**
* 只处理竖向滚轮
* 处理n*1符号数据为每个滚轮准备对应的n*1符号信息
* @returns 处理后的n*1符号数据数组每个元素对应一个滚轮
*/
private processCroSymbolsForRollers(): any[] {
this._processedCroSymbols = [];
let row = 5;
let col = 6;
// 如果没有交叉符号数据,返回空对象数组
if (!this._CroSymbols) {
return new Array(col).fill({});
}
// 为每个滚轮创建一个空对象
let rollerSymbols: any[] = [];
for (let i = 0; i < col; i++) {
rollerSymbols.push({});
}
// 遍历所有交叉符号
for (let symbolId in this._CroSymbols) {
let symbol = this._CroSymbols[symbolId];
// 计算符号所在的滚轮索引
let rollerIndex = Math.floor(symbol.PosFirst / 5);
// 计算在滚轮中的起始和结束位置
let startPos = symbol.PosFirst % row;
let endPos = symbol.PosLast % row;
// 在滚轮的每个位置上设置符号信息
for (let pos = startPos; pos <= endPos; pos++) {
rollerSymbols[rollerIndex][pos] = {
id: symbolId,
isStart: pos === startPos,
isEnd: pos === endPos,
startPos: startPos,
endPos: endPos,
lHeight: endPos - startPos + 1,
Type: symbol.Type,
iconIndex: symbol.Symbol
};
}
}
this._processedCroSymbols = [...rollerSymbols];
return this._processedCroSymbols;
}
// 滚轮Icon生成规则
setRollerIconRule(rollerIconRule: number[][]) {
for (let i = 0; i < this.allRollers.length; i++) {
this.allRollers[i].setRollerIconRule(rollerIconRule[i]);
}
}
getIconNode(pos: number): Node {
let lx = this.getLx(pos);
let ly = this.getLy(pos);
let roller = this.allRollers[lx];
return roller.getIconNode(ly);
}
getLx(pos: number): number {
let currentPos = pos;
for (let i = 0; i < this.rollerMsg.length; i++) {
let roller = this.rollerMsg[i];
let rollerSize = roller.row * roller.col;
if (currentPos < rollerSize) {
return i;
}
currentPos -= rollerSize;
}
return -1; // 如果位置超出范围,返回-1
}
getLy(pos: number): number {
let currentPos = pos;
// 先找到对应的滚轮
let rollerId = this.getLx(pos);
if (rollerId === -1) return -1;
// 计算在当前滚轮之前的所有位置数
for (let i = 0; i < rollerId; i++) {
let roller = this.rollerMsg[i];
currentPos -= (roller.row * roller.col);
}
let currentRoller = this.rollerMsg[rollerId];
// if (currentRoller.isHorizontal) {
// // 横向滚轮直接返回列位置
// return currentPos;
// } else {
// // 纵向滚轮返回行位置
return currentPos % currentRoller.row;
// }
}
// 获取第一个可以停止的滚轮id
getFirstRollerIndex(): number {
return 0;
}
// 获取下一个可以停止的滚轮id
getNextRollerIndex(id: number): number {
for (let lx = id + 1; lx < this.allRollers.length; lx++) {
return lx;
}
return -1;
}
resetInfo() {
this.allRollers.forEach(roller => {
roller.resetInfo();
})
}
getIsManualStop(): boolean {
return this._isManualStop;
}
// 滚轮开始滚动
startScroll() {
this._isManualStop = false;
this.unscheduleAllCallbacks();
if (this._isFastSpin) {
for (let i = 0; i < this.allRollers.length; i++) {
let roller = this.allRollers[i];
if (roller) {
if (this._isManualStop) return;
roller.startScroll();
}
}
} else {
this.allRollers.forEach(roller => {
roller.startScroll();
})
}
}
// 滚轮停止滚动
stopScroll(data: GameData) {
this._spinData = data;
this._resultStopData = [];
// 分割底盘数据
this._resultStopData = [...this.splitArray(data.Symbol.Middle, [5, 5, 5, 5, 5, 5])];
// 处理不对则icon
this._CroSymbols = data.CroSymbols;
let processedCroSymbols = this.processCroSymbolsForRollers();
let stopSpeedData = this._isFastSpin ? [[0, 6000]] : [[0.1, 3500]];
if (this._isFastSpin) {
// this.stopAllRollersImmediately(processedCroSymbols);
for (let i = 0; i < this.allRollers.length; i++) {
let stopData = this._resultStopData[i];
let roller = this.allRollers[i];
let rollerCroSymbols = processedCroSymbols[i];
roller.setCroSymbols(rollerCroSymbols);
roller.stopScroll(stopData, stopSpeedData)
}
} else {
// this.stopRollersInSequence(processedCroSymbols);
let firstRollerCroSymbols = processedCroSymbols[0];
this.allRollers[0].setCroSymbols(firstRollerCroSymbols);
this.allRollers[0].stopScroll(this._resultStopData[0], stopSpeedData);
}
}
stopRollersInSequence(processedCroSymbols: any[]) {
let standardStopDuration = [[0.1, 3500]];
}
manualStop(data: GameData) {
this._isManualStop = true;
this._resultStopData = [];
this._resultStopData = [...this.splitArray(data.Symbol.Middle, [5, 5, 5, 5, 5, 5])];
this._CroSymbols = data.CroSymbols;
let processedCroSymbols = this.processCroSymbolsForRollers();
for (let i = 0; i < this.allRollers.length; i++) {
let stopData = this._resultStopData[i];
let roller = this.allRollers[i];
let rollerCroSymbols = processedCroSymbols[i];
roller.setCroSymbols(rollerCroSymbols);
roller.manualStopScroll(stopData)
}
}
// 对服务器下发的数据进行操作
splitArray<T>(arr: T[], sizes: number[]): T[][] {
let result: T[][] = [];
let currentIndex = 0;
for (let size of sizes) {
let subArray = arr.slice(currentIndex, currentIndex + size);
result.push(subArray);
currentIndex += size;
}
return result;
}
// 获取滚轮的坐标
getRollerPosition(id: number): Vec3 {
let col = 6;
let hMiddle = Math.floor(col / 2);
let x = -(col % 2 == 0 ? hMiddle - 0.5 : hMiddle) * (this.iconWidth + this.iconHMerge);
let xdis = id * this.iconWidth + id * this.iconHMerge;
return v3(x + xdis, 0, 0);
}
// 获取icon坐标
getIconWorldPosition(pos: number) {
let lx = this.getLx(pos);
let roller = this.allRollers[lx];
return roller.getIconWorldPosition(this.getLy(pos));
}
getContentNode(pos: number): Node {
let lx = this.getLx(pos);
let roller = this.allRollers[lx];
return roller.getContentNode();
}
// 将图标移动到win层并处理删除和动画
handleWinIcons(winLayer: Node, deleteMsg: number[], aniData: number[]) {
if (deleteMsg.length === 0 && aniData.length === 0) {
return; // 没有需要处理的图标,直接返回
}
// 激活win层
winLayer.active = true;
// 1. 找出所有需要处理的唯一位置
let processedNodes = new Set();
let uniquePositions = [];
// 合并并去重处理位置
[...deleteMsg, ...aniData].forEach(pos => {
let iconNode = this.getIconNode(pos);
if (iconNode && !processedNodes.has(iconNode)) {
uniquePositions.push(pos);
processedNodes.add(iconNode);
}
});
// 2. 缓存winLayer的UITransform以提高性能
let winLayerTransform = winLayer.getComponent(UITransform);
// 3. 将所有需处理的图标移动到win层
uniquePositions.forEach(pos => {
let iconNode = this.getIconNode(pos);
if (iconNode) {
// 保存原始父节点和位置信息到Map中
this.winIconNodeMap.set(pos, {
node: iconNode,
originalParent: iconNode.parent,
originalPosition: iconNode.position.clone()
});
// 计算并设置正确位置
let worldPos = this.getIconWorldPosition(pos);
if (worldPos) {
let localPos = winLayerTransform.convertToNodeSpaceAR(worldPos);
iconNode.parent = winLayer;
iconNode.setPosition(localPos);
}
}
});
// 4. 准备删除操作的数据结构
let rollerDeletePositions = new Map<number, number[]>();
let rollerAniPos = new Map<number, number[]>();
// 5. 分类处理需要删除的位置
deleteMsg.forEach(pos => {
let lx = this.getLx(pos);
let ly = this.getLy(pos);
if (!rollerDeletePositions.has(lx)) {
rollerDeletePositions.set(lx, []);
}
rollerDeletePositions.get(lx).push(ly);
});
// 6. 分类处理需要动画的位置
aniData.forEach(pos => {
let lx = this.getLx(pos);
let ly = this.getLy(pos);
if (!rollerAniPos.has(lx)) {
rollerAniPos.set(lx, []);
}
rollerAniPos.get(lx).push(ly);
});
// 7. 执行删除操作
rollerDeletePositions.forEach((positions, lx) => {
if (positions.length > 0) {
this.allRollers[lx].deleteIconNode(positions);
}
});
AudioManager.instance.playSFX('Win_Frame_Sound');
// 8. 执行动画操作
rollerAniPos.forEach((positions, lx) => {
if (positions.length > 0) {
this.allRollers[lx].playFrameTypeChangeAni(positions);
}
});
// 保存一个引用以避免闭包中的引用问题
let positionsCopy = [...uniquePositions];
let winLayerRef = winLayer;
// 9. 计算动画播放时间并处理没有删除图标的roller
let animationTime = aniData.length > 0 ? 1.1 : 1.1;
let rollersWithoutDeleteOps = [];
for (let i = 0; i < this.allRollers.length; i++) {
if (!rollerDeletePositions.has(i) || rollerDeletePositions.get(i).length === 0) {
rollersWithoutDeleteOps.push(i);
}
}
// 10. 使用单个计时器处理所有没有删除操作的roller
if (rollersWithoutDeleteOps.length > 0) {
this.scheduleOnce(() => {
rollersWithoutDeleteOps.forEach(i => {
this.allRollers[i].node.emit(ROLLER_EVENT.ICON_DELETED, this.allRollers[i]);
});
}, animationTime);
}
// 11. 添加清理函数,根据需要在适当时机调用
this.scheduleOnce(() => {
AudioManager.instance.playSFX('Win_Eliminate_Sound');
// if (rollerAniPos.size > 0) {
// AudioManager.instance.playSFX('Symbol_Change_Sound');
// }
this.returnIconsFromWinLayer(winLayerRef, positionsCopy);
}, 0.8); // 在动画结束前稍早将图标移回
}
// 将图标从win层返回到原始层
private returnIconsFromWinLayer(winLayer: Node, positions: number[]) {
if (!winLayer || !positions || positions.length === 0) {
console.warn("Invalid arguments in returnIconsFromWinLayer");
if (winLayer) winLayer.active = false;
return;
}
positions.forEach(pos => {
let iconInfo = this.winIconNodeMap.get(pos);
// 检查图标信息是否存在
if (!iconInfo) {
console.warn(`No info found for icon at position ${pos}`);
return; // 跳过当前图标
}
let { node: iconNode, originalParent, originalPosition } = iconInfo;
// 检查图标是否还存在(可能已被删除)
if (iconNode && iconNode.isValid && originalParent && originalParent.isValid) {
try {
// 直接使用保存的原始父节点和位置信息
iconNode.parent = originalParent;
iconNode.position = originalPosition;
} catch (error) {
console.error(`Error moving icon back at position ${pos}:`, error);
}
} else {
console.warn(`Icon or original parent is invalid for position ${pos}`);
}
// 无论处理成功与否,都清理引用
this.winIconNodeMap.delete(pos);
});
// 隐藏win层
winLayer.active = false;
}
changeIconAndFrameType(panChanges: any[]) {
let rollerChangePositions: Map<number, any[]> = new Map();
panChanges.forEach(change => {
let lx = this.getLx(change.oldStartPos);
let ly = this.getLy(change.oldStartPos);
// 获取或创建该列的变化位置数组
if (!rollerChangePositions.has(lx)) {
rollerChangePositions.set(lx, []);
}
// 将oldStartPos改为ly并添加到对应列的数组中
change.oldStartPos = ly;
rollerChangePositions.get(lx).push(change);
})
rollerChangePositions.forEach((changes, lx) => {
this.allRollers[lx].chanegeIconAndFrameType(changes);
})
}
createNewIconTop(createDatas: number[][][], CroSymbols: any) {
this.allRollers.forEach((roller, index) => {
let rollerData = createDatas[index];
roller.createNewIconTop(rollerData, CroSymbols);
})
}
iconFallDown(data: GameData, inPan: boolean) {
this._spinData = data;
this._resultStopData = [];
this._fallenRollerCount = 0; // 重置计数器
this._deletedRollerCount = 0;
// 分割底盘数据
this._resultStopData = [...this.splitArray(data.Symbol.Middle, [5, 5, 5, 5, 5, 5])];
// 处理不对则icon
this._CroSymbols = data.CroSymbols;
let processedCroSymbols = this.processCroSymbolsForRollers();
this.allRollers.forEach((roller, index) => {
let stopData = this._resultStopData[index];
let rollerCroSymbols = processedCroSymbols[index];
roller.setCroSymbols(rollerCroSymbols);
this.scheduleOnce(() => {
roller.iconFallDown(stopData, rollerCroSymbols, inPan)
}, 0.03 * index)
})
// 在第一个图标开始掉落时播放音效
this.scheduleOnce(() => {
AudioManager.instance.playSFX('Win_Symbol_Fall');
}, 0.1);
}
onDestroy(): void {
// 清理事件监听
for (let roller of this.allRollers) {
roller.node.off(ROLLER_EVENT.ON_R_ICON_CREATE, this.onRollerRIconCreate, this);
roller.node.off(ROLLER_EVENT.LAST_PAGE_CREATE, this.onRollerLastPageCreate, this);
roller.node.off(ROLLER_EVENT.ROLLER_BOUNCE, this.onRollerBounce, this);
roller.node.off(ROLLER_EVENT.ROLLER_DECELERATE, this.onRollerSlowDown, this);
roller.node.off(ROLLER_EVENT.ROLLER_STOP, this.onRollerStop, this);
roller.node.off(ROLLER_EVENT.ROLLER_UNIFORM, this.onRollerUniform, this);
roller.node.off(ROLLER_EVENT.ICON_DELETED, this.onRollerIconDeleted, this);
roller.node.off(ROLLER_EVENT.ICON_CREATE, this.onRollerIconCreate, this);
roller.node.off(ROLLER_EVENT.ICON_FALLEN, this.onRollerIconFallen, this);
}
}
// 修改winIconNodeMap的类型为存储更多信息
private winIconNodeMap: Map<number, {
node: Node,
originalParent: Node,
originalPosition: Vec3
}> = new Map();
}