/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Candy class: represents a single candy on the board var Candy = Container.expand(function () { var self = Container.call(this); // Properties self.type = 0; // 0-5 for normal candies, 6+ for special self.row = 0; self.col = 0; self.selected = false; self.special = null; // null, 'row', 'col', 'bomb' // Attach asset var candyColors = [0xff4d4d, // Red 0x4db8ff, // Blue 0xffe14d, // Yellow 0x7cff4d, // Green 0xff4df7, // Pink 0xff914d // Orange ]; // For special candies, use a white border function getCandyAsset(type, special) { var color = candyColors[type % candyColors.length]; var asset = LK.getAsset('candy_' + type, { width: candySize, height: candySize, color: color, shape: 'ellipse', anchorX: 0.5, anchorY: 0.5 }); if (special) { // Add a border by overlaying a slightly larger ellipse var border = LK.getAsset('candy_border', { width: candySize + 16, height: candySize + 16, color: 0xffffff, shape: 'ellipse', anchorX: 0.5, anchorY: 0.5 }); var group = new Container(); group.addChild(border); group.addChild(asset); return group; } return asset; } self.setType = function (type, special) { self.type = type; self.special = special || null; // Remove old graphics while (self.children.length) self.removeChild(self.children[0]); var asset = getCandyAsset(type, special); self.addChild(asset); }; // Highlight for selection self.setSelected = function (selected) { self.selected = selected; if (self.children.length) { if (selected) { tween(self, { scaleX: 1.2, scaleY: 1.2 }, { duration: 120, easing: tween.easeOut }); } else { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 120, easing: tween.easeOut }); } } }; // Animate removal self.animateRemove = function (_onFinish) { tween(self, { scaleX: 0, scaleY: 0, alpha: 0 }, { duration: 180, easing: tween.easeIn, onFinish: function onFinish() { if (_onFinish) _onFinish(); } }); }; // Animate drop self.animateDrop = function (targetY, onFinish) { tween(self, { y: targetY }, { duration: 180, easing: tween.bounceOut, onFinish: onFinish }); }; // Animate spawn self.animateSpawn = function () { self.scaleX = self.scaleY = 0; tween(self, { scaleX: 1, scaleY: 1 }, { duration: 180, easing: tween.easeOut }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222244 }); /**** * Game Code ****/ // Board settings var boardRows = 9; var boardCols = 7; var candyTypes = 6; var candySize = 180; var boardOffsetX = Math.floor((2048 - boardCols * candySize) / 2); var boardOffsetY = 320; var moveLimit = 25; var targetScore = 3000; // Game state var board = []; var candies = []; var selectedCandy = null; var swapping = false; var animating = false; var movesLeft = moveLimit; var score = 0; // UI var scoreTxt = new Text2('Score: 0', { size: 90, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var movesTxt = new Text2('Moves: ' + movesLeft, { size: 70, fill: "#fff" }); movesTxt.anchor.set(0.5, 0); LK.gui.top.addChild(movesTxt); movesTxt.y = 110; // Helper: get board position from x/y function getBoardPos(x, y) { var col = Math.floor((x - boardOffsetX) / candySize); var row = Math.floor((y - boardOffsetY) / candySize); if (col < 0 || col >= boardCols || row < 0 || row >= boardRows) return null; return { row: row, col: col }; } // Helper: get candy at row,col function getCandy(row, col) { if (row < 0 || row >= boardRows || col < 0 || col >= boardCols) return null; return board[row][col]; } // Helper: swap candies in board and update their row/col function swapCandies(c1, c2) { var r1 = c1.row, c1c = c1.col, r2 = c2.row, c2c = c2.col; board[r1][c1c] = c2; board[r2][c2c] = c1; c1.row = r2; c1.col = c2c; c2.row = r1; c2.col = c1c; } // Helper: check if two candies are adjacent function areAdjacent(c1, c2) { return Math.abs(c1.row - c2.row) + Math.abs(c1.col - c2.col) === 1; } // Helper: find all matches on the board function findMatches() { var matches = []; // Horizontal for (var r = 0; r < boardRows; r++) { var streak = 1; for (var c = 1; c < boardCols; c++) { if (board[r][c].type === board[r][c - 1].type) { streak++; } else { if (streak >= 3) { matches.push({ row: r, col: c - 1, len: streak, dir: 'h' }); } streak = 1; } } if (streak >= 3) { matches.push({ row: r, col: boardCols - 1, len: streak, dir: 'h' }); } } // Vertical for (var c = 0; c < boardCols; c++) { var streak = 1; for (var r = 1; r < boardRows; r++) { if (board[r][c].type === board[r - 1][c].type) { streak++; } else { if (streak >= 3) { matches.push({ row: r - 1, col: c, len: streak, dir: 'v' }); } streak = 1; } } if (streak >= 3) { matches.push({ row: boardRows - 1, col: c, len: streak, dir: 'v' }); } } return matches; } // Helper: mark candies to be removed, and create special candies if needed function markMatches(matches) { var removeMap = []; for (var r = 0; r < boardRows; r++) { removeMap[r] = []; for (var c = 0; c < boardCols; c++) { removeMap[r][c] = false; } } // For special candy creation var specials = []; for (var i = 0; i < matches.length; i++) { var m = matches[i]; if (m.dir === 'h') { for (var k = 0; k < m.len; k++) { removeMap[m.row][m.col - k] = true; } // Create special for 4/5 if (m.len === 4) { specials.push({ row: m.row, col: m.col - 1, special: 'row' }); } else if (m.len >= 5) { specials.push({ row: m.row, col: m.col - 2, special: 'bomb' }); } } else if (m.dir === 'v') { for (var k = 0; k < m.len; k++) { removeMap[m.row - k][m.col] = true; } if (m.len === 4) { specials.push({ row: m.row - 1, col: m.col, special: 'col' }); } else if (m.len >= 5) { specials.push({ row: m.row - 2, col: m.col, special: 'bomb' }); } } } return { removeMap: removeMap, specials: specials }; } // Helper: remove candies, animate, and return positions to refill function removeAndScore(removeMap, specials) { var toRemove = []; for (var r = 0; r < boardRows; r++) { for (var c = 0; c < boardCols; c++) { if (removeMap[r][c]) { toRemove.push(board[r][c]); } } } // Score: 60 per candy, + bonus for special var gained = toRemove.length * 60; score += gained; LK.setScore(score); scoreTxt.setText('Score: ' + score); // Place specials for (var i = 0; i < specials.length; i++) { var s = specials[i]; var candy = board[s.row][s.col]; if (candy) { candy.setType(candy.type, s.special); } } // Animate and remove var removed = 0; for (var i = 0; i < toRemove.length; i++) { var c = toRemove[i]; c.animateRemove(function () { removed++; if (removed === toRemove.length) { refillBoard(); } }); // Remove from board after animation board[c.row][c.col] = null; } // If nothing to remove, refill immediately if (toRemove.length === 0) { refillBoard(); } } // Helper: refill board after removals function refillBoard() { // Drop candies down for (var c = 0; c < boardCols; c++) { var empty = 0; for (var r = boardRows - 1; r >= 0; r--) { if (!board[r][c]) { empty++; } else if (empty > 0) { var candy = board[r][c]; board[r + empty][c] = candy; candy.row = r + empty; candy.col = c; board[r][c] = null; var targetY = boardOffsetY + (r + empty) * candySize + candySize / 2; candy.animateDrop(targetY); } } // Add new candies at top for (var e = 0; e < empty; e++) { var type = Math.floor(Math.random() * candyTypes); var newCandy = new Candy(); newCandy.setType(type); newCandy.row = e; newCandy.col = c; var x = boardOffsetX + c * candySize + candySize / 2; var y = boardOffsetY + e * candySize + candySize / 2 - empty * candySize; newCandy.x = x; newCandy.y = y; newCandy.scaleX = newCandy.scaleY = 1; newCandy.alpha = 1; game.addChild(newCandy); candies.push(newCandy); board[e][c] = newCandy; // Animate drop to correct position var targetY = boardOffsetY + e * candySize + candySize / 2; newCandy.animateDrop(targetY, function () {}); newCandy.animateSpawn(); } } // After all drops, check for new matches LK.setTimeout(function () { resolveBoard(); }, 220); } // Helper: resolve board (find matches, remove, refill) function resolveBoard() { var matches = findMatches(); if (matches.length > 0) { var _markMatches = markMatches(matches), removeMap = _markMatches.removeMap, specials = _markMatches.specials; removeAndScore(removeMap, specials); } else { animating = false; // Check for win/lose if (score >= targetScore) { LK.showYouWin(); } else if (movesLeft <= 0) { LK.showGameOver(); } } } // Helper: deselect all candies function deselectAll() { for (var i = 0; i < candies.length; i++) { candies[i].setSelected(false); } selectedCandy = null; } // Helper: get candy at x,y function getCandyAt(x, y) { var pos = getBoardPos(x, y); if (!pos) return null; return board[pos.row][pos.col]; } // Initialize board function initBoard() { // Clear old for (var i = 0; i < candies.length; i++) { candies[i].destroy(); } candies = []; board = []; for (var r = 0; r < boardRows; r++) { board[r] = []; for (var c = 0; c < boardCols; c++) { var type = Math.floor(Math.random() * candyTypes); var candy = new Candy(); candy.setType(type); candy.row = r; candy.col = c; var x = boardOffsetX + c * candySize + candySize / 2; var y = boardOffsetY + r * candySize + candySize / 2; candy.x = x; candy.y = y; candy.scaleX = candy.scaleY = 1; candy.alpha = 1; game.addChild(candy); candies.push(candy); board[r][c] = candy; } } // Remove any initial matches LK.setTimeout(function () { resolveBoard(); }, 100); } // Handle touch/mouse down game.down = function (x, y, obj) { if (animating) return; var candy = getCandyAt(x, y); if (!candy) { deselectAll(); return; } if (!selectedCandy) { selectedCandy = candy; candy.setSelected(true); } else if (selectedCandy === candy) { deselectAll(); } else if (areAdjacent(selectedCandy, candy)) { swapping = true; animating = true; // Swap visually var c1 = selectedCandy, c2 = candy; var c1x = c1.x, c1y = c1.y, c2x = c2.x, c2y = c2.y; tween(c1, { x: c2x, y: c2y }, { duration: 180, easing: tween.easeInOut }); tween(c2, { x: c1x, y: c1y }, { duration: 180, easing: tween.easeInOut, onFinish: function onFinish() { // Swap in board swapCandies(c1, c2); // Check for matches var matches = findMatches(); if (matches.length > 0) { movesLeft--; movesTxt.setText('Moves: ' + movesLeft); deselectAll(); var _markMatches2 = markMatches(matches), removeMap = _markMatches2.removeMap, specials = _markMatches2.specials; removeAndScore(removeMap, specials); } else { // No match, swap back tween(c1, { x: c1x, y: c1y }, { duration: 180, easing: tween.easeInOut }); tween(c2, { x: c2x, y: c2y }, { duration: 180, easing: tween.easeInOut, onFinish: function onFinish() { swapCandies(c1, c2); deselectAll(); animating = false; } }); } swapping = false; } }); } else { deselectAll(); selectedCandy = candy; candy.setSelected(true); } }; // Prevent drag game.move = function (x, y, obj) { // No drag for match-3 }; // Prevent up game.up = function (x, y, obj) {}; // Game update game.update = function () { // No per-frame logic needed }; // Start game function startGame() { score = 0; movesLeft = moveLimit; LK.setScore(score); scoreTxt.setText('Score: ' + score); movesTxt.setText('Moves: ' + movesLeft); animating = false; swapping = false; selectedCandy = null; initBoard(); } startGame();
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,566 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+// Candy class: represents a single candy on the board
+var Candy = Container.expand(function () {
+ var self = Container.call(this);
+ // Properties
+ self.type = 0; // 0-5 for normal candies, 6+ for special
+ self.row = 0;
+ self.col = 0;
+ self.selected = false;
+ self.special = null; // null, 'row', 'col', 'bomb'
+ // Attach asset
+ var candyColors = [0xff4d4d,
+ // Red
+ 0x4db8ff,
+ // Blue
+ 0xffe14d,
+ // Yellow
+ 0x7cff4d,
+ // Green
+ 0xff4df7,
+ // Pink
+ 0xff914d // Orange
+ ];
+ // For special candies, use a white border
+ function getCandyAsset(type, special) {
+ var color = candyColors[type % candyColors.length];
+ var asset = LK.getAsset('candy_' + type, {
+ width: candySize,
+ height: candySize,
+ color: color,
+ shape: 'ellipse',
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ if (special) {
+ // Add a border by overlaying a slightly larger ellipse
+ var border = LK.getAsset('candy_border', {
+ width: candySize + 16,
+ height: candySize + 16,
+ color: 0xffffff,
+ shape: 'ellipse',
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ var group = new Container();
+ group.addChild(border);
+ group.addChild(asset);
+ return group;
+ }
+ return asset;
+ }
+ self.setType = function (type, special) {
+ self.type = type;
+ self.special = special || null;
+ // Remove old graphics
+ while (self.children.length) self.removeChild(self.children[0]);
+ var asset = getCandyAsset(type, special);
+ self.addChild(asset);
+ };
+ // Highlight for selection
+ self.setSelected = function (selected) {
+ self.selected = selected;
+ if (self.children.length) {
+ if (selected) {
+ tween(self, {
+ scaleX: 1.2,
+ scaleY: 1.2
+ }, {
+ duration: 120,
+ easing: tween.easeOut
+ });
+ } else {
+ tween(self, {
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 120,
+ easing: tween.easeOut
+ });
+ }
+ }
+ };
+ // Animate removal
+ self.animateRemove = function (_onFinish) {
+ tween(self, {
+ scaleX: 0,
+ scaleY: 0,
+ alpha: 0
+ }, {
+ duration: 180,
+ easing: tween.easeIn,
+ onFinish: function onFinish() {
+ if (_onFinish) _onFinish();
+ }
+ });
+ };
+ // Animate drop
+ self.animateDrop = function (targetY, onFinish) {
+ tween(self, {
+ y: targetY
+ }, {
+ duration: 180,
+ easing: tween.bounceOut,
+ onFinish: onFinish
+ });
+ };
+ // Animate spawn
+ self.animateSpawn = function () {
+ self.scaleX = self.scaleY = 0;
+ tween(self, {
+ scaleX: 1,
+ scaleY: 1
+ }, {
+ duration: 180,
+ easing: tween.easeOut
+ });
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x222244
+});
+
+/****
+* Game Code
+****/
+// Board settings
+var boardRows = 9;
+var boardCols = 7;
+var candyTypes = 6;
+var candySize = 180;
+var boardOffsetX = Math.floor((2048 - boardCols * candySize) / 2);
+var boardOffsetY = 320;
+var moveLimit = 25;
+var targetScore = 3000;
+// Game state
+var board = [];
+var candies = [];
+var selectedCandy = null;
+var swapping = false;
+var animating = false;
+var movesLeft = moveLimit;
+var score = 0;
+// UI
+var scoreTxt = new Text2('Score: 0', {
+ size: 90,
+ fill: "#fff"
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+var movesTxt = new Text2('Moves: ' + movesLeft, {
+ size: 70,
+ fill: "#fff"
+});
+movesTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(movesTxt);
+movesTxt.y = 110;
+// Helper: get board position from x/y
+function getBoardPos(x, y) {
+ var col = Math.floor((x - boardOffsetX) / candySize);
+ var row = Math.floor((y - boardOffsetY) / candySize);
+ if (col < 0 || col >= boardCols || row < 0 || row >= boardRows) return null;
+ return {
+ row: row,
+ col: col
+ };
+}
+// Helper: get candy at row,col
+function getCandy(row, col) {
+ if (row < 0 || row >= boardRows || col < 0 || col >= boardCols) return null;
+ return board[row][col];
+}
+// Helper: swap candies in board and update their row/col
+function swapCandies(c1, c2) {
+ var r1 = c1.row,
+ c1c = c1.col,
+ r2 = c2.row,
+ c2c = c2.col;
+ board[r1][c1c] = c2;
+ board[r2][c2c] = c1;
+ c1.row = r2;
+ c1.col = c2c;
+ c2.row = r1;
+ c2.col = c1c;
+}
+// Helper: check if two candies are adjacent
+function areAdjacent(c1, c2) {
+ return Math.abs(c1.row - c2.row) + Math.abs(c1.col - c2.col) === 1;
+}
+// Helper: find all matches on the board
+function findMatches() {
+ var matches = [];
+ // Horizontal
+ for (var r = 0; r < boardRows; r++) {
+ var streak = 1;
+ for (var c = 1; c < boardCols; c++) {
+ if (board[r][c].type === board[r][c - 1].type) {
+ streak++;
+ } else {
+ if (streak >= 3) {
+ matches.push({
+ row: r,
+ col: c - 1,
+ len: streak,
+ dir: 'h'
+ });
+ }
+ streak = 1;
+ }
+ }
+ if (streak >= 3) {
+ matches.push({
+ row: r,
+ col: boardCols - 1,
+ len: streak,
+ dir: 'h'
+ });
+ }
+ }
+ // Vertical
+ for (var c = 0; c < boardCols; c++) {
+ var streak = 1;
+ for (var r = 1; r < boardRows; r++) {
+ if (board[r][c].type === board[r - 1][c].type) {
+ streak++;
+ } else {
+ if (streak >= 3) {
+ matches.push({
+ row: r - 1,
+ col: c,
+ len: streak,
+ dir: 'v'
+ });
+ }
+ streak = 1;
+ }
+ }
+ if (streak >= 3) {
+ matches.push({
+ row: boardRows - 1,
+ col: c,
+ len: streak,
+ dir: 'v'
+ });
+ }
+ }
+ return matches;
+}
+// Helper: mark candies to be removed, and create special candies if needed
+function markMatches(matches) {
+ var removeMap = [];
+ for (var r = 0; r < boardRows; r++) {
+ removeMap[r] = [];
+ for (var c = 0; c < boardCols; c++) {
+ removeMap[r][c] = false;
+ }
+ }
+ // For special candy creation
+ var specials = [];
+ for (var i = 0; i < matches.length; i++) {
+ var m = matches[i];
+ if (m.dir === 'h') {
+ for (var k = 0; k < m.len; k++) {
+ removeMap[m.row][m.col - k] = true;
+ }
+ // Create special for 4/5
+ if (m.len === 4) {
+ specials.push({
+ row: m.row,
+ col: m.col - 1,
+ special: 'row'
+ });
+ } else if (m.len >= 5) {
+ specials.push({
+ row: m.row,
+ col: m.col - 2,
+ special: 'bomb'
+ });
+ }
+ } else if (m.dir === 'v') {
+ for (var k = 0; k < m.len; k++) {
+ removeMap[m.row - k][m.col] = true;
+ }
+ if (m.len === 4) {
+ specials.push({
+ row: m.row - 1,
+ col: m.col,
+ special: 'col'
+ });
+ } else if (m.len >= 5) {
+ specials.push({
+ row: m.row - 2,
+ col: m.col,
+ special: 'bomb'
+ });
+ }
+ }
+ }
+ return {
+ removeMap: removeMap,
+ specials: specials
+ };
+}
+// Helper: remove candies, animate, and return positions to refill
+function removeAndScore(removeMap, specials) {
+ var toRemove = [];
+ for (var r = 0; r < boardRows; r++) {
+ for (var c = 0; c < boardCols; c++) {
+ if (removeMap[r][c]) {
+ toRemove.push(board[r][c]);
+ }
+ }
+ }
+ // Score: 60 per candy, + bonus for special
+ var gained = toRemove.length * 60;
+ score += gained;
+ LK.setScore(score);
+ scoreTxt.setText('Score: ' + score);
+ // Place specials
+ for (var i = 0; i < specials.length; i++) {
+ var s = specials[i];
+ var candy = board[s.row][s.col];
+ if (candy) {
+ candy.setType(candy.type, s.special);
+ }
+ }
+ // Animate and remove
+ var removed = 0;
+ for (var i = 0; i < toRemove.length; i++) {
+ var c = toRemove[i];
+ c.animateRemove(function () {
+ removed++;
+ if (removed === toRemove.length) {
+ refillBoard();
+ }
+ });
+ // Remove from board after animation
+ board[c.row][c.col] = null;
+ }
+ // If nothing to remove, refill immediately
+ if (toRemove.length === 0) {
+ refillBoard();
+ }
+}
+// Helper: refill board after removals
+function refillBoard() {
+ // Drop candies down
+ for (var c = 0; c < boardCols; c++) {
+ var empty = 0;
+ for (var r = boardRows - 1; r >= 0; r--) {
+ if (!board[r][c]) {
+ empty++;
+ } else if (empty > 0) {
+ var candy = board[r][c];
+ board[r + empty][c] = candy;
+ candy.row = r + empty;
+ candy.col = c;
+ board[r][c] = null;
+ var targetY = boardOffsetY + (r + empty) * candySize + candySize / 2;
+ candy.animateDrop(targetY);
+ }
+ }
+ // Add new candies at top
+ for (var e = 0; e < empty; e++) {
+ var type = Math.floor(Math.random() * candyTypes);
+ var newCandy = new Candy();
+ newCandy.setType(type);
+ newCandy.row = e;
+ newCandy.col = c;
+ var x = boardOffsetX + c * candySize + candySize / 2;
+ var y = boardOffsetY + e * candySize + candySize / 2 - empty * candySize;
+ newCandy.x = x;
+ newCandy.y = y;
+ newCandy.scaleX = newCandy.scaleY = 1;
+ newCandy.alpha = 1;
+ game.addChild(newCandy);
+ candies.push(newCandy);
+ board[e][c] = newCandy;
+ // Animate drop to correct position
+ var targetY = boardOffsetY + e * candySize + candySize / 2;
+ newCandy.animateDrop(targetY, function () {});
+ newCandy.animateSpawn();
+ }
+ }
+ // After all drops, check for new matches
+ LK.setTimeout(function () {
+ resolveBoard();
+ }, 220);
+}
+// Helper: resolve board (find matches, remove, refill)
+function resolveBoard() {
+ var matches = findMatches();
+ if (matches.length > 0) {
+ var _markMatches = markMatches(matches),
+ removeMap = _markMatches.removeMap,
+ specials = _markMatches.specials;
+ removeAndScore(removeMap, specials);
+ } else {
+ animating = false;
+ // Check for win/lose
+ if (score >= targetScore) {
+ LK.showYouWin();
+ } else if (movesLeft <= 0) {
+ LK.showGameOver();
+ }
+ }
+}
+// Helper: deselect all candies
+function deselectAll() {
+ for (var i = 0; i < candies.length; i++) {
+ candies[i].setSelected(false);
+ }
+ selectedCandy = null;
+}
+// Helper: get candy at x,y
+function getCandyAt(x, y) {
+ var pos = getBoardPos(x, y);
+ if (!pos) return null;
+ return board[pos.row][pos.col];
+}
+// Initialize board
+function initBoard() {
+ // Clear old
+ for (var i = 0; i < candies.length; i++) {
+ candies[i].destroy();
+ }
+ candies = [];
+ board = [];
+ for (var r = 0; r < boardRows; r++) {
+ board[r] = [];
+ for (var c = 0; c < boardCols; c++) {
+ var type = Math.floor(Math.random() * candyTypes);
+ var candy = new Candy();
+ candy.setType(type);
+ candy.row = r;
+ candy.col = c;
+ var x = boardOffsetX + c * candySize + candySize / 2;
+ var y = boardOffsetY + r * candySize + candySize / 2;
+ candy.x = x;
+ candy.y = y;
+ candy.scaleX = candy.scaleY = 1;
+ candy.alpha = 1;
+ game.addChild(candy);
+ candies.push(candy);
+ board[r][c] = candy;
+ }
+ }
+ // Remove any initial matches
+ LK.setTimeout(function () {
+ resolveBoard();
+ }, 100);
+}
+// Handle touch/mouse down
+game.down = function (x, y, obj) {
+ if (animating) return;
+ var candy = getCandyAt(x, y);
+ if (!candy) {
+ deselectAll();
+ return;
+ }
+ if (!selectedCandy) {
+ selectedCandy = candy;
+ candy.setSelected(true);
+ } else if (selectedCandy === candy) {
+ deselectAll();
+ } else if (areAdjacent(selectedCandy, candy)) {
+ swapping = true;
+ animating = true;
+ // Swap visually
+ var c1 = selectedCandy,
+ c2 = candy;
+ var c1x = c1.x,
+ c1y = c1.y,
+ c2x = c2.x,
+ c2y = c2.y;
+ tween(c1, {
+ x: c2x,
+ y: c2y
+ }, {
+ duration: 180,
+ easing: tween.easeInOut
+ });
+ tween(c2, {
+ x: c1x,
+ y: c1y
+ }, {
+ duration: 180,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ // Swap in board
+ swapCandies(c1, c2);
+ // Check for matches
+ var matches = findMatches();
+ if (matches.length > 0) {
+ movesLeft--;
+ movesTxt.setText('Moves: ' + movesLeft);
+ deselectAll();
+ var _markMatches2 = markMatches(matches),
+ removeMap = _markMatches2.removeMap,
+ specials = _markMatches2.specials;
+ removeAndScore(removeMap, specials);
+ } else {
+ // No match, swap back
+ tween(c1, {
+ x: c1x,
+ y: c1y
+ }, {
+ duration: 180,
+ easing: tween.easeInOut
+ });
+ tween(c2, {
+ x: c2x,
+ y: c2y
+ }, {
+ duration: 180,
+ easing: tween.easeInOut,
+ onFinish: function onFinish() {
+ swapCandies(c1, c2);
+ deselectAll();
+ animating = false;
+ }
+ });
+ }
+ swapping = false;
+ }
+ });
+ } else {
+ deselectAll();
+ selectedCandy = candy;
+ candy.setSelected(true);
+ }
+};
+// Prevent drag
+game.move = function (x, y, obj) {
+ // No drag for match-3
+};
+// Prevent up
+game.up = function (x, y, obj) {};
+// Game update
+game.update = function () {
+ // No per-frame logic needed
+};
+// Start game
+function startGame() {
+ score = 0;
+ movesLeft = moveLimit;
+ LK.setScore(score);
+ scoreTxt.setText('Score: ' + score);
+ movesTxt.setText('Moves: ' + movesLeft);
+ animating = false;
+ swapping = false;
+ selectedCandy = null;
+ initBoard();
+}
+startGame();
\ No newline at end of file
candy . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
candy. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
black bomb candy. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
yellow candy. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
red candy. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat