Code edit (1 edits merged)
Please save this source code
User prompt
Picture Perfect Puzzler
Initial prompt
A game where players rearrange shuffled picture tiles to form clear images like trees, houses, and cars. The game has 10 levels with increasing difficulty and each completed level gives 50 points. After finishing a level, a "Wow! You finished Level X!" message appears with a celebration. Completing all 10 levels shows a final message: "You won the match!" with total score.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { currentLevel: 1, highestLevel: 1 }); /**** * Classes ****/ var EmptySpace = Container.expand(function (row, col, gridSize) { var self = Container.call(this); self.currentRow = row; self.currentCol = col; var tileSize = Math.floor(2000 / gridSize); // Create a visual representation of the empty space var emptyGraphics = self.attachAsset('emptySpace', { anchorX: 0.5, anchorY: 0.5, width: tileSize - 10, height: tileSize - 10, alpha: 0.5 }); self.moveTo = function (row, col) { var targetX = tileGame.getXPositionForCol(col); var targetY = tileGame.getYPositionForRow(row); self.currentRow = row; self.currentCol = col; self.x = targetX; self.y = targetY; }; return self; }); var LevelCompletePopup = Container.expand(function (level, moveCount) { var self = Container.call(this); // Background panel var panel = self.attachAsset('levelComplete', { anchorX: 0.5, anchorY: 0.5 }); // Title var titleText = new Text2("Level " + level + " Complete!", { size: 80, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0); titleText.y = -150; self.addChild(titleText); // Moves text var movesText = new Text2("Completed in " + moveCount + " moves", { size: 50, fill: 0xFFFFFF }); movesText.anchor.set(0.5, 0); movesText.y = -50; self.addChild(movesText); // Next level button text var nextLevelText = new Text2("Tap to continue", { size: 60, fill: 0xFFFFFF }); nextLevelText.anchor.set(0.5, 0); nextLevelText.y = 80; self.addChild(nextLevelText); // Handle tap to continue self.down = function () { if (tileGame) { self.destroy(); tileGame.startNextLevel(); } }; return self; }); var Tile = Container.expand(function (id, imageId, row, col, gridSize) { var self = Container.call(this); self.id = id; self.currentRow = row; self.currentCol = col; self.targetRow = row; self.targetCol = col; self.gridSize = gridSize; var tileSize = Math.floor(2000 / gridSize); // Create a background tile var background = self.attachAsset('tile', { anchorX: 0.5, anchorY: 0.5, width: tileSize - 10, height: tileSize - 10 }); // Add text showing the tile number (for development and as a fallback) var tileText = new Text2(String(id + 1), { size: tileSize / 3, fill: 0xFFFFFF }); tileText.anchor.set(0.5, 0.5); self.addChild(tileText); // If we have an image for this tile, we would create and add it here // This would be implemented in the final version with real images // Set up event handlers self.down = function (x, y, obj) { // Handle tile selection if (tileGame) { tileGame.attemptMove(self); } }; self.isMovable = function () { if (!tileGame || !tileGame.emptySpace) { return false; } // Check if this tile is adjacent to the empty space var emptyRow = tileGame.emptySpace.currentRow; var emptyCol = tileGame.emptySpace.currentCol; return self.currentRow === emptyRow && Math.abs(self.currentCol - emptyCol) === 1 || self.currentCol === emptyCol && Math.abs(self.currentRow - emptyRow) === 1; }; self.moveTo = function (row, col, animate) { var targetX = tileGame.getXPositionForCol(col); var targetY = tileGame.getYPositionForRow(row); self.currentRow = row; self.currentCol = col; if (animate) { // Use tween for smooth animation LK.getSound('slide').play(); tween(self, { x: targetX, y: targetY }, { duration: 200, easing: tween.easeOut }); } else { // Immediate positioning without animation self.x = targetX; self.y = targetY; } }; self.isInCorrectPosition = function () { return self.currentRow === self.targetRow && self.currentCol === self.targetCol; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x282c34 }); /**** * Game Code ****/ // Game variables var tileGame = null; var tiles = []; var moveCount = 0; var currentLevel = storage.currentLevel || 1; var highestLevel = storage.highestLevel || 1; var gridSizes = [3, 3, 4, 4, 4, 5, 5, 5, 6, 6]; // Grid size for each level var levelStartTime = 0; // Game UI elements var levelText = new Text2("Level: " + currentLevel, { size: 60, fill: 0xFFFFFF }); levelText.anchor.set(0, 0); LK.gui.topRight.addChild(levelText); levelText.x = -300; levelText.y = 30; var movesText = new Text2("Moves: 0", { size: 60, fill: 0xFFFFFF }); movesText.anchor.set(0, 0); LK.gui.topRight.addChild(movesText); movesText.x = -300; movesText.y = 100; // Game object var TileGame = function TileGame() { this.tiles = []; this.emptySpace = null; this.boardSize = 0; this.gridSize = 3; this.tileSize = 0; this.boardX = 0; this.boardY = 0; this.isLevelComplete = false; this.init = function (level) { moveCount = 0; this.isLevelComplete = false; levelStartTime = Date.now(); // Update UI levelText.setText("Level: " + level); movesText.setText("Moves: " + moveCount); // Calculate grid size for this level this.gridSize = gridSizes[level - 1] || 3; // Default to 3 if level not found this.tileSize = Math.floor(2000 / this.gridSize); // Calculate board position to center it this.boardSize = this.tileSize * this.gridSize; this.boardX = (2048 - this.boardSize) / 2 + this.tileSize / 2; this.boardY = (2732 - this.boardSize) / 2 + this.tileSize / 2; // Clear existing tiles for (var i = 0; i < this.tiles.length; i++) { this.tiles[i].destroy(); } if (this.emptySpace) { this.emptySpace.destroy(); } this.tiles = []; // Create tiles var totalTiles = this.gridSize * this.gridSize - 1; // One spot remains empty for (var i = 0; i < totalTiles; i++) { var row = Math.floor(i / this.gridSize); var col = i % this.gridSize; var tile = new Tile(i, "image_" + level + "_" + i, row, col, this.gridSize); this.tiles.push(tile); game.addChild(tile); tile.moveTo(row, col, false); } // Create empty space at the bottom right var emptyRow = this.gridSize - 1; var emptyCol = this.gridSize - 1; this.emptySpace = new EmptySpace(emptyRow, emptyCol, this.gridSize); game.addChild(this.emptySpace); this.emptySpace.moveTo(emptyRow, emptyCol); // Shuffle the tiles this.shuffleTiles(); }; this.getXPositionForCol = function (col) { return this.boardX + col * this.tileSize; }; this.getYPositionForRow = function (row) { return this.boardY + row * this.tileSize; }; this.shuffleTiles = function () { // Perform random moves to shuffle var moves = this.gridSize * this.gridSize * 20; // Number of random moves for (var i = 0; i < moves; i++) { var adjacentTiles = this.getAdjacentTiles(); if (adjacentTiles.length > 0) { var randomIndex = Math.floor(Math.random() * adjacentTiles.length); var tileToMove = adjacentTiles[randomIndex]; this.moveTile(tileToMove, false); } } }; this.getAdjacentTiles = function () { var emptyRow = this.emptySpace.currentRow; var emptyCol = this.emptySpace.currentCol; var adjacentTiles = []; // Check all tiles for adjacency to empty space for (var i = 0; i < this.tiles.length; i++) { var tile = this.tiles[i]; if (tile.currentRow === emptyRow && Math.abs(tile.currentCol - emptyCol) === 1 || tile.currentCol === emptyCol && Math.abs(tile.currentRow - emptyRow) === 1) { adjacentTiles.push(tile); } } return adjacentTiles; }; this.moveTile = function (tile, countMove) { if (!tile || this.isLevelComplete) { return; } var emptyRow = this.emptySpace.currentRow; var emptyCol = this.emptySpace.currentCol; // Swap positions var tileRow = tile.currentRow; var tileCol = tile.currentCol; tile.moveTo(emptyRow, emptyCol, true); this.emptySpace.moveTo(tileRow, tileCol); if (countMove) { moveCount++; movesText.setText("Moves: " + moveCount); } // Check if puzzle is solved if (this.isPuzzleSolved()) { this.levelComplete(); } }; this.attemptMove = function (tile) { if (tile.isMovable()) { this.moveTile(tile, true); } }; this.isPuzzleSolved = function () { // Check if all tiles are in their correct positions for (var i = 0; i < this.tiles.length; i++) { if (!this.tiles[i].isInCorrectPosition()) { return false; } } return true; }; this.levelComplete = function () { if (this.isLevelComplete) { return; } this.isLevelComplete = true; // Play completion sound LK.getSound('complete').play(); // Flash screen to indicate success LK.effects.flashScreen(0x00ff00, 500); // Increment score based on level and moves var baseScore = currentLevel * 100; var moveScore = Math.max(0, 1000 - moveCount * 5); var totalScore = baseScore + moveScore; LK.setScore(LK.getScore() + totalScore); // Update storage if needed if (currentLevel >= highestLevel) { highestLevel = currentLevel + 1; storage.highestLevel = highestLevel; } // Show level complete popup after a short delay LK.setTimeout(function () { var popup = new LevelCompletePopup(currentLevel, moveCount); popup.x = 2048 / 2; popup.y = 2732 / 2; game.addChild(popup); }, 800); }; this.startNextLevel = function () { currentLevel++; if (currentLevel > 10) { // Player completed all levels LK.showYouWin(); return; } storage.currentLevel = currentLevel; this.init(currentLevel); }; }; // Initialize game tileGame = new TileGame(); tileGame.init(currentLevel); // Play background music LK.playMusic('bgmusic'); // Main game loop game.update = function () { // Game logic that needs to run every frame would go here }; // Handle game-wide touch events game.down = function (x, y, obj) { // Any game-wide touch handling logic would go here }; game.move = function (x, y, obj) { // Any game-wide move handling logic would go here }; game.up = function (x, y, obj) { // Any game-wide touch release handling logic would go here };
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,351 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1", {
+ currentLevel: 1,
+ highestLevel: 1
+});
+
+/****
+* Classes
+****/
+var EmptySpace = Container.expand(function (row, col, gridSize) {
+ var self = Container.call(this);
+ self.currentRow = row;
+ self.currentCol = col;
+ var tileSize = Math.floor(2000 / gridSize);
+ // Create a visual representation of the empty space
+ var emptyGraphics = self.attachAsset('emptySpace', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: tileSize - 10,
+ height: tileSize - 10,
+ alpha: 0.5
+ });
+ self.moveTo = function (row, col) {
+ var targetX = tileGame.getXPositionForCol(col);
+ var targetY = tileGame.getYPositionForRow(row);
+ self.currentRow = row;
+ self.currentCol = col;
+ self.x = targetX;
+ self.y = targetY;
+ };
+ return self;
+});
+var LevelCompletePopup = Container.expand(function (level, moveCount) {
+ var self = Container.call(this);
+ // Background panel
+ var panel = self.attachAsset('levelComplete', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Title
+ var titleText = new Text2("Level " + level + " Complete!", {
+ size: 80,
+ fill: 0xFFFFFF
+ });
+ titleText.anchor.set(0.5, 0);
+ titleText.y = -150;
+ self.addChild(titleText);
+ // Moves text
+ var movesText = new Text2("Completed in " + moveCount + " moves", {
+ size: 50,
+ fill: 0xFFFFFF
+ });
+ movesText.anchor.set(0.5, 0);
+ movesText.y = -50;
+ self.addChild(movesText);
+ // Next level button text
+ var nextLevelText = new Text2("Tap to continue", {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ nextLevelText.anchor.set(0.5, 0);
+ nextLevelText.y = 80;
+ self.addChild(nextLevelText);
+ // Handle tap to continue
+ self.down = function () {
+ if (tileGame) {
+ self.destroy();
+ tileGame.startNextLevel();
+ }
+ };
+ return self;
+});
+var Tile = Container.expand(function (id, imageId, row, col, gridSize) {
+ var self = Container.call(this);
+ self.id = id;
+ self.currentRow = row;
+ self.currentCol = col;
+ self.targetRow = row;
+ self.targetCol = col;
+ self.gridSize = gridSize;
+ var tileSize = Math.floor(2000 / gridSize);
+ // Create a background tile
+ var background = self.attachAsset('tile', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: tileSize - 10,
+ height: tileSize - 10
+ });
+ // Add text showing the tile number (for development and as a fallback)
+ var tileText = new Text2(String(id + 1), {
+ size: tileSize / 3,
+ fill: 0xFFFFFF
+ });
+ tileText.anchor.set(0.5, 0.5);
+ self.addChild(tileText);
+ // If we have an image for this tile, we would create and add it here
+ // This would be implemented in the final version with real images
+ // Set up event handlers
+ self.down = function (x, y, obj) {
+ // Handle tile selection
+ if (tileGame) {
+ tileGame.attemptMove(self);
+ }
+ };
+ self.isMovable = function () {
+ if (!tileGame || !tileGame.emptySpace) {
+ return false;
+ }
+ // Check if this tile is adjacent to the empty space
+ var emptyRow = tileGame.emptySpace.currentRow;
+ var emptyCol = tileGame.emptySpace.currentCol;
+ return self.currentRow === emptyRow && Math.abs(self.currentCol - emptyCol) === 1 || self.currentCol === emptyCol && Math.abs(self.currentRow - emptyRow) === 1;
+ };
+ self.moveTo = function (row, col, animate) {
+ var targetX = tileGame.getXPositionForCol(col);
+ var targetY = tileGame.getYPositionForRow(row);
+ self.currentRow = row;
+ self.currentCol = col;
+ if (animate) {
+ // Use tween for smooth animation
+ LK.getSound('slide').play();
+ tween(self, {
+ x: targetX,
+ y: targetY
+ }, {
+ duration: 200,
+ easing: tween.easeOut
+ });
+ } else {
+ // Immediate positioning without animation
+ self.x = targetX;
+ self.y = targetY;
+ }
+ };
+ self.isInCorrectPosition = function () {
+ return self.currentRow === self.targetRow && self.currentCol === self.targetCol;
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x282c34
+});
+
+/****
+* Game Code
+****/
+// Game variables
+var tileGame = null;
+var tiles = [];
+var moveCount = 0;
+var currentLevel = storage.currentLevel || 1;
+var highestLevel = storage.highestLevel || 1;
+var gridSizes = [3, 3, 4, 4, 4, 5, 5, 5, 6, 6]; // Grid size for each level
+var levelStartTime = 0;
+// Game UI elements
+var levelText = new Text2("Level: " + currentLevel, {
+ size: 60,
+ fill: 0xFFFFFF
+});
+levelText.anchor.set(0, 0);
+LK.gui.topRight.addChild(levelText);
+levelText.x = -300;
+levelText.y = 30;
+var movesText = new Text2("Moves: 0", {
+ size: 60,
+ fill: 0xFFFFFF
+});
+movesText.anchor.set(0, 0);
+LK.gui.topRight.addChild(movesText);
+movesText.x = -300;
+movesText.y = 100;
+// Game object
+var TileGame = function TileGame() {
+ this.tiles = [];
+ this.emptySpace = null;
+ this.boardSize = 0;
+ this.gridSize = 3;
+ this.tileSize = 0;
+ this.boardX = 0;
+ this.boardY = 0;
+ this.isLevelComplete = false;
+ this.init = function (level) {
+ moveCount = 0;
+ this.isLevelComplete = false;
+ levelStartTime = Date.now();
+ // Update UI
+ levelText.setText("Level: " + level);
+ movesText.setText("Moves: " + moveCount);
+ // Calculate grid size for this level
+ this.gridSize = gridSizes[level - 1] || 3; // Default to 3 if level not found
+ this.tileSize = Math.floor(2000 / this.gridSize);
+ // Calculate board position to center it
+ this.boardSize = this.tileSize * this.gridSize;
+ this.boardX = (2048 - this.boardSize) / 2 + this.tileSize / 2;
+ this.boardY = (2732 - this.boardSize) / 2 + this.tileSize / 2;
+ // Clear existing tiles
+ for (var i = 0; i < this.tiles.length; i++) {
+ this.tiles[i].destroy();
+ }
+ if (this.emptySpace) {
+ this.emptySpace.destroy();
+ }
+ this.tiles = [];
+ // Create tiles
+ var totalTiles = this.gridSize * this.gridSize - 1; // One spot remains empty
+ for (var i = 0; i < totalTiles; i++) {
+ var row = Math.floor(i / this.gridSize);
+ var col = i % this.gridSize;
+ var tile = new Tile(i, "image_" + level + "_" + i, row, col, this.gridSize);
+ this.tiles.push(tile);
+ game.addChild(tile);
+ tile.moveTo(row, col, false);
+ }
+ // Create empty space at the bottom right
+ var emptyRow = this.gridSize - 1;
+ var emptyCol = this.gridSize - 1;
+ this.emptySpace = new EmptySpace(emptyRow, emptyCol, this.gridSize);
+ game.addChild(this.emptySpace);
+ this.emptySpace.moveTo(emptyRow, emptyCol);
+ // Shuffle the tiles
+ this.shuffleTiles();
+ };
+ this.getXPositionForCol = function (col) {
+ return this.boardX + col * this.tileSize;
+ };
+ this.getYPositionForRow = function (row) {
+ return this.boardY + row * this.tileSize;
+ };
+ this.shuffleTiles = function () {
+ // Perform random moves to shuffle
+ var moves = this.gridSize * this.gridSize * 20; // Number of random moves
+ for (var i = 0; i < moves; i++) {
+ var adjacentTiles = this.getAdjacentTiles();
+ if (adjacentTiles.length > 0) {
+ var randomIndex = Math.floor(Math.random() * adjacentTiles.length);
+ var tileToMove = adjacentTiles[randomIndex];
+ this.moveTile(tileToMove, false);
+ }
+ }
+ };
+ this.getAdjacentTiles = function () {
+ var emptyRow = this.emptySpace.currentRow;
+ var emptyCol = this.emptySpace.currentCol;
+ var adjacentTiles = [];
+ // Check all tiles for adjacency to empty space
+ for (var i = 0; i < this.tiles.length; i++) {
+ var tile = this.tiles[i];
+ if (tile.currentRow === emptyRow && Math.abs(tile.currentCol - emptyCol) === 1 || tile.currentCol === emptyCol && Math.abs(tile.currentRow - emptyRow) === 1) {
+ adjacentTiles.push(tile);
+ }
+ }
+ return adjacentTiles;
+ };
+ this.moveTile = function (tile, countMove) {
+ if (!tile || this.isLevelComplete) {
+ return;
+ }
+ var emptyRow = this.emptySpace.currentRow;
+ var emptyCol = this.emptySpace.currentCol;
+ // Swap positions
+ var tileRow = tile.currentRow;
+ var tileCol = tile.currentCol;
+ tile.moveTo(emptyRow, emptyCol, true);
+ this.emptySpace.moveTo(tileRow, tileCol);
+ if (countMove) {
+ moveCount++;
+ movesText.setText("Moves: " + moveCount);
+ }
+ // Check if puzzle is solved
+ if (this.isPuzzleSolved()) {
+ this.levelComplete();
+ }
+ };
+ this.attemptMove = function (tile) {
+ if (tile.isMovable()) {
+ this.moveTile(tile, true);
+ }
+ };
+ this.isPuzzleSolved = function () {
+ // Check if all tiles are in their correct positions
+ for (var i = 0; i < this.tiles.length; i++) {
+ if (!this.tiles[i].isInCorrectPosition()) {
+ return false;
+ }
+ }
+ return true;
+ };
+ this.levelComplete = function () {
+ if (this.isLevelComplete) {
+ return;
+ }
+ this.isLevelComplete = true;
+ // Play completion sound
+ LK.getSound('complete').play();
+ // Flash screen to indicate success
+ LK.effects.flashScreen(0x00ff00, 500);
+ // Increment score based on level and moves
+ var baseScore = currentLevel * 100;
+ var moveScore = Math.max(0, 1000 - moveCount * 5);
+ var totalScore = baseScore + moveScore;
+ LK.setScore(LK.getScore() + totalScore);
+ // Update storage if needed
+ if (currentLevel >= highestLevel) {
+ highestLevel = currentLevel + 1;
+ storage.highestLevel = highestLevel;
+ }
+ // Show level complete popup after a short delay
+ LK.setTimeout(function () {
+ var popup = new LevelCompletePopup(currentLevel, moveCount);
+ popup.x = 2048 / 2;
+ popup.y = 2732 / 2;
+ game.addChild(popup);
+ }, 800);
+ };
+ this.startNextLevel = function () {
+ currentLevel++;
+ if (currentLevel > 10) {
+ // Player completed all levels
+ LK.showYouWin();
+ return;
+ }
+ storage.currentLevel = currentLevel;
+ this.init(currentLevel);
+ };
+};
+// Initialize game
+tileGame = new TileGame();
+tileGame.init(currentLevel);
+// Play background music
+LK.playMusic('bgmusic');
+// Main game loop
+game.update = function () {
+ // Game logic that needs to run every frame would go here
+};
+// Handle game-wide touch events
+game.down = function (x, y, obj) {
+ // Any game-wide touch handling logic would go here
+};
+game.move = function (x, y, obj) {
+ // Any game-wide move handling logic would go here
+};
+game.up = function (x, y, obj) {
+ // Any game-wide touch release handling logic would go here
+};
\ No newline at end of file