Code edit (4 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Uncaught ReferenceError: baseX is not defined' in or related to this line: 'tween(levelText, {' Line Number: 468
Code edit (7 edits merged)
Please save this source code
User prompt
seems there is a scope/closure bug with the code : ```levelText.down = function (level) { return function () { log("levelText currentState:", currentState, " isMenuReady=", isMenuReady); //{3F.2} if (!isMenuReady) { log("Menu not ready.", level); //{3F.2} return; } log("Tapped level number:", level); //{3F.2} if (level <= puzzleManager.maxReachedLevelNumber) { // Store initial width and height var initialWidth = levelText.width; var initialHeight = levelText.height; levelText.tint = tileColors[1]; // Animate width and height to 10 times their size and fade out tween(levelText, { width: initialWidth * 10, height: initialHeight * 10, alpha: 0 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { // Restore to initial values levelText.width = initialWidth; levelText.height = initialHeight; levelText.alpha = 1; puzzleManager.selectLevel(level); levelNumberText.setText(level, level + 1); changeGameState(GAME_STATE.NEW_ROUND); } }); } }; ``` resulting for example in the text not animating
Code edit (1 edits merged)
Please save this source code
User prompt
in menuBoard, implement animateExit the same way as animateEntrance but with target x = baseX - 2300 āŖš” Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1, @upit/tween.v1
Code edit (5 edits merged)
Please save this source code
User prompt
in menuboard animateEntrance, animate the menuGrid (levelTexts) the same way as cells āŖš” Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1, @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
Code edit (5 edits merged)
Please save this source code
User prompt
in MenuBoard, animateEntrance delay each col entrance by 200ms āŖš” Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1, @upit/tween.v1
Code edit (2 edits merged)
Please save this source code
User prompt
add logs in menuboard animateEntrance
Code edit (2 edits merged)
Please save this source code
User prompt
in animateEntrance, animate cells entrance from the right of the screen to their initial position (baseX; baseY) āŖš” Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1, @upit/tween.v1
Code edit (3 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting '0')' in or related to this line: 'self.menuGrid[row][col] = menuCell;' Line Number: 425
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting '0')' in or related to this line: 'self.menuGrid[row][col] = menuCell;' Line Number: 422
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting '0')' in or related to this line: 'self.menuGrid[row][col] = menuCell;' Line Number: 425
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting '0')' in or related to this line: 'self.menuGrid[row][col] = menuCell;' Line Number: 425
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting '0')' in or related to this line: 'self.menuGrid[row][col] = menuCell;' Line Number: 425
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting '0')' in or related to this line: 'self.menuGrid[row][col] = menuCell;' Line Number: 425
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting '0')' in or related to this line: 'self.menuGrid[row][col] = menuCell;' Line Number: 425
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting '0')' in or related to this line: 'self.menuGrid[row][col] = menuCell;' Line Number: 424
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting '0')' in or related to this line: 'self.menuGrid[row][col] = menuCell;' Line Number: 420
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ // BackgroundImage class to represent the background image var BackgroundImage = Container.expand(function () { var self = Container.call(this); // Asset Attachments var backgroundGraphics = self.attachAsset('gradientBackground', { anchorX: 0.5, anchorY: 0.5, x: centerX, y: centerY //tint: 0x00FF00 }); var nextBackgroundH = self.attachAsset('gradientBackground', { anchorX: 0.5, anchorY: 0.5, scaleX: -1, scaleY: 1, x: centerX + 2048, y: centerY }); var nextBackgroundV = self.attachAsset('gradientBackground', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: -1, x: centerX, y: centerY + 2732 }); var nextBackgroundC = self.attachAsset('gradientBackground', { anchorX: 0.5, anchorY: 0.5, scaleX: -1, scaleY: -1, x: centerX + 2048, y: centerY + 2732 //tint: 0xFF0000 }); var backgroundWall = self.attachAsset('startButton', { anchorX: 0.5, anchorY: 0.5, x: centerX, y: centerY, visible: false }); self.animateTransition = function (dirX, dirY) { if (puzzleManager.currentLevel == 1 || !dirX || !dirY) { // No anim for level 1 or reset return; } self.prepareSideBackgrounds(dirX, dirY); var deltaX = -dirX * 2048; var deltaY = -dirY * 2732; tween(backgroundGraphics, { x: backgroundGraphics.x + deltaX, y: backgroundGraphics.y + deltaY }, { duration: 1000, easing: tween.easeInOut }); tween(nextBackgroundH, { x: nextBackgroundH.x + deltaX, y: nextBackgroundH.y + deltaY }, { duration: 1000, easing: tween.easeInOut }); tween(nextBackgroundV, { x: nextBackgroundV.x + deltaX, y: nextBackgroundV.y + deltaY }, { duration: 1000, easing: tween.easeInOut }); tween(nextBackgroundC, { x: nextBackgroundC.x + deltaX, y: nextBackgroundC.y + deltaY }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { // Update main background like the transitioned one var referenceNextScaleX = Math.abs(dirX) == 0 ? nextBackgroundV.scale.x : nextBackgroundH.scale.x; var referenceNextScaleY = Math.abs(dirY) == 0 ? nextBackgroundH.scale.y : nextBackgroundV.scale.y; backgroundGraphics.scale.x = referenceNextScaleX; backgroundGraphics.scale.y = referenceNextScaleY; // Switch backgrounds backgroundGraphics.x = centerX; backgroundGraphics.y = centerY; nextBackgroundC.x += 2048; nextBackgroundC.y += 2732; // Restore initial positions of graphics nextBackgroundH.scale.x = -1 * backgroundGraphics.scale.x; nextBackgroundH.scale.y = 1 * backgroundGraphics.scale.y; nextBackgroundV.scale.x = 1 * backgroundGraphics.scale.x; nextBackgroundV.scale.y = -1 * backgroundGraphics.scale.y; nextBackgroundC.scale.x = -1 * backgroundGraphics.scale.x; nextBackgroundC.scale.y = -1 * backgroundGraphics.scale.y; } }); }; self.prepareSideBackgrounds = function (dirX, dirY) { // Position the next backgrounds depending on the currrent transition direction nextBackgroundH.x = centerX + dirX * 2048; nextBackgroundH.y = centerY; nextBackgroundV.x = centerX; nextBackgroundV.y = centerY + dirY * 2732; nextBackgroundC.x = centerX + dirX * 2048; nextBackgroundC.y = centerY + dirY * 2732; }; self.showWall = function () { backgroundWall.visible = true; backgroundWall.alpha = 0; tween(backgroundWall, { alpha: 1 }, { duration: 500, easing: tween.easeOut }); }; self.hideWall = function () { backgroundWall.alpha = 1; tween(backgroundWall, { alpha: 0 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { backgroundWall.visible = false; } }); }; return self; }); /***********************************************************************************************/ /******************************************* ASSETS CLASSES ************************************/ /***********************************************************************************************/ // HexTile class to represent each tile on the board var HexTile = Container.expand(function (value, col, row, levelData) { var self = Container.call(this); // Constants var interTileOffsetX = -2; var interTileOffsetY = -4; // relative to interTileOffsetX self.tileSizeX = LK.getAsset('hexTile', {}).width + interTileOffsetX; self.tileSizeY = self.tileSizeX * 0.75 - interTileOffsetY; // Properties self.value = value; self.originalValue = value; self.visible = false; self.col = col; self.row = row; self.neighbors = []; var tileX = col * self.tileSizeX; var tileY = row * self.tileSizeY; self.baseX = tileX; self.baseY = tileY; log("Tile Init row, col: ", row, col, " => ", tileX, tileY); self.x = tileX; self.y = tileY; // Asset Attachments var tileGraphicsShadow = self.attachAsset('hexTile', { anchorX: 0.5, anchorY: 0.5, x: 7, y: 5, tint: 0x000000, alpha: 0.70 }); var tileGraphics = self.attachAsset('hexTile', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0, tint: tileColors[self.value], alpha: 0.9 }); // Value text shadow var valueTextShadow = new Text2(self.value.toString(), { size: self.tileSizeX * 0.5, fill: 0x000000, //fill: tileColors[self.value], weight: 1000 }); valueTextShadow.anchor.set(0.5, 0.5); valueTextShadow.alpha = 0.1; valueTextShadow.x = tileGraphics.x + 12; valueTextShadow.y = tileGraphics.y - self.tileSizeY * 0.01 + 12; self.valueTextShadow = self.addChild(valueTextShadow); // Value Text var valueText = new Text2(self.value.toString(), { size: self.tileSizeX * 0.5, fill: 0xEAEEE8, dropShadow: false }); valueText.anchor.set(0.5, 0.5); valueText.x = tileGraphics.x; valueText.y = tileGraphics.y - self.tileSizeY * 0.01; self.valueText = self.addChild(valueText); // Functions self.setValue = function (newValue, depth) { log("setValue to ", newValue, depth); self.value = newValue; LK.setTimeout(function () { // Enclose operation in a timeout if (self.value === 0) { self.valueTextShadow.setText(""); self.valueText.setText(""); LK.getSound('tileRemove').play(); tween(tileGraphics, { scaleX: 0, scaleY: 0, rotation: Math.PI / 2 }, { duration: 1000, easing: tween.easeOut }); tween(tileGraphicsShadow, { scaleX: 0, scaleY: 0, rotation: Math.PI / 2 }, { duration: 1000, easing: tween.easeOut }); } else { LK.getSound('tileChangeValue').play(); self.valueText.setText(self.value.toString()); self.valueTextShadow.setText(self.value.toString()); } // Animate color change tween(tileGraphics, { tint: tileColors[self.value] }, { duration: 600, easing: tween.easeOut }); }, depth * 175); // Delay proportional to normalized distance }; self.setBasePosition = function (x, y) { self.x = x; self.y = y; self.baseX = x; self.baseY = y; }; self.shake = function () { log("shaking..."); tween(self, { rotation: 0.3 }, { duration: 150, easing: tween.bounceIn, onFinish: function onFinish() { tween(self, { rotation: -0.3 }, { duration: 150, easing: tween.bounceIn, onFinish: function onFinish() { tween(self, { rotation: 0 }, { duration: 150, easing: tween.bounceIn }); } }); } }); }; return self; }); // LevelNumberText class to represent the level number text var LevelNumberText = Container.expand(function (initialLevel) { var self = Container.call(this); self.displayedLevel = initialLevel; // Initialize level number text var levelText = new Text2(initialLevel.toString(), { size: 600, fill: 0x787878, weight: 1000, dropShadow: true, dropShadowAngle: Math.PI, dropShadowDistance: 10 }); levelText.anchor.set(0.5, 0.5); levelText.alpha = 0.2; levelText.blendMode = 2; levelText.x = centerX; levelText.y = centerY; levelText.visible = false; self.addChild(levelText); // Initialize next level number text var levelText2 = new Text2((initialLevel + 1).toString(), { size: 600, fill: 0x787878, weight: 1000, dropShadow: true, dropShadowAngle: Math.PI, dropShadowDistance: 10 }); levelText2.anchor.set(0.5, 0.5); levelText2.alpha = 0.2; levelText2.blendMode = 2; levelText2.x = centerX + 2048; levelText2.y = centerY + 2732; levelText2.visible = false; self.addChild(levelText2); // Method to update the level number self.updateLevel = function (newLevel, dirX, dirY) { if (newLevel != 1 && dirX && dirY) { if (newLevel == self.displayedLevel) { // When reseting current level show current level in text2 levelText2.setText(self.displayedLevel.toString()); } if (newLevel == 0) { // When reseting current level show current level in text2 levelText2.setText("THE\nEND"); } self.prepareTextTransition(dirX, dirY); var deltaX = -dirX * 2048; var deltaY = -dirY * 2732; tween(levelText, { x: levelText.x + deltaX, y: levelText.y + deltaY }, { duration: 1000, easing: tween.easeInOut }); tween(levelText2, { x: levelText2.x + deltaX, y: levelText2.y + deltaY }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { self.displayedLevel = newLevel; if (newLevel > 0) { levelText.setText(newLevel.toString()); levelText2.setText((newLevel + 1).toString()); } else { levelText.setText("THE\nEND"); } // Restore initial positions levelText.x = centerX; levelText.y = centerY; levelText2.x = centerX + 2048; levelText2.y = centerY + 2732; } }); } }; self.setText = function (text, text2) { levelText.setText(text); levelText2.setText(text2 || text); }; // Method to show the level number self.show = function () { levelText.visible = true; levelText2.visible = true; }; // Method to hide the level number self.hide = function () { levelText.visible = false; levelText2.visible = false; }; self.prepareTextTransition = function (dirX, dirY) { // Position the next text depending on the currrent transition direction levelText2.x = centerX + dirX * 2048; levelText2.y = centerY + dirY * 2732; }; return self; }); // MenuBoard class to represent a grid of menuCell assets var MenuBoard = Container.expand(function () { var self = Container.call(this); self.menuGrid = []; self.menuCells = []; // Define grid dimensions var rows = 7; var cols = 6; var cellSize = LK.getAsset('menuCell', {}).width; // Create grid of menuCell assets for (var row = 0; row < rows; row++) { self.menuCells[row] = []; for (var col = 0; col < cols; col++) { var menuCell = self.attachAsset('menuCell', { anchorX: 0.5, anchorY: 0.5, x: cellSize / 2 + col * cellSize, y: cellSize / 2 + row * cellSize, scaleX: col % 2 ? 1 : -1, scaleY: row % 2 ? 1 : -1 }); menuCell.baseX = menuCell.x; menuCell.baseY = menuCell.y; self.menuCells[row][col] = menuCell; self.addChild(menuCell); } } // Create grid of menuCell assets for (var row = 0; row < rows; row++) { self.menuGrid[row] = []; for (var col = 0; col < cols; col++) { if (row >= 1 && col < 6) { var lvl = col + (cols - 1) * (row - 1) + 1; var isDone = lvl < puzzleManager.maxReachedLevelNumber; var isReached = lvl == puzzleManager.maxReachedLevelNumber; var notReached = lvl > puzzleManager.maxReachedLevelNumber; var lvlColor = isDone ? 0x6ad100 : 0xF93827; lvlColor = notReached ? 0x787878 : lvlColor; var levelText = new Text2(lvl < 10 ? "0" + lvl : lvl, { size: 160, fill: 0xFFFFFF, //lvlColor, weight: 1000, dropShadow: true, dropShadowAngle: Math.PI, dropShadowDistance: 10 }); levelText.tint = lvlColor; levelText.lvl = lvl; levelText.alpha = lvl <= puzzleManager.maxReachedLevelNumber ? 1 : 0.6; levelText.blendMode = 2; levelText.x = col * cellSize * 1.0 + cellSize / 2 - 90; levelText.y = row * cellSize * 1.0 + cellSize / 4 + 10; levelText.down = function (level) { return function () { log("levelText currentState:", currentState, " isMenuReady=", isMenuReady); //{3F.2} if (!isMenuReady) { log("Menu not ready.", level); //{3F.2} return; } log("Tapped level number:", level); //{3F.2} if (level <= puzzleManager.maxReachedLevelNumber) { // Store initial width and height var initialWidth = levelText.width; var initialHeight = levelText.height; // Animate width and height to 10 times their size and fade out tween(levelText, { width: initialWidth * 10, height: initialHeight * 10, alpha: 0 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { // Restore to initial values levelText.width = initialWidth; levelText.height = initialHeight; levelText.alpha = 1; puzzleManager.selectLevel(level); levelNumberText.setText(level, level + 1); changeGameState(GAME_STATE.NEW_ROUND); } }); } }; //{3F.3} }(lvl); //{3F.4} self.menuGrid[row][col] = levelText; self.addChild(levelText); } } } self.updateMenuGrid = function () { // Foreach levelText in menuGrid, update the level color depending on puzzleManager.maxReachedLevelNumber for (var row = 0; row < self.menuGrid.length; row++) { for (var col = 0; col < self.menuGrid[row].length; col++) { var levelText = self.menuGrid[row][col]; if (levelText) { var lvl = levelText.lvl; //parseInt(levelText.text); log("Updating levelText for level:", lvl); // Log the level being updated var isDone = lvl < puzzleManager.maxReachedLevelNumber; var isReached = lvl == puzzleManager.maxReachedLevelNumber; var notReached = lvl > puzzleManager.maxReachedLevelNumber; var lvlColor = isDone ? 0x6ad100 : 0xF93827; lvlColor = notReached ? 0x787878 : lvlColor; log("Level color set to:", lvlColor.toString(16)); // Log the color being set // levelText.setStyle({ // fill: lvlColor // }); levelText.tint = lvlColor; levelText.alpha = lvl <= puzzleManager.maxReachedLevelNumber ? 1 : 0.6; log("Level alpha set to:", levelText.alpha); // Log the alpha value being set } } } }; self.animateEntrance = function () { self.menuCells.forEach(function (row, rowIndex) { row.forEach(function (cell, colIndex) { // Start cells off-screen to the right cell.x = 2048 + cell.baseX + cell.width; cell.visible = true; log("Animating entrance for cell at initial position:", cell.x, cell.y); // Log initial position // Animate cells to their base positions tween(cell, { x: cell.baseX, y: cell.baseY }, { duration: 2000, easing: tween.easeOut, delay: colIndex * 200, // Delay each column by 200ms onFinish: function onFinish() { log("Completed animation for cell to base position:", cell.baseX, cell.baseY); // Log completion isMenuReady = true; } //{4e.1} }); }); }); }; return self; }); // MenuButton class to represent the menu button var MenuButton = Container.expand(function () { var self = Container.call(this); // Asset Attachments var buttonShadow = self.attachAsset('menuButton', { anchorX: 0.5, anchorY: 0.5, x: 8, y: 8, scaleX: 1.0, scaleY: 1.0, tint: 0x000000, alpha: 0.25 }); var buttonGraphics = self.attachAsset('menuButton', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0, tint: 0x787878, blendMode: 1 }); self.down = function () { puzzleManager.reset(true); LK.getSound("resetSound").play(); resetButton.deactivate(); menuBoard.updateMenuGrid(); LK.setTimeout(function () { backgroundImage.showWall(); tween(buttonGraphics, { scaleY: 0 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { self.deactivate(); buttonGraphics.scaleY = 1; changeGameState(GAME_STATE.MENU); } }); tween(buttonShadow, { scaleY: 0 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { buttonShadow.scaleY = 1; } }); }, 800); }; self.disable = function () {}; self.enable = function () {}; self.activate = function () { if (self.visible) { return; } self.visible = true; self.y = -300; tween(self, { y: 130 }, { duration: 500, easing: tween.easeOut }); }; self.deactivate = function () { self.visible = false; }; return self; }); // OperationButton class to represent each operation button var OperationButton = Container.expand(function (type, index) { var self = Container.call(this); // Properties self.type = type; self.index = index; self.isSelected = false; self.rotation = 0; self.baseX = 0; self.baseY = 0; self.baseR = 0; self.visible = false; self.interactive = true; self.alpha = 1; var buttonSize = LK.getAsset('operationButton', {}).width; // Asset Attachments var buttonGraphicsShadow = self.attachAsset('operationButton', { anchorX: 0.5, anchorY: 0.5, x: 10, y: 10, tint: 0x000000, alpha: 0.7 }); var buttonGraphics = self.attachAsset('operationButton', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0 }); var opColor; switch (self.type[0]) { case "+": opColor = 0x6ad100; break; case "-": opColor = 0xF93827; break; default: opColor = 0x1E90FF; break; } // Value Text self.valueText = new Text2(self.type, { size: buttonSize * 0.45, fill: opColor, dropShadow: true, dropShadowAngle: Math.PI, dropShadowDistance: 4, weight: 1000 }); self.valueText.anchor.set(0.5, 0.5); self.valueText.x = buttonGraphics.x; self.valueText.y = buttonGraphics.y; self.valueText = self.addChild(self.valueText); // Functions self.setBasePosition = function (x, y, r) { self.x = x; self.y = y; self.rotation = r; self.baseX = x; self.baseY = y; self.baseR = r; }; self.preselect = function () { log("operation preselect..."); var scaleRatio = 2; //{2S.1} tween(buttonGraphics, { scaleX: scaleRatio, scaleY: scaleRatio }, { duration: 500, easing: tween.easeOut }); //{2S.2} tween(buttonGraphicsShadow, { scaleX: scaleRatio, scaleY: scaleRatio }, { duration: 500, easing: tween.easeOut }); //{2S.3} tween(self.valueText, { width: self.valueText.width * scaleRatio, height: self.valueText.height * scaleRatio }, { duration: 500, easing: tween.easeOut }); tween(self, { x: rightOperationPreselectX, y: rightOperationPreselectY, rotation: rightOperationPreselectR }, { duration: 500, easing: tween.easeOut }); //{2S.5} self.isSelected = true; //{2T.1} self.interactive = true; self.alpha = 1; self.parent.addChildAt(self, self.parent.children.length - 1); //{2T.2} }; self.show = function () { self.visible = true; }; return self; }); // ResetButton class to represent the reset button var ResetButton = Container.expand(function () { var self = Container.call(this); // Asset Attachments var buttonShadow = self.attachAsset('resetButton', { anchorX: 0.5, anchorY: 0.5, x: 10, y: 10, tint: 0x000000, alpha: 0.25 }); var buttonGraphics = self.attachAsset('resetButton', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0, tint: 0xEAEEE8 }); self.down = function () { self.disable(); tween(self, { // Animate rotation rotation: Math.PI * 2 // Rotate 360 degrees }, { duration: 500, // Duration of the animation easing: tween.easeOut, // Easing function for smooth transition onFinish: function onFinish() { self.rotation = 0; // Restore rotation to 0 } }); LK.getSound("resetSound").play(); puzzleManager.reset(); // Reset the level puzzle }; self.disable = function () { buttonGraphics.alpha = 0.5; // Dim the button to indicate it's disabled self.interactive = false; // Disable interaction tween(self, { scaleX: 0.8, scaleY: 0.8 }, { duration: 300, easing: tween.easeOut }); }; self.enable = function () { buttonGraphics.alpha = 1.0; // Restore full opacity to indicate it's enabled self.interactive = true; // Enable interaction tween(self, { scaleX: 1.0, scaleY: 1.0 }, { duration: 300, easing: tween.easeOut }); }; self.activate = function () { self.visible = true; self.y = -300; tween(self, { y: 130 }, { duration: 500, easing: tween.easeOut }); }; self.deactivate = function () { tween(self, { y: -300 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { self.visible = false; } }); }; self.highlight = function () { tween(self, { scaleX: 1.2, scaleY: 1.2 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1.0, scaleY: 1.0 }, { duration: 300, easing: tween.easeOut }); } }); }; return self; }); // StartButton class to represent the start button var StartButton = Container.expand(function () { var self = Container.call(this); // Asset Attachments self.buttonGraphics = self.attachAsset('startButton', { anchorX: 0.5, anchorY: 0.5, x: 0, y: 0, visible: true }); self.letterGraphics = []; // Individual letter texts for "START" var letters = ['S', 'T', 'A', 'R', 'T']; var tileSpacing = 390; var letterPositions = { 0: { 'x': -585, 'y': -300 }, 1: { 'x': -195, 'y': -300 }, 2: { 'x': 0, 'y': 0 }, 3: { 'x': 195, 'y': 300 }, 4: { 'x': 585, 'y': 300 } }; letters.forEach(function (letter, index) { var letterContainer = new Container(); var tileGraphics = letterContainer.attachAsset('hexTile', { anchorX: 0.5, anchorY: 0.5, width: 390, height: 390, x: 0, y: 0, tint: tileColors[1 + index % 3], alpha: 1 }); var letterText = new Text2(letter, { size: 260, fill: 0xEAEEE8, weight: 1000, dropShadow: true, dropShadowAngle: Math.PI, dropShadowDistance: 10 }); letterText.anchor.set(0.5, 0.5); letterText.alpha = 0.9; letterText.blendMode = 0; letterText.visible = true; letterText.x = 0; letterContainer.addChild(tileGraphics); letterContainer.addChild(letterText); letterContainer.x = letterPositions[index].x; //(index - 2) * tileSpacing; letterContainer.y = letterPositions[index].y; log("letter:", letter, letterContainer.x); self.letterGraphics.push(letterContainer); self.addChild(letterContainer); }); self.fadeOut = function () { LK.getSound('tileRemove').play(); self.letterGraphics.forEach(function (letterContainer) { tween(letterContainer, { scaleX: 0, scaleY: 0, rotation: Math.PI / 2 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { tween(self.buttonGraphics, { alpha: 0 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { self.destroy(); } }); } }); }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 // Set game background to black }); /**** * Game Code ****/ function _typeof2(o) { "@babel/helpers - typeof"; return _typeof2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof2(o); } function _defineProperty3(e, r, t) { return (r = _toPropertyKey2(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey2(t) { var i = _toPrimitive2(t, "string"); return "symbol" == _typeof2(i) ? i : i + ""; } function _toPrimitive2(t, r) { if ("object" != _typeof2(t) || !t) { return t; } var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof2(i)) { return i; } throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) { return t; } var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) { return i; } throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function resetAdjacentTilesScale() { currentAdjacentTiles.forEach(function (adjTile) { adjTile.isHighlighted = false; tween(adjTile, { scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeOut }); }); currentAdjacentTiles = []; // Clear the list after restoring scale } /************************************* GAME OBJECTS CLASSES ************************************/ /***********************************************************************************************/ // Transition to menu state function PuzzleManager(game) { var self = this; // Properties self.game = game; self.activeTileCount = 0; // Initialize active tile count self.levelBoardOffsetX = 0; // Initialize levelBoardOffsetX self.levelBoardOffsetY = 0; // Initialize levelBoardOffsetY self.currentLevel = debug ? 1 : 1; self.previousLevelNumber = 1; self.maxReachedLevelNumber = storage.maxReachedLevelNumber || 1; // Retrieve from storage or default to 1 self.board = []; self.operations = []; self.isAnimating = false; self.selectedOperation = null; self.moveCount = 0; self.levelData = null; self.levelFailed = false; // Core Functions self.initPuzzle = function () { self.loadLevel(self.currentLevel); }; self.selectLevel = function (level) { self.currentLevel = level; self.previousLevelNumber = level; }; self.reset = function (noContinue) { // Remove all existing tiles self.board.forEach(function (tile) { // Animate tiles moving randomly out of screen tween(tile, { x: Math.random() > 0.5 ? -200 - Math.random() * 1000 : 2248 + Math.random() * 1000, y: Math.random() > 0.5 ? -200 - Math.random() * 1000 : 2732 + Math.random() * 1000 }, { duration: 800, easing: tween.easeIn, onFinish: function onFinish() { tile.destroy(); } }); }); self.board = []; // Remove all existing operations self.operations.forEach(function (operation) { // Animate operations moving randomly out of screen tween(operation, { x: Math.random() > 0.5 ? -200 - Math.random() * 1000 : 2248 + Math.random() * 1000, y: Math.random() > 0.5 ? -200 - Math.random() * 1000 : 2732 + Math.random() * 1000 }, { duration: 800, easing: tween.easeIn, onFinish: function onFinish() { operation.destroy(); } }); }); self.operations = []; self.levelFailed = false; // Load the current level self.previousLevelNumber = self.currentLevel; if (noContinue) { return; } LK.setTimeout(function () { self.loadLevel(self.currentLevel); }, 850); }; self.loadLevel = function (levelNumber) { log("loadLevel...previousLevelNumber", self.previousLevelNumber, " new levelNumber:", levelNumber); // Load level configuration self.levelData = levelConfigs[levelNumber] || { tiles: [], operations: [] }; currentTransitionDirectionH = levelNumber > self.previousLevelNumber ? 1 : 0; currentTransitionDirectionV = levelNumber > self.previousLevelNumber ? Math.random() > 0.5 ? -1 : 1 : 0; log("transitions :", currentTransitionDirectionH, currentTransitionDirectionV); levelNumberText.updateLevel(levelNumber, currentTransitionDirectionH, currentTransitionDirectionV); backgroundImage.animateTransition(currentTransitionDirectionH, currentTransitionDirectionV); self.createBoard(); self.fillTilesNeighbors(); self.createOperations(); //LK.setTimeout(self.animateTilesEntrance, levelNumber == 1 ? 0 : 800); //LK.setTimeout(self.animateOperationsEntrance, 900); //LK.setTimeout(self.updateOperations, 900); LK.setTimeout(function () { self.animateTilesEntrance(); self.animateOperationsEntrance(); }, 800); }; self.createBoard = function () { self.board = []; // Max grid for 200px tiles = 11x7 var maxRows = self.levelData.tiles.length; var maxColsRowIndex = 0; var maxCols = 0; // Local variable to track the largest number of tiles in the level rows self.activeTileCount = 0; // Reset active tile count // Update levelBoardOffsets depending on level for (var row = 0; row < self.levelData.tiles.length; row++) { var firstColWithValue = -1; // Initialize to -1 to indicate no value found yet var lastColWithValue = -1; // Initialize to -1 to indicate no value found yet for (var col = 0; col < self.levelData.tiles[row].length; col++) { var value = self.levelData.tiles[row][col]; //{4r.1} if (value !== "") { //{4r.2} if (firstColWithValue === -1) { // Check if this is the first value in the row firstColWithValue = col; } lastColWithValue = col; // Update lastColWithValue to the current column var tile = new HexTile(value, col, row, self.levelData); //{4r.3} self.board.push(tile); //{4r.4} boardContainer.addChild(tile); //{4r.5} self.activeTileCount++; // Increment active tile count //{4r.6} } //{4r.7} } var tempMaxCols = lastColWithValue - firstColWithValue + 1; // Calculate the number of columns with values log("tempMaxCols=", tempMaxCols, maxCols); //{4q.1} if (tempMaxCols > maxCols) { //{4q.2} maxCols = tempMaxCols; //{4q.3} maxColsRowIndex = row; //{4q.4} } //{4q.5} } log("boardContainer: ", boardContainer.x, boardContainer.y); if (self.board.length > 0) { log("createBoard calc: ", game.width, maxCols, self.board[0].tileSizeX, -maxCols * self.board[0].tileSizeX); //{5A.1} var actualTilesizeX = self.board[0].tileSizeX; //{5A.2} var actualTilesizeY = self.board[0].tileSizeY; //{5A.3} } else { log("createBoard calc: Board is empty, skipping tile size calculations."); var actualTilesizeX = 0; var actualTilesizeY = 0; } var fixOffsetX = 0; switch (maxCols) { case 3: fixOffsetX = -367; // -115 - 4 * 63; break; case 5: fixOffsetX = -265; break; case 6: fixOffsetX = -220; break; case 7: fixOffsetX = -175; break; default: fixOffsetX = -115 - Math.max(0, 7 - maxCols) * 63; break; } self.levelBoardOffsetX = (game.width - maxCols * actualTilesizeX) / 2 + fixOffsetX + (maxColsRowIndex % 2 != 0 ? -actualTilesizeX / 2 : 0); log("Cols: ", maxCols, " actualTilesizeX=", actualTilesizeX, " C x Size => ", actualTilesizeX * maxCols, " self.levelBoardOffsetX=", self.levelBoardOffsetX, " fix =", fixOffsetX); var fixOffsetY = 0; switch (maxRows) { case 3: fixOffsetY = -280; break; case 4: fixOffsetY = -180; break; case 5: fixOffsetY = -80; break; case 6: fixOffsetY = 0; break; case 7: fixOffsetY = 165; break; case 8: fixOffsetY = 250; break; case 9: fixOffsetY = 400; break; case 11: fixOffsetY = 615; break; default: fixOffsetY = maxRows * 0.4 * actualTilesizeY; break; } self.levelBoardOffsetY = (game.height - maxRows * actualTilesizeY) / 2 - maxRows * 0.5 * actualTilesizeY + fixOffsetY; log("Rows: ", maxRows, " actualTilesizeY=", actualTilesizeY, " R x Size => ", actualTilesizeY * maxRows, " self.levelBoardOffsetX=", self.levelBoardOffsetY, " fix =", fixOffsetY); log("createBoard max dimensions: ", maxRows, maxCols, " largest row #", maxColsRowIndex, " OffsetX=", self.levelBoardOffsetX, " OffsetY=", self.levelBoardOffsetY); for (var i = 0; i < self.board.length; i++) { var tile = self.board[i]; //log("tile #" + i, tile); //{4q.1} var oddOffset = tile.row % 2 == 0 ? actualTilesizeX / 2 : 0; tile.setBasePosition(tile.x + self.levelBoardOffsetX + oddOffset, tile.y + self.levelBoardOffsetY); } }; self.fillTilesNeighbors = function () { for (var i = 0; i < self.board.length; i++) { var tile = self.board[i]; tile.neighbors = []; for (var j = 0; j < self.board.length; j++) { var potentialNeighbor = self.board[j]; if (tile !== potentialNeighbor && self.areNeighbors(tile, potentialNeighbor)) { tile.neighbors.push(potentialNeighbor); } } } }; self.areNeighbors = function (tile1, tile2) { if (tile1.value != tile2.value) { return false; } var dx = Math.abs(tile1.col - tile2.col); //{6b.1} var dy = Math.abs(tile1.row - tile2.row); //{6b.2} var areNeighbors = dx === 1 && dy === 0 || dx === 0 && dy === 1 || dx === 1 && dy === 1 && (tile1.row % 2 === 0 && tile2.col > tile1.col || tile1.row % 2 !== 0 && tile2.col < tile1.col); //{6b.4} //log("are neighbors: T1 row:", tile1.row, "col:", tile1.col, " val:", tile1.value, " vs T2 row:", tile2.row, "col:", tile2.col, " val:", tile2.value, " => dx:", dx, "dy:", dy, " => ", areNeighbors); //{6b.3} return areNeighbors; //{6b.6} }; self.getAdjacentTiles = function (tile) { var adjacentTiles = []; var toCheck = [tile]; var checked = []; while (toCheck.length > 0) { var currentTile = toCheck.pop(); if (checked.includes(currentTile)) { continue; } checked.push(currentTile); currentTile.neighbors.forEach(function (neighbor) { if (neighbor.value === tile.value && !checked.includes(neighbor)) { adjacentTiles.push(neighbor); toCheck.push(neighbor); } }); } return adjacentTiles; }; self.createOperations = function () { self.operations.forEach(function (operation) { operation.destroy(); }); self.operations = []; var baseX = 100; var baseY = 2600; for (var i = 0; i < self.levelData.operations.length; i++) { var opType = self.levelData.operations[i]; var operation = new OperationButton(opType, i); self.operations.push(operation); var operationX = operationsSlots[i].x; var operationY = operationsSlots[i].y; var operationR = operationsSlots[i].r; operation.setBasePosition(operationX, operationY, operationR); // Space buttons evenly and position near the bottom self.game.addChild(operation); } }; self.updateOperations = function () { log("updateOperations:", self.operations); if (!self.operations || !self.operations.length) { return; } for (var i = 0; i < self.levelData.operations.length; i++) { if (self.operations[i]) { var op = self.operations[i]; op.show(); var operationX = op.baseX; // operationsSlots[i].x; var operationY = op.baseY; // operationsSlots[i].y; var operationR = op.baseR; // operationsSlots[i].r; log("Updating :", i, " old x=", op.x, " => operationX:", operationX); tween(op, { x: operationX, y: operationY, rotation: operationR }, { //{4S.2} duration: 500, // Duration of the animation in milliseconds //{4S.3} easing: tween.easeOut // Easing function for smooth transition //{4S.4} }); //{4S.5} } } }; self.applyOperation = function (operation, tile) { if (self.isAnimating) { return false; // Exit if an operation is already in progress } self.isAnimating = true; // Set animating flag self.propagateOperation(operation, tile); // Remove used operation from the list var operationIndex = self.operations.indexOf(operation); if (operationIndex > -1) { self.operations.splice(operationIndex, 1); if (operation) { operation.destroy(); } } self.checkWinCondition(); LK.setTimeout(function () { self.isAnimating = false; // Reset animating flag after operation is done self.updateOperations(); self.fillTilesNeighbors(); }, 600); return true; }; self.propagateOperation = function (operation, startTile) { var visited = []; var toProcess = [{ tile: startTile, depth: 0 }]; var targetValue = startTile.value; log("Starting propagateOperation with targetValue:", targetValue); while (toProcess.length > 0) { var current = toProcess.pop(); var currentTile = current.tile; var startX = startTile.x; var startY = startTile.y; var dx = Math.abs(currentTile.col - startTile.col); var dy = Math.abs(currentTile.row - startTile.row); var normalizedDistance = Math.max(dx, dy); // Use the maximum of dx and dy to count the distance in tiles log("Processing tile at position:", currentTile.x, currentTile.y, "with value:", currentTile.value, "at normalized distance:", normalizedDistance); if (visited.includes(currentTile)) { log("Tile already visited:", currentTile); continue; } visited.push(currentTile); var newValue = Math.max(0, currentTile.value + parseInt(operation.type)); if (newValue <= 0) { self.activeTileCount--; } resetButton.enable(); currentTile.setValue(newValue, normalizedDistance); log("Applied operation. New value:", currentTile.value); // Check neighbors var _iterator = _createForOfIteratorHelper(currentTile.neighbors), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var neighbor = _step.value; log("Checking neighbor at position:", neighbor.x, neighbor.y, "with value:", neighbor.value); if (neighbor.value === targetValue && !visited.includes(neighbor)) { log("Neighbor matches target value and is not visited. Adding to process list:", neighbor); toProcess.push({ tile: neighbor, depth: normalizedDistance + 1 }); } } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } } log("Finished propagateOperation"); }; self.animateTilesEntrance = function () { self.board.forEach(function (tile, index) { // Place tiles randomly out of the screen tile.x = Math.random() > 0.5 ? -200 - Math.random() * 1000 : 2248 + Math.random() * 1000; tile.y = Math.random() > 0.5 ? -200 - Math.random() * 1000 : 2732 + Math.random() * 1000; //log("animateTilesEntrance #" + index, tile.x, tile.y); tile.visible = true; if (index < 6) { LK.setTimeout(function () { LK.getSound("tileEntrance").play(); }, 100 + index * 75); } // Animate tiles to their base positions tween(tile, { x: tile.baseX + self.levelBoardOffsetX, y: tile.baseY + self.levelBoardOffsetY }, { duration: 800, easing: tween.bounceOut }); }); }; self.animateOperationsEntrance = function () { self.operations.forEach(function (op, index) { // Place tiles randomly out of the screen op.x = Math.random() > 0.5 ? -200 - Math.random() * 1000 : 2248 + Math.random() * 1000; op.x = Math.random() > 0.5 ? -200 - Math.random() * 1000 : 2248 + Math.random() * 1000; op.rotation = Math.random() * Math.PI * 2; //log("animateOperationsEntrance #" + index, op.x, op.y); op.visible = true; // Animate tiles to their base positions tween(op, { x: op.baseX, y: op.baseY, rotation: op.baseR }, { duration: 800, easing: tween.bounceOut }); }); }; self.checkWinCondition = function () { log("checkWinCondition... Active tiles:", self.activeTileCount); if (self.activeTileCount <= 0) { self.playVictoryAnimation(); isPlaying = false; resetButton.disable(); LK.setTimeout(function () { self.previousLevelNumber = self.currentLevel; self.currentLevel++; // Advance to the next level if (self.currentLevel > self.maxReachedLevelNumber) { self.maxReachedLevelNumber = self.currentLevel; //{b6.1} storage.maxReachedLevelNumber = self.maxReachedLevelNumber; // Store in storage } //{b6.2} changeGameState(GAME_STATE.NEW_ROUND); // Change state to newRound }, 2000); return true; } // if tiles remaning but no more operations play level failed animation if (self.activeTileCount > 0 && self.operations.length === 0) { self.levelFailed = true; LK.setTimeout(self.playLevelFailedAnimation, 800); return false; } }; // Animation Functions self.playVictoryAnimation = function () { log("playVictoryAnimation...previousLevelNumber", self.previousLevelNumber); // Play level complete animation }; self.playLevelFailedAnimation = function () { log("playLevelFailedAnimation..."); LK.getSound("levelFailed").play(); self.board.forEach(function (tile) { if (tile.value > 0) { // Only shake tiles with a value greater than 0 tile.shake(); } }); resetButton.highlight(); }; } /***********************************************************************************************/ /************************************* UTILITY FUNCTIONS ************************************/ /***********************************************************************************************/ function log() { if (debug) { console.log.apply(console, arguments); } } function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) { throw o; } } } }; } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) { return _arrayLikeToArray(r, a); } var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) { n[e] = r[e]; } return n; } // Business tools function isPointInsideTile(x, y, tile) { var overlapOffsetX = 10; // Offset to prevent multiple tile selection on X-axis var overlapOffsetY = 45; // Offset to prevent multiple tile selection on Y-axis return x >= boardContainer.x + tile.x - tile.width / 2 + overlapOffsetX && x <= boardContainer.x + tile.x + tile.width / 2 - overlapOffsetX && y >= boardContainer.y + tile.y - tile.height / 2 + overlapOffsetY && y <= boardContainer.y + tile.y + tile.height / 2 - overlapOffsetY; } /***********************************************************************************************/ /************************************* GAME STATE MANAGEMENT ************************************/ /***********************************************************************************************/ function cleanInitState() { // Clean up the game state for MENU log("Cleaning INIT State"); startButton.fadeOut(); } function initMenuState() { // Initialize the game state for MENU log("Initializing MENU State"); //menuBoard.x = 2048; // Start off-screen to the right menuBoard.visible = true; menuBoard.animateEntrance(); //isMenuReady = true; /* tween(menuBoard, { x: 0 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { isMenuReady = true; } }); */ menuButton.deactivate(); } function handleMenuLoop() { // Handle the game loop for MENU state log("Handling MENU Loop"); } function cleanMenuState() { // Clean up the game state for MENU log("Cleaning MENU State"); isMenuReady = false; // Animate menuBoard exit to the left side tween(menuBoard, { x: -2048 }, { duration: 1000, easing: tween.easeIn, onFinish: function onFinish() { menuBoard.visible = false; backgroundImage.hideWall(); } }); } function initNewRoundState() { // Initialize the game state for NEW_ROUND log("Initializing NEW_ROUND State"); if (!levelConfigs[puzzleManager.currentLevel]) { changeGameState(GAME_STATE.SCORE); return; } puzzleManager.initPuzzle(); levelNumberText.show(); if (debug) { changeGameState(GAME_STATE.PLAYING); } } function handleNewRoundLoop() { // Handle the game loop for NEW_ROUND state log("Handling NEW_ROUND Loop"); } function cleanNewRoundState() { // Clean up the game state for NEW_ROUND log("Cleaning NEW_ROUND State"); } function initPlayingState() { // Initialize the game state for PLAYING log("Initializing PLAYING State"); menuButton.activate(); resetButton.disable(); resetButton.activate(); // Make resetButton visible in PLAYING state } function handlePlayingLoop() { // Handle the game loop for PLAYING state log("Handling PLAYING Loop"); } function cleanPlayingState() { // Clean up the game state for PLAYING log("Cleaning PLAYING State"); resetButton.deactivate(); } function initScoreState() { // Initialize the game state for SCORE log("Initializing SCORE State"); levelNumberText.updateLevel(0, 1, 1); backgroundImage.animateTransition(1, 1); } function handleScoreLoop() { // Handle the game loop for SCORE state log("Handling SCORE Loop"); } function cleanScoreState() { // Clean up the game state for SCORE log("Cleaning SCORE State"); } function changeGameState(newState) { log("Changing game state from", currentState, "to", newState); // Clean up the current state switch (currentState) { case GAME_STATE.INIT: cleanInitState(); break; case GAME_STATE.MENU: cleanMenuState(); break; case GAME_STATE.NEW_ROUND: cleanNewRoundState(); break; case GAME_STATE.PLAYING: cleanPlayingState(); break; case GAME_STATE.SCORE: cleanScoreState(); break; default: log("Unknown state:", currentState); } // Set the new state currentState = newState; // Initialize the new state switch (newState) { case GAME_STATE.INIT: // Do nothing break; case GAME_STATE.MENU: initMenuState(); break; case GAME_STATE.NEW_ROUND: initNewRoundState(); break; case GAME_STATE.PLAYING: initPlayingState(); break; case GAME_STATE.SCORE: initScoreState(); break; default: log("Unknown state:", newState); } } /***********************************************************************************************/ /****************************************** EVENT HANDLERS *************************************/ /***********************************************************************************************/ game.down = function (x, y, obj) { switch (currentState) { case GAME_STATE.INIT: handleInitStateDown(x, y, obj); break; case GAME_STATE.MENU: handleMenuStateDown(x, y, obj); break; case GAME_STATE.PLAYING: handlePlayingStateDown(x, y, obj); break; case GAME_STATE.SCORE: handleScoreStateDown(x, y, obj); break; default: log("Unknown state:", currentState); } }; game.move = function (x, y, obj) { switch (currentState) { case GAME_STATE.INIT: // Do nothing break; case GAME_STATE.MENU: handleMenuStateMove(x, y, obj); break; case GAME_STATE.PLAYING: handlePlayingStateMove(x, y, obj); break; case GAME_STATE.SCORE: handleScoreStateMove(x, y, obj); break; default: log("Unknown state:", currentState); } }; game.up = function (x, y, obj) { switch (currentState) { case GAME_STATE.INIT: // Do nothing break; case GAME_STATE.MENU: handleMenuStateUp(x, y, obj); break; case GAME_STATE.PLAYING: handlePlayingStateUp(x, y, obj); break; case GAME_STATE.SCORE: handleScoreStateUp(x, y, obj); break; default: log("Unknown state:", currentState); } }; // Menu State Handlers function handleInitStateDown(x, y, obj) { // Implement logic for handling down event in MENU state log("Handling down event in INIT state"); changeGameState(GAME_STATE.MENU); } // Menu State Handlers function handleMenuStateDown(x, y, obj) { // Implement logic for handling down event in MENU state log("Handling down event in MENU state"); } function handleMenuStateMove(x, y, obj) { // Implement logic for handling move event in MENU state //log("Handling move event in MENU state"); } function handleMenuStateUp(x, y, obj) { // Implement logic for handling up event in MENU state log("Handling up event in MENU state"); } // Playing State Handlers function handlePlayingStateDown(x, y, obj) { // Implement logic for handling down event in PLAYING state log("Handling down event in PLAYING state", obj); puzzleManager.operations.forEach(function (operation) { //operation.isSelected && if (x >= operation.x - operation.width / 2 && x <= operation.x + operation.width / 2 && y >= operation.y - operation.height / 2 && y <= operation.y + operation.height / 2) { dragNode = operation; tween(operation, { rotation: 0, scaleX: 0.6, scaleY: 0.6 }, { duration: 500, easing: tween.easeOut }); LK.getSound('operationSelect').play(); return; } }); if (!dragNode) { // Check if tapping a tile, if so play 'tick' puzzleManager.board.forEach(function (tile) { if (!tile.isHighlighted && isPointInsideTile(x, y, tile)) { if (puzzleManager.levelFailed) { puzzleManager.playLevelFailedAnimation(); return; } tile.isHighlighted = true; if (typeof tile.previousZIndex === 'undefined') { tile.previousZIndex = boardContainer.getChildIndex(tile); // Store previous z-index } boardContainer.addChildAt(tile, boardContainer.children.length - 1); // Bring tile to the front tween(tile, { scaleX: 1.33, scaleY: 1.33 }, { duration: 200, easing: tween.easeOut }); // Play tick sound when a tile is highlighted LK.getSound('tick').play(); currentHighlightedTile = tile; // Store the currently highlighted tile in a global variable if (currentAdjacentTiles && currentAdjacentTiles.length > 0 && currentAdjacentTiles[0].value != tile.value) { resetAdjacentTilesScale(); } currentAdjacentTiles = puzzleManager.getAdjacentTiles(tile); currentAdjacentTiles.forEach(function (adjTile) { adjTile.isHighlighted = true; var dx = Math.abs(adjTile.col - tile.col); var dy = Math.abs(adjTile.row - tile.row); var normalizedDistance = Math.max(dx, dy); tween(adjTile, { scaleX: 1.33, scaleY: 1.33 }, { duration: 200, easing: tween.easeOut, delay: normalizedDistance * 75 // Delay based on normalized distance }); }); return; } }); } } function handlePlayingStateMove(x, y, obj) { //log("Handling move event in PLAYING state", dragNode); if (dragNode) { // Calculate rotation based on x delta var deltaX = x - dragNode.x; //{71.1} var rotationFactor = -0.1; // Adjust this factor to control rotation sensitivity//{71.2} var newRotation = deltaX * rotationFactor; //{71.3} if (Math.abs(deltaX) < 5) { //{71.4} newRotation = 0; //{71.5} tween(dragNode, { rotation: newRotation }, { duration: 200, easing: tween.easeOut }); //{71.9} } else { //{71.6} newRotation = Math.max(-0.1, Math.min(0.1, newRotation)); //{71.7} dragNode.rotation = newRotation; } //{71.8} dragNode.x = x; dragNode.y = y; puzzleManager.board.forEach(function (tile) { // When moving... // Check if above a tile... if (isPointInsideTile(x, y, tile)) { // Above a tile... if (!tile.isHighlighted) { tile.isHighlighted = true; if (typeof tile.previousZIndex === 'undefined') { tile.previousZIndex = boardContainer.getChildIndex(tile); // Store previous z-index } boardContainer.addChildAt(tile, boardContainer.children.length - 1); // Bring tile to the front tween(tile, { scaleX: 1.33, scaleY: 1.33 }, { duration: 200, easing: tween.easeOut }); // Play tick sound when a tile is highlighted LK.getSound('tick').play(); currentHighlightedTile = tile; // Store the currently highlighted tile in a global variable if (currentAdjacentTiles && currentAdjacentTiles.length > 0 && currentAdjacentTiles[0].value != tile.value) { resetAdjacentTilesScale(); } currentAdjacentTiles = puzzleManager.getAdjacentTiles(tile); currentAdjacentTiles.forEach(function (adjTile) { adjTile.isHighlighted = true; var dx = Math.abs(adjTile.col - tile.col); var dy = Math.abs(adjTile.row - tile.row); var normalizedDistance = Math.max(dx, dy); tween(adjTile, { scaleX: 1.33, scaleY: 1.33 }, { duration: 200, easing: tween.easeOut, delay: normalizedDistance * 75 // Delay based on normalized distance }); }); } } else if (tile.isHighlighted && !currentAdjacentTiles.includes(tile)) { tile.isHighlighted = false; if (typeof tile.previousZIndex === 'undefined') { tile.previousZIndex = boardContainer.getChildIndex(tile); // Set previousZIndex if undefined } if (typeof tile.previousZIndex !== 'undefined') { boardContainer.addChildAt(tile, tile.previousZIndex); // Restore tile's original z-index } tween(tile, { scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeOut }); if (currentAdjacentTiles && currentAdjacentTiles.length > 0 && currentAdjacentTiles[0].value == tile.value) { resetAdjacentTilesScale(); } } }); } //log("Handling move event in PLAYING state"); } function handlePlayingStateUp(x, y, obj) { // Implement logic for handling up event in PLAYING state log("Handling up event in PLAYING state"); if (dragNode) { // Check if the operation button is above a tile var tileFound = false; log("Operation dropped at ", x, y); log("boardContainer at ", boardContainer.x, boardContainer.y); puzzleManager.board.forEach(function (tile) { log("Checking tile at position:", tile.x, tile.y); // Log tile position if (isPointInsideTile(x, y, tile)) { log("Operation button is above tile at position:", tile.x, tile.y); // Log when operation button is above a tile var applied = puzzleManager.applyOperation(dragNode, tile); if (!applied) { return; } tileFound = true; if (typeof tile.previousZIndex !== 'undefined') { boardContainer.addChildAt(tile, tile.previousZIndex); // Restore tile's original z-index } tween(tile, { // Restore tile size after operation is applied scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeOut }); //{4x.1} if (currentAdjacentTiles) { resetAdjacentTilesScale(); } tween(dragNode, { alpha: 0 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { if (dragNode) { dragNode.destroy(); } } }); } else { log("Operation button is NOT above tile at position:", tile.x, tile.y); // Log when operation button is not above a tile } }); if (!tileFound) { log("Operation button not above any tile"); LK.getSound('operationCancel').play(); tween(dragNode, { x: dragNode.baseX, //rightOperationPreselectX, y: dragNode.baseY, //rightOperationPreselectY, rotation: dragNode.baseR || 0, //rightOperationPreselectR, scaleX: 1, scaleY: 1 }, { duration: 500, easing: tween.easeOut }); if (currentAdjacentTiles) { currentAdjacentTiles.forEach(function (adjTile) { adjTile.isHighlighted = false; tween(adjTile, { scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeOut }); }); currentAdjacentTiles = []; // Clear the list after restoring scale } } dragNode = null; } else { puzzleManager.board.forEach(function (tile) { tile.isHighlighted = false; if (typeof tile.previousZIndex === 'undefined') { tile.previousZIndex = boardContainer.getChildIndex(tile); // Set previousZIndex if undefined } tween(tile, { scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeOut }); if (currentAdjacentTiles && currentAdjacentTiles.length > 0 && currentAdjacentTiles[0].value == tile.value) { resetAdjacentTilesScale(); } return; }); } } // Score State Handlers function handleScoreStateDown(x, y, obj) { // Implement logic for handling down event in SCORE state log("Handling down event in SCORE state"); LK.showGameOver(); } function handleScoreStateMove(x, y, obj) { // Implement logic for handling move event in SCORE state //log("Handling move event in SCORE state"); } function handleScoreStateUp(x, y, obj) { // Implement logic for handling up event in SCORE state log("Handling up event in SCORE state"); } // Initialize PuzzleManager //<Assets used in the game will automatically appear here> //<Write imports for supported plugins here> /***********************************************************************************************/ /****************************************** GLOBAL VARIABLES ***********************************/ /***********************************************************************************************/ var debug = true; var isPlaying = false; var GAME_STATE = { INIT: 'INIT', MENU: 'MENU', NEW_ROUND: 'NEW_ROUND', PLAYING: 'PLAYING', SCORE: 'SCORE' }; var currentState = GAME_STATE.INIT; var boardContainer; var puzzleManager; var menuBoard; var startButton; var backgroundLayer; var middleLayer; var foregroundLayer; var backgroundImage; var centerX = 1024; var centerY = 1366; var currentTransitionDirectionH = 1; var currentTransitionDirectionV = 1; var rightOperationPreselectX = centerX + 650; var rightOperationPreselectY = 2500; var rightOperationPreselectR = -0.15; var levelNumberText; var currentHighlightedTile; var currentAdjacentTiles = []; // Initialize currentAdjacentTiles as a global variable var dragNode = null; var isMenuReady = false; var resetButton; // Declare resetButton as a global variable var menuButton; // Declare menuButton as a global variable var tileColors = { 0: 0xEAEEE8, // White / Gray 1: 0x1E90FF, // Blue 2: 0xF93827, // Red 3: 0xFF9D23, // Yellow / Orange 4: 0xFFD65A, // Yellow light 5: 0x90ff1e, // Green 6: 0xFF00FF, // Magenta 7: 0x00FFFF, // Cyan 8: 0xFFFF00, // Yellow 9: 0xFF0000, // Red "default": 0xFFFFFF // Default color to prevent undefined errors }; var operationsSlots = { 0: { x: 180, y: 2280, r: 0.15 }, 1: { x: 430, y: 2450, r: 0.15 }, 2: { x: 680, y: 2600, r: 0.15 }, 3: { x: 1380, y: 2600, r: -0.15 }, 4: { x: 1630, y: 2450, r: -0.15 }, 5: { x: 1880, y: 2280, r: -0.15 } }; var levelConfigs = { 1: { "tiles": [["", 1, ""], ["", 1, 1], [1, 1, 1], ["", 1, 1], ["", 1, ""]], "operations": ['-1'] }, 2: { "tiles": [["", 1, ""], ["", 1, 1], [2, 2, 2], ["", 1, 1], ["", 1, ""]], "operations": ['-1', '-1'] }, 3: { "tiles": [["", "", "", "", "", ""], ["", 2, 2, 1, 2, 2], [2, 1, 1, 1, 1, 2], ["", 2, "", "", "", 2], [3, 2, 3, 3, 2, 3], ["", 2, 3, "", 3, 2], [2, 3, 3, 3, 3, 2], ["", 2, 2, 3, 2, 2]], "operations": ["-1", "-2", "+1", "+1"] }, 4: { "tiles": [["", "", 2, 2, 2, ""], ["", "", 2, 1, 1, 2], ["", 2, 1, 2, 1, 2], ["", "", 2, 1, 1, 2], ["", "", 2, 2, 2, ""], ["", "", "", "", "", ""], ["", "", 2, 2, "", ""], ["", "", 2, 1, 2, ""], [1, 1, 2, 2, "", ""]], "operations": ["-1", "-1", "+1", "-1", "-1"] }, 5: { "tiles": [["", "", 3, 3, "", ""], ["", "", 3, 2, 3, ""], ["", 3, 2, 2, 3, ""], ["", 3, 2, 2, 2, 3], [3, 2, 2, 2, 2, 3], ["", "", "", 3, "", ""], ["", "", 3, 3, "", ""], ["", 1, 1, 1, 1, 1], ["", 1, 1, 1, 1, ""]], "operations": ["+1", "-2", "-1"] }, 6: { "tiles": [["", "", 1, "", ""], ["", "", 1, 1, ""], ["", 2, 2, 2, ""], ["", 2, 2, 2, 2], [3, 3, 3, 3, 3], ["", 2, 2, 2, 2], ["", 2, 2, 2, ""], ["", "", 1, 1, ""], ["", "", 1, "", ""]], "operations": ['+1', '+1', '-1', '-2'] }, 7: { "tiles": [[2, "", "", "", "", 1], ["", 2, "", "", "", 3], [2, "", 2, 3, "", 3], ["", 2, 2, "", 3, 3], ["", 2, "", "", 3, ""], ["", "", 1, "", 1, ""], ["", "", 1, 1, "", ""], ["", "", "", 1, "", ""], ["", "", "", "", "", ""]], "operations": ["-2", "-1", "+1"] }, 8: { "tiles": [["", 3, 1, 2, 1, "", ""], ["", 3, 1, 2, 1, "", ""], [3, 1, 2, 1, "", "", ""], ["", "", "", "", 1, 1, ""], [3, 3, 3, 1, 1, 1, 1], ["", 3, 3, 1, 1, 2, ""], ["", 3, 1, 1, 2, 2, ""], ["", "", 1, 1, 2, 2, ""], ["", "", 1, 2, 2, "", ""]], "operations": ["-2", "+2", "-1", "-1", "-1"] }, 9: { "tiles": [["", "", "", "", "", "", ""], ["", 1, 3, 3, 3, 3, 1], [1, 1, 3, 3, 3, 1, 1], ["", 3, 3, 3, 3, 3, 3], [3, 2, 3, 2, 3, 2, 3], ["", 3, 3, 3, 3, 3, 3], [1, 1, 3, 3, 3, 1, 1], ["", 1, 3, 3, 3, 3, 1], ["", "", "", "", "", "", ""]], "operations": ["-2", "+1", "-2"] }, 10: { "tiles": [[1, 2, 1, 1, 1, 1, 1], ["", 3, 3, 3, 3, 2, 1], [1, 2, 1, 1, 1, 1, 1], ["", 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1], ["", 1, 1, 1, 2, 2, 1], [1, 2, 3, 3, 2, 1, 1], ["", 1, 1, 1, 2, 2, 1], [1, 3, 3, 1, 3, 3, 3], ["", 1, 3, 1, 3, 2, 3], [1, 1, 1, 3, 3, 3, 1]], "operations": ["+1", "+2", "-2", "-2"] }, 11: { "tiles": [[3, 3, 2, 3, 3, 4, 3], ["", 3, 2, 3, 3, 3, 3], [3, 2, 3, 3, 3, 4, 3], ["", 3, 2, 3, 3, 3, 3], [3, 2, 2, 2, 1, 2, 2], ["", 3, 2, 3, 3, 3, 3], [3, 2, 3, 3, 3, 4, 3], ["", 3, 2, 3, 3, 3, 3], [3, 3, 2, 3, 3, 4, 3]], "operations": ["-2", "-1", "-1", "-1", "+2", "+2"] }, 12: { "tiles": [["", 2, 2, 2, 2, 2, ""], ["", 2, 1, 1, 1, 1, 2], [2, 1, 3, 3, 3, 1, 2], ["", 1, 3, 2, 2, 3, 1], [2, 1, 3, 1, 3, 1, 2], ["", 1, 3, 2, 2, 3, 1], [2, 1, 3, 3, 3, 1, 2], ["", 2, 1, 1, 1, 1, 2], ["", 2, 2, 2, 2, 2, ""]], "operations": ["-2", "-1", "-1", "+1"] }, 13: { "tiles": [["", "", 3, 3, "", "", ""], ["", "", 3, 4, 3, "", ""], ["", "", 3, 3, "", "", ""], ["", "", "", "", 2, 2, ""], ["", "", "", 2, 3, 2, ""], ["", "", "", "", 2, 2, ""], ["", "", 1, 1, "", "", ""], ["", "", 1, 2, 1, "", ""], ["", "", 1, 1, "", "", ""]], "operations": ["-2", "-2", "-1", "-1", "+1"] }, 14: { "tiles": [[1, 1, 4, 4, 1, 1, 1], ["", 1, 4, 4, 1, 3, 1], [1, 4, 4, 1, 3, 1, 2], ["", 4, 4, 1, 3, 1, 2], [4, 4, 1, 3, 1, 2, 1], ["", 4, 4, 1, 3, 1, 2], [1, 4, 4, 1, 3, 1, 2], ["", 1, 4, 4, 1, 3, 1], [1, 1, 4, 4, 1, 1, 1]], "operations": ["-2", "-1", "-1", "-1", "+1"] }, 15: { "tiles": [["", "", 1, 2, 1, "", ""], ["", "", 1, 2, 2, 1, ""], ["", 1, 2, 2, 2, 1, ""], ["", 1, 2, 2, 2, 2, 1], [1, 1, 1, 1, 1, 1, 1], ["", "", 2, 3, 3, 2, ""], ["", 2, 2, 3, 2, 2, ""], ["", 4, 4, 4, 4, 4, 4], ["", "", "", "", "", "", ""]], "operations": ["-2", "-1", "-1", "+2"] }, 16: { "tiles": [[1, 2, 1, 1, 1, 2, 1], ["", 1, 2, 1, 1, 2, 1], [1, 2, 4, 4, 4, 2, 1], ["", 1, 4, 4, 4, 4, 1], [3, 2, 4, 4, 4, 2, 3], ["", 1, 4, 4, 4, 4, 1], [1, 1, 2, 4, 2, 1, 1], ["", 1, 2, 1, 1, 2, 1], [1, 2, 1, 1, 1, 2, 1]], "operations": ["-2", "-2", "-1", "+1"] }, 17: { "tiles": [["", 3, 3, 3, 3, 3, ""], ["", 3, 3, 3, 3, 3, 3], ["", "", 4, "", "", "", ""], ["", 3, 3, 3, 3, 3, 3], [3, 3, 3, 3, 3, 3, 3], ["", "", "", "", "", 2, ""], [3, 3, 3, 3, 3, 3, 3], ["", 3, 3, 3, 3, 3, 3], ["", 1, "", "", "", "", ""]], "operations": ["-2", "-1", "-1", "+1"] }, 18: { "tiles": [[2, 1, 1, 1, 1, 1, 2], ["", 2, 1, 1, 1, 1, 2], ["", 2, "", 1, "", 2, ""], ["", 2, 3, "", "", 3, 2], [2, 3, 4, 1, 4, 3, 2], ["", 2, 3, 1, 1, 3, 2], [2, 3, 4, 1, 4, 3, 2], ["", 2, 3, 1, 1, 3, 2], [2, 3, 4, 1, 4, 3, 2], ["", 2, 3, "", "", 3, 2], ["", 2, 3, 1, 3, 2, ""]], "operations": ["-2", "-1", "-1", "+1", "+2"] }, 19: { "tiles": [["", 1, "", "", "", 1, ""], ["", 1, 1, "", "", 1, 1], [1, 1, 1, "", 1, 1, 1], ["", 4, 4, 4, 4, 4, 4], [4, 2, 2, 2, 2, 2, 4], ["", 2, 4, 4, 4, 4, 2], [4, 2, 2, 2, 2, 2, 4], ["", 4, 4, 4, 4, 4, 4], [1, 1, 1, "", 1, 1, 1], ["", 1, 1, "", "", 1, 1], ["", 1, "", "", "", 1, ""]], "operations": ["-3", "-1", "+2"] }, 20: { "tiles": [["", "", "", 1, 2, 3, 1], ["", "", 1, 1, 2, 3, 1], [1, 1, 2, 2, 3, 1, 2], ["", 2, 2, 3, 3, 1, 2], [3, 3, 3, 1, 1, 2, 2], ["", 1, 1, 1, 2, 2, 2], [2, 2, 2, 2, 2, 2, 3], ["", 2, 2, 2, 2, 3, 3], [3, 3, 3, 3, 3, 2, 2], ["", 2, 2, 2, 2, 2, 1], [1, 1, 1, 1, 1, 1, ""]], "operations": ["-1", "-1", "-1", "-1", "+2"] } }; /***********************************************************************************************/ /***************************************** GAME INITIALISATION *********************************/ /***********************************************************************************************/ function initializeGame() { backgroundLayer = new Container(); middleLayer = new Container(); foregroundLayer = new Container(); backgroundImage = new BackgroundImage(); backgroundLayer.addChild(backgroundImage); game.addChild(backgroundLayer); game.addChild(middleLayer); game.addChild(foregroundLayer); boardContainer = new Container(); middleLayer.addChild(boardContainer); boardContainer.x = 0; boardContainer.y = 0; puzzleManager = new PuzzleManager(game); startButton = new StartButton(); startButton.x = centerX; // Center horizontally startButton.y = centerY; // Center vertically startButton.visible = true; game.addChild(startButton); resetButton = new ResetButton(); resetButton.x = game.width - 150; // Position at top right resetButton.y = 130; resetButton.visible = false; // Keep it non-visible initially // Initialize levelNumberText using LevelNumberText class levelNumberText = new LevelNumberText(puzzleManager.currentLevel); backgroundLayer.addChild(levelNumberText); foregroundLayer.addChild(resetButton); menuButton = new MenuButton(); menuButton.x = 350; // Position at top left menuButton.y = 130; menuButton.visible = true; // Make it visible initially foregroundLayer.addChild(menuButton); menuBoard = new MenuBoard(); middleLayer.addChild(menuBoard); } initializeGame();
===================================================================
--- original.js
+++ change.js
@@ -492,23 +492,26 @@
}
}
};
self.animateEntrance = function () {
- self.menuCells.forEach(function (row) {
- row.forEach(function (cell) {
+ self.menuCells.forEach(function (row, rowIndex) {
+ row.forEach(function (cell, colIndex) {
// Start cells off-screen to the right
- cell.x = 2048 + cell.width;
+ cell.x = 2048 + cell.baseX + cell.width;
cell.visible = true;
log("Animating entrance for cell at initial position:", cell.x, cell.y); // Log initial position
// Animate cells to their base positions
tween(cell, {
x: cell.baseX,
y: cell.baseY
}, {
- duration: 800,
+ duration: 2000,
easing: tween.easeOut,
+ delay: colIndex * 200,
+ // Delay each column by 200ms
onFinish: function onFinish() {
log("Completed animation for cell to base position:", cell.baseX, cell.baseY); // Log completion
+ isMenuReady = true;
} //{4e.1}
});
});
});
@@ -1509,9 +1512,9 @@
log("Initializing MENU State");
//menuBoard.x = 2048; // Start off-screen to the right
menuBoard.visible = true;
menuBoard.animateEntrance();
- isMenuReady = true;
+ //isMenuReady = true;
/*
tween(menuBoard, {
x: 0
}, {
tick
Sound effect
tileEntrance
Sound effect
tileRemove
Sound effect
operationSelect
Sound effect
operationCancel
Sound effect
tileChangeValue
Sound effect
resetSound
Sound effect
levelFailed
Sound effect
menuLevelSelect
Sound effect
menuCellEnter
Sound effect
applause
Sound effect
bgMusic
Music
tada
Sound effect