Code edit (1 edits merged)
Please save this source code
User prompt
for entrance anim, Adjust tile placement to include negative x and y
User prompt
fix `Place tiles randomly out of the screen` because not tiles come from top or left of the screen
User prompt
``` // Place tiles randomly out of the screen tile.x = Math.random() * 2048; tile.y = Math.random() * 2732; ``` should also places tiles at -tile.width and -tile.height to cover all screen borders, not only right and bottom
Code edit (4 edits merged)
Please save this source code
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'animateTilesEntrance')' in or related to this line: 'self.animateTilesEntrance = function () {' Line Number: 248
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'animateTilesEntrance')' in or related to this line: 'self.animateTilesEntrance = function () {' Line Number: 885
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'animateTilesEntrance')' in or related to this line: 'self.animateTilesEntrance = function () {' Line Number: 885
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'animateTilesEntrance')' in or related to this line: 'self.animateTilesEntrance = function () {' Line Number: 885
User prompt
Please fix the bug: 'self.animateTilesEntrance is not a function' in or related to this line: 'self.animateTilesEntrance();' Line Number: 288
User prompt
in loadLevel after `self.createOperations();` call an new function animateTilesEntrance(). in this function follow the folowing scenario: - place tiles randomly out of the screen - make them visible - then animate their move to their baseX, baseY
Code edit (6 edits merged)
Please save this source code
User prompt
rework the code to simplify operations in levelConfigs: for example instead of `operations: [{ type: '-1', uses: 2 }, { type: '-2', uses: 1 }]` simplify into `operations: ['-1', '-1', '-2']` (remove the 'uses' notion)
Code edit (1 edits merged)
Please save this source code
User prompt
in createOperations, when there are more than 3 operations, place operations after the 3rd at y = baseY-200
Code edit (15 edits merged)
Please save this source code
User prompt
in createBoard() loop, determine the maxTilesInRow
User prompt
in (), determine maxTilesInRow
User prompt
in createBoard(), add a local variable to track largest number of tiles in the level rows
Code edit (1 edits merged)
Please save this source code
Code edit (10 edits merged)
Please save this source code
User prompt
in isPointInsideTile, decompose overlapOffset into overlapOffsetX and overlapOffsetY
Code edit (4 edits merged)
Please save this source code
User prompt
in PuzzleManager reset(), remove all existing tiles and operations before loading level
Code edit (1 edits merged)
Please save this source code
/****
* Plugins
****/
var tween = LK.import("@upit/tween.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
});
return self;
});
/***********************************************************************************************/
/******************************************* ASSETS CLASSES ************************************/
/***********************************************************************************************/
// HexTile class to represent each tile on the board
var HexTile = Container.expand(function (value, col, row, levelData, levelBoardOffsetX, levelBoardOffsetY) {
var self = Container.call(this);
// Constants
var interTileOffsetX = -2;
var interTileOffsetY = -0; // relative to interTileOffsetX
var tileSize = LK.getAsset('hexTile', {}).width + interTileOffsetX;
var tileOffsetX = tileSize;
var tileOffsetY = tileSize * 0.75 - interTileOffsetY;
// Properties
self.value = value;
self.originalValue = value;
self.col = col;
self.row = row;
self.neighbors = [];
var tileX = col * tileOffsetX - (levelData ? levelData.tiles.length : 0) * (tileSize / 2) + (row % 2 === 1 ? -tileSize / 2 : 0);
var tileY = row * tileOffsetY - (levelData ? levelData.tiles.length : 0) * (tileSize / 2);
self.x = levelBoardOffsetX + tileX;
self.y = levelBoardOffsetY + 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,
//levelBoardOffsetX + tileX,
y: 0,
//levelBoardOffsetY + tileY,
tint: tileColors[self.value],
alpha: 0.9
});
// Value text shadow
var valueTextShadow = new Text2(self.value.toString(), {
size: tileSize * 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 - tileSize * 0.01 + 12;
self.valueTextShadow = self.addChild(valueTextShadow);
// Value Text
var valueText = new Text2(self.value.toString(), {
size: tileSize * 0.5,
fill: 0xEAEEE8,
dropShadow: false
});
valueText.anchor.set(0.5, 0.5);
valueText.x = tileGraphics.x;
valueText.y = tileGraphics.y - tileSize * 0.01;
self.valueText = self.addChild(valueText);
// Functions
self.setValue = function (newValue, depth) {
LK.setTimeout(function () {
// Enclose operation in a timeout
log("setValue to ", newValue, depth);
self.value = newValue;
if (self.value === 0) {
self.valueTextShadow.setText("");
self.valueText.setText("");
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 {
self.valueText.setText(self.value.toString());
self.valueTextShadow.setText(self.value.toString());
}
// Animate color change
tween(tileGraphics, {
tint: tileColors[self.value]
}, {
duration: 500,
easing: tween.easeOut
});
}, depth * 150); // Delay proportional to normalized distance
};
return self;
});
// OperationButton class to represent each operation button
var OperationButton = Container.expand(function (type, uses) {
var self = Container.call(this);
// Properties
self.type = type;
self.remainingUses = uses;
self.baseX = 0; // Initialize baseX to store initial x position
self.baseY = 0; // Initialize baseY to store initial y position
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
});
// Value Text
var valueText = new Text2(self.type, {
size: buttonSize * 0.45,
fill: tileColors[1],
dropShadow: false,
weight: 1000
});
valueText.anchor.set(0.5, 0.5);
valueText.x = buttonGraphics.x;
valueText.y = buttonGraphics.y;
self.valueText = self.addChild(valueText);
// Functions
self.setBasePosition = function (x, y) {
self.x = x;
self.y = y;
self.baseX = x;
self.baseY = y;
};
self.updateUses = function () {
// Update the display or logic related to remaining uses
log("Remaining uses updated: ", self.remainingUses);
};
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.disable = function () {
buttonGraphics.alpha = 0.5; // Dim the button to indicate it's disabled
self.interactive = false; // Disable interaction
};
self.enable = function () {
buttonGraphics.alpha = 1.0; // Restore full opacity to indicate it's enabled
self.interactive = true; // Enable interaction
};
self.activate = function () {
self.visible = true;
};
self.deactivate = function () {
self.visible = false;
};
return self;
});
// StartButton class to represent the start button
var StartButton = Container.expand(function () {
var self = Container.call(this);
// Asset Attachments
var buttonGraphics = self.attachAsset('startButton', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 0
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000 // Set game background to black
});
/****
* Game Code
****/
// Transition to menu state
/***********************************************************************************************/
/************************************* GAME OBJECTS CLASSES ************************************/
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 = 1;
self.board = [];
self.operations = [];
self.isAnimating = false;
self.selectedOperation = null;
self.moveCount = 0;
self.levelData = null;
// Core Functions
self.initPuzzle = function () {
self.loadLevel(self.currentLevel);
};
self.reset = function () {
self.loadLevel(self.currentLevel);
};
self.loadLevel = function (levelNumber) {
// Load level configuration
self.levelData = levelConfigs[levelNumber] || {
tiles: [],
operations: []
};
self.createBoard();
self.fillTilesNeighbors();
self.createOperations();
};
self.createBoard = function () {
self.board = [];
self.activeTileCount = 0; // Reset active tile count
// Update levelBoardOffsets depending on level
self.levelBoardOffsetX = 300;
self.levelBoardOffsetY = 150;
for (var row = 0; row < self.levelData.tiles.length; row++) {
for (var col = 0; col < self.levelData.tiles[row].length; col++) {
var value = self.levelData.tiles[row][col];
if (value !== "") {
var tile = new HexTile(value, col, row, self.levelData, self.levelBoardOffsetX, self.levelBoardOffsetY);
self.board.push(tile);
boardContainer.addChild(tile);
self.activeTileCount++; // Increment active tile count
}
}
}
};
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) {
var dx = Math.abs(tile1.col - tile2.col);
var dy = Math.abs(tile1.row - tile2.row);
return dx === 1 && dy === 0 || dx === 0 && dy === 1 || dx === 1 && dy === 1;
};
self.createOperations = function () {
self.operations = [];
for (var i = 0; i < self.levelData.operations.length; i++) {
var opData = self.levelData.operations[i];
var operation = new OperationButton(opData.type, opData.uses);
self.operations.push(operation);
operation.setBasePosition(centerX + 600 + (i - (self.levelData.operations.length - 1) / 2) * 250, 2600); // Space buttons evenly and position near the bottom
self.game.addChild(operation);
}
};
self.applyOperation = function (operation, tile) {
if (operation.remainingUses > 0) {
self.propagateOperation(operation, tile);
operation.remainingUses--;
operation.updateUses();
self.checkWinCondition();
}
};
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 = currentTile.value + parseInt(operation.type);
if (newValue == 0) {
self.activeTileCount--;
}
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.checkWinCondition = function () {
log("checkWinCondition... Active tiles:", self.activeTileCount);
if (self.activeTileCount == 0) {
self.playVictoryAnimation();
isPlaying = false;
LK.setTimeout(function () {
self.currentLevel++; // Advance to the next level
changeGameState(GAME_STATE.NEW_ROUND); // Change state to newRound
}, 2000);
}
};
// Animation Functions
self.playVictoryAnimation = function () {
log("playVictoryAnimation...");
// Play level complete animation
};
}
/***********************************************************************************************/
/************************************* 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 overlapOffset = 33; // Offset to prevent multiple tile selection
return x >= boardContainer.x + tile.x - tile.width / 2 + overlapOffset && x <= boardContainer.x + tile.x + tile.width / 2 - overlapOffset && y >= boardContainer.y + tile.y - tile.height / 2 + overlapOffset && y <= boardContainer.y + tile.y + tile.height / 2 - overlapOffset;
}
/***********************************************************************************************/
/************************************* GAME STATE MANAGEMENT ************************************/
/***********************************************************************************************/
function initMenuState() {
// Initialize the game state for MENU
log("Initializing MENU State");
startButton.visible = true;
if (debug) {
changeGameState(GAME_STATE.NEW_ROUND);
}
}
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");
startButton.visible = false;
}
function initNewRoundState() {
// Initialize the game state for NEW_ROUND
log("Initializing NEW_ROUND State");
puzzleManager.initPuzzle();
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");
resetButton.visible = true; // 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");
}
function initScoreState() {
// Initialize the game state for SCORE
log("Initializing SCORE State");
}
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:
// Do nothing
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.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.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.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.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 handleMenuStateDown(x, y, obj) {
// Implement logic for handling down event in MENU state
log("Handling down event in MENU state");
changeGameState(GAME_STATE.NEW_ROUND);
}
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);
if (x >= resetButton.x - resetButton.width / 2 && x <= resetButton.x + resetButton.width / 2 && y >= resetButton.y - resetButton.height / 2 && y <= resetButton.y + resetButton.height / 2) {
log("Reset button pressed");
puzzleManager.reset(); // Reset the level puzzle
return;
}
puzzleManager.operations.forEach(function (operation) {
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;
return;
}
});
}
function handlePlayingStateMove(x, y, obj) {
//log("Handling move event in PLAYING state", dragNode);
if (dragNode) {
dragNode.x = x;
dragNode.y = y;
puzzleManager.board.forEach(function (tile) {
if (isPointInsideTile(x, y, tile)) {
if (!tile.isHighlighted) {
tile.isHighlighted = true;
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.2,
scaleY: 1.2
}, {
duration: 200,
easing: tween.easeOut
});
}
} else if (tile.isHighlighted) {
tile.isHighlighted = false;
boardContainer.addChildAt(tile, tile.previousZIndex); // Restore tile's original z-index
tween(tile, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeOut
});
}
});
}
//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
puzzleManager.applyOperation(dragNode, tile);
tileFound = true;
tween(tile, {
// Restore tile size after operation is applied
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeOut
}); //{4x.1}
tween(dragNode, {
alpha: 0
}, {
duration: 500,
easing: tween.easeOut,
onFinish: function onFinish() {
if (dragNode) {
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");
tween(dragNode, {
x: dragNode.baseX,
y: dragNode.baseY
}, {
duration: 500,
easing: tween.easeOut
});
}
dragNode = null;
}
}
// Score State Handlers
function handleScoreStateDown(x, y, obj) {
// Implement logic for handling down event in SCORE state
log("Handling down event in SCORE state");
}
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 startButton;
var backgroundLayer;
var middleLayer;
var foregroundLayer;
var backgroundImage;
var centerX = 1024;
var centerY = 1366;
var dragNode = null;
var resetButton; // Declare resetButton as a global variable
var tileColors = {
0: 0xEAEEE8,
// White / Gray
1: 0x1E90FF,
// Blue
2: 0xF93827,
// Red
4: 0xFFD65A,
// Yellow light
3: 0xFF9D23 // Yellow / Orange
};
var levelConfigs = {
1: {
tiles: [["", 1, ""], ["", 1, 1], [1, 1, 1], ["", 1, 1], ["", 1, ""]],
operations: [{
type: '-1',
uses: 1
}]
},
2: {
tiles: [["", 1, ""], ["", 1, 1], [2, 2, 2], ["", 1, 1], ["", 1, ""]],
operations: [{
type: '-1',
uses: 1
}, {
type: '-1',
uses: 1
}]
}
}; // Example configuration for two levels
/***********************************************************************************************/
/***************************************** 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 = centerX;
boardContainer.y = centerY;
puzzleManager = new PuzzleManager(game);
startButton = new StartButton();
startButton.x = centerX; // Center horizontally
startButton.y = centerY; // Center vertically
game.addChild(startButton);
startButton.visible = false;
resetButton = new ResetButton();
resetButton.x = game.width - 150; // Position at top right
resetButton.y = 150;
resetButton.visible = false; // Keep it non-visible initially
foregroundLayer.addChild(resetButton);
// Transition to menu state
changeGameState(GAME_STATE.MENU);
}
initializeGame();
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