User prompt
Go optimum for game
User prompt
Add levels if player beat first level target must be rise by 600 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
You must fix the bugs
User prompt
Crystal must be slideable ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Crystal Crush Blast
Initial prompt
Create a candy crush game with powerfull add ons
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Crystal = Container.expand(function (crystalType) { var self = Container.call(this); self.crystalType = crystalType; self.gridX = 0; self.gridY = 0; self.isSelected = false; self.isAnimating = false; var assetName = 'crystal_' + crystalType; if (crystalType === 'bomb') assetName = 'bomb_crystal';else if (crystalType === 'lightning') assetName = 'lightning_crystal';else if (crystalType === 'rainbow') assetName = 'rainbow_crystal'; var crystalGraphics = self.attachAsset(assetName, { anchorX: 0.5, anchorY: 0.5 }); self.setSelected = function (selected) { self.isSelected = selected; if (selected) { crystalGraphics.scaleX = 1.2; crystalGraphics.scaleY = 1.2; } else { crystalGraphics.scaleX = 1.0; crystalGraphics.scaleY = 1.0; } }; self.setGridPosition = function (gridX, gridY) { self.gridX = gridX; self.gridY = gridY; self.x = GRID_START_X + gridX * CELL_SIZE + CELL_SIZE / 2; self.y = GRID_START_Y + gridY * CELL_SIZE + CELL_SIZE / 2; }; self.animateToPosition = function (newX, newY, callback) { self.isAnimating = true; tween(self, { x: newX, y: newY }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { self.isAnimating = false; if (callback) callback(); } }); }; self.down = function (x, y, obj) { if (self.isAnimating || gameState !== 'playing') return; handleCrystalClick(self); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x1a1a2e }); /**** * Game Code ****/ var GRID_SIZE = 8; var CELL_SIZE = 240; var GRID_START_X = (2048 - GRID_SIZE * CELL_SIZE) / 2; var GRID_START_Y = (2732 - GRID_SIZE * CELL_SIZE) / 2; var crystalTypes = ['red', 'blue', 'green', 'yellow', 'purple', 'orange']; var grid = []; var selectedCrystal = null; var gameState = 'playing'; var score = 0; var movesLeft = 30; var targetScore = 5000; // UI Elements var scoreText = new Text2('Score: 0', { size: 80, fill: 0xFFFFFF }); scoreText.anchor.set(0, 0); scoreText.x = 50; scoreText.y = 100; game.addChild(scoreText); var movesText = new Text2('Moves: 30', { size: 80, fill: 0xFFFFFF }); movesText.anchor.set(1, 0); movesText.x = 1998; movesText.y = 100; game.addChild(movesText); var targetText = new Text2('Target: 5000', { size: 60, fill: 0xFFFF00 }); targetText.anchor.set(0.5, 0); targetText.x = 1024; targetText.y = 50; game.addChild(targetText); // Initialize grid background function createGridBackground() { for (var x = 0; x < GRID_SIZE; x++) { for (var y = 0; y < GRID_SIZE; y++) { var cell = LK.getAsset('grid_cell', { anchorX: 0.5, anchorY: 0.5 }); cell.x = GRID_START_X + x * CELL_SIZE + CELL_SIZE / 2; cell.y = GRID_START_Y + y * CELL_SIZE + CELL_SIZE / 2; cell.alpha = 0.3; game.addChild(cell); } } } // Initialize game grid function initializeGrid() { grid = []; for (var x = 0; x < GRID_SIZE; x++) { grid[x] = []; for (var y = 0; y < GRID_SIZE; y++) { var crystalType = crystalTypes[Math.floor(Math.random() * crystalTypes.length)]; var crystal = new Crystal(crystalType); crystal.setGridPosition(x, y); grid[x][y] = crystal; game.addChild(crystal); } } // Remove initial matches removeInitialMatches(); } function removeInitialMatches() { var hasMatches = true; while (hasMatches) { hasMatches = false; for (var x = 0; x < GRID_SIZE; x++) { for (var y = 0; y < GRID_SIZE; y++) { if (checkMatchAt(x, y).length >= 3) { hasMatches = true; var newType = crystalTypes[Math.floor(Math.random() * crystalTypes.length)]; grid[x][y].crystalType = newType; } } } } } function handleCrystalClick(crystal) { if (!selectedCrystal) { selectedCrystal = crystal; crystal.setSelected(true); } else if (selectedCrystal === crystal) { selectedCrystal.setSelected(false); selectedCrystal = null; } else { // Check if crystals are adjacent var dx = Math.abs(selectedCrystal.gridX - crystal.gridX); var dy = Math.abs(selectedCrystal.gridY - crystal.gridY); if (dx === 1 && dy === 0 || dx === 0 && dy === 1) { swapCrystals(selectedCrystal, crystal); } selectedCrystal.setSelected(false); selectedCrystal = null; } } function swapCrystals(crystal1, crystal2) { if (movesLeft <= 0) return; var tempType = crystal1.crystalType; crystal1.crystalType = crystal2.crystalType; crystal2.crystalType = tempType; // Check for matches after swap var matches1 = checkMatchAt(crystal1.gridX, crystal1.gridY); var matches2 = checkMatchAt(crystal2.gridX, crystal2.gridY); if (matches1.length >= 3 || matches2.length >= 3) { movesLeft--; updateUI(); processMatches(); LK.getSound('match').play(); } else { // Swap back if no matches crystal1.crystalType = tempType; crystal2.crystalType = crystal2.crystalType; } } function checkMatchAt(x, y) { if (!grid[x] || !grid[x][y]) return []; var crystal = grid[x][y]; var matches = [crystal]; var type = crystal.crystalType; // Check horizontal matches var left = x - 1; while (left >= 0 && grid[left][y] && grid[left][y].crystalType === type) { matches.push(grid[left][y]); left--; } var right = x + 1; while (right < GRID_SIZE && grid[right][y] && grid[right][y].crystalType === type) { matches.push(grid[right][y]); right++; } if (matches.length >= 3) return matches; // Check vertical matches matches = [crystal]; var up = y - 1; while (up >= 0 && grid[x][up] && grid[x][up].crystalType === type) { matches.push(grid[x][up]); up--; } var down = y + 1; while (down < GRID_SIZE && grid[x][down] && grid[x][down].crystalType === type) { matches.push(grid[x][down]); down++; } return matches.length >= 3 ? matches : []; } function processMatches() { var allMatches = []; // Find all matches for (var x = 0; x < GRID_SIZE; x++) { for (var y = 0; y < GRID_SIZE; y++) { var matches = checkMatchAt(x, y); if (matches.length >= 3) { for (var i = 0; i < matches.length; i++) { if (allMatches.indexOf(matches[i]) === -1) { allMatches.push(matches[i]); } } } } } if (allMatches.length > 0) { // Calculate score score += allMatches.length * 100; // Remove matched crystals for (var i = 0; i < allMatches.length; i++) { var crystal = allMatches[i]; game.removeChild(crystal); grid[crystal.gridX][crystal.gridY] = null; } // Drop crystals down dropCrystals(); updateUI(); checkWinCondition(); } } function dropCrystals() { for (var x = 0; x < GRID_SIZE; x++) { var writeIndex = GRID_SIZE - 1; // Move existing crystals down for (var y = GRID_SIZE - 1; y >= 0; y--) { if (grid[x][y] !== null) { if (y !== writeIndex) { grid[x][writeIndex] = grid[x][y]; grid[x][y] = null; grid[x][writeIndex].gridY = writeIndex; grid[x][writeIndex].setGridPosition(x, writeIndex); } writeIndex--; } } // Fill empty spaces with new crystals for (var emptyY = writeIndex; emptyY >= 0; emptyY--) { var crystalType = crystalTypes[Math.floor(Math.random() * crystalTypes.length)]; var newCrystal = new Crystal(crystalType); newCrystal.setGridPosition(x, emptyY); grid[x][emptyY] = newCrystal; game.addChild(newCrystal); } } // Check for new matches after dropping LK.setTimeout(function () { processMatches(); }, 400); } function updateUI() { scoreText.setText('Score: ' + score); movesText.setText('Moves: ' + movesLeft); } function checkWinCondition() { if (score >= targetScore) { gameState = 'won'; LK.showYouWin(); } else if (movesLeft <= 0) { gameState = 'lost'; LK.showGameOver(); } } // Initialize game createGridBackground(); initializeGrid(); updateUI(); game.update = function () { // Game loop - matches are processed through event system };
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,297 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+
+/****
+* Classes
+****/
+var Crystal = Container.expand(function (crystalType) {
+ var self = Container.call(this);
+ self.crystalType = crystalType;
+ self.gridX = 0;
+ self.gridY = 0;
+ self.isSelected = false;
+ self.isAnimating = false;
+ var assetName = 'crystal_' + crystalType;
+ if (crystalType === 'bomb') assetName = 'bomb_crystal';else if (crystalType === 'lightning') assetName = 'lightning_crystal';else if (crystalType === 'rainbow') assetName = 'rainbow_crystal';
+ var crystalGraphics = self.attachAsset(assetName, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.setSelected = function (selected) {
+ self.isSelected = selected;
+ if (selected) {
+ crystalGraphics.scaleX = 1.2;
+ crystalGraphics.scaleY = 1.2;
+ } else {
+ crystalGraphics.scaleX = 1.0;
+ crystalGraphics.scaleY = 1.0;
+ }
+ };
+ self.setGridPosition = function (gridX, gridY) {
+ self.gridX = gridX;
+ self.gridY = gridY;
+ self.x = GRID_START_X + gridX * CELL_SIZE + CELL_SIZE / 2;
+ self.y = GRID_START_Y + gridY * CELL_SIZE + CELL_SIZE / 2;
+ };
+ self.animateToPosition = function (newX, newY, callback) {
+ self.isAnimating = true;
+ tween(self, {
+ x: newX,
+ y: newY
+ }, {
+ duration: 300,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ self.isAnimating = false;
+ if (callback) callback();
+ }
+ });
+ };
+ self.down = function (x, y, obj) {
+ if (self.isAnimating || gameState !== 'playing') return;
+ handleCrystalClick(self);
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x1a1a2e
+});
+
+/****
+* Game Code
+****/
+var GRID_SIZE = 8;
+var CELL_SIZE = 240;
+var GRID_START_X = (2048 - GRID_SIZE * CELL_SIZE) / 2;
+var GRID_START_Y = (2732 - GRID_SIZE * CELL_SIZE) / 2;
+var crystalTypes = ['red', 'blue', 'green', 'yellow', 'purple', 'orange'];
+var grid = [];
+var selectedCrystal = null;
+var gameState = 'playing';
+var score = 0;
+var movesLeft = 30;
+var targetScore = 5000;
+// UI Elements
+var scoreText = new Text2('Score: 0', {
+ size: 80,
+ fill: 0xFFFFFF
+});
+scoreText.anchor.set(0, 0);
+scoreText.x = 50;
+scoreText.y = 100;
+game.addChild(scoreText);
+var movesText = new Text2('Moves: 30', {
+ size: 80,
+ fill: 0xFFFFFF
+});
+movesText.anchor.set(1, 0);
+movesText.x = 1998;
+movesText.y = 100;
+game.addChild(movesText);
+var targetText = new Text2('Target: 5000', {
+ size: 60,
+ fill: 0xFFFF00
+});
+targetText.anchor.set(0.5, 0);
+targetText.x = 1024;
+targetText.y = 50;
+game.addChild(targetText);
+// Initialize grid background
+function createGridBackground() {
+ for (var x = 0; x < GRID_SIZE; x++) {
+ for (var y = 0; y < GRID_SIZE; y++) {
+ var cell = LK.getAsset('grid_cell', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ cell.x = GRID_START_X + x * CELL_SIZE + CELL_SIZE / 2;
+ cell.y = GRID_START_Y + y * CELL_SIZE + CELL_SIZE / 2;
+ cell.alpha = 0.3;
+ game.addChild(cell);
+ }
+ }
+}
+// Initialize game grid
+function initializeGrid() {
+ grid = [];
+ for (var x = 0; x < GRID_SIZE; x++) {
+ grid[x] = [];
+ for (var y = 0; y < GRID_SIZE; y++) {
+ var crystalType = crystalTypes[Math.floor(Math.random() * crystalTypes.length)];
+ var crystal = new Crystal(crystalType);
+ crystal.setGridPosition(x, y);
+ grid[x][y] = crystal;
+ game.addChild(crystal);
+ }
+ }
+ // Remove initial matches
+ removeInitialMatches();
+}
+function removeInitialMatches() {
+ var hasMatches = true;
+ while (hasMatches) {
+ hasMatches = false;
+ for (var x = 0; x < GRID_SIZE; x++) {
+ for (var y = 0; y < GRID_SIZE; y++) {
+ if (checkMatchAt(x, y).length >= 3) {
+ hasMatches = true;
+ var newType = crystalTypes[Math.floor(Math.random() * crystalTypes.length)];
+ grid[x][y].crystalType = newType;
+ }
+ }
+ }
+ }
+}
+function handleCrystalClick(crystal) {
+ if (!selectedCrystal) {
+ selectedCrystal = crystal;
+ crystal.setSelected(true);
+ } else if (selectedCrystal === crystal) {
+ selectedCrystal.setSelected(false);
+ selectedCrystal = null;
+ } else {
+ // Check if crystals are adjacent
+ var dx = Math.abs(selectedCrystal.gridX - crystal.gridX);
+ var dy = Math.abs(selectedCrystal.gridY - crystal.gridY);
+ if (dx === 1 && dy === 0 || dx === 0 && dy === 1) {
+ swapCrystals(selectedCrystal, crystal);
+ }
+ selectedCrystal.setSelected(false);
+ selectedCrystal = null;
+ }
+}
+function swapCrystals(crystal1, crystal2) {
+ if (movesLeft <= 0) return;
+ var tempType = crystal1.crystalType;
+ crystal1.crystalType = crystal2.crystalType;
+ crystal2.crystalType = tempType;
+ // Check for matches after swap
+ var matches1 = checkMatchAt(crystal1.gridX, crystal1.gridY);
+ var matches2 = checkMatchAt(crystal2.gridX, crystal2.gridY);
+ if (matches1.length >= 3 || matches2.length >= 3) {
+ movesLeft--;
+ updateUI();
+ processMatches();
+ LK.getSound('match').play();
+ } else {
+ // Swap back if no matches
+ crystal1.crystalType = tempType;
+ crystal2.crystalType = crystal2.crystalType;
+ }
+}
+function checkMatchAt(x, y) {
+ if (!grid[x] || !grid[x][y]) return [];
+ var crystal = grid[x][y];
+ var matches = [crystal];
+ var type = crystal.crystalType;
+ // Check horizontal matches
+ var left = x - 1;
+ while (left >= 0 && grid[left][y] && grid[left][y].crystalType === type) {
+ matches.push(grid[left][y]);
+ left--;
+ }
+ var right = x + 1;
+ while (right < GRID_SIZE && grid[right][y] && grid[right][y].crystalType === type) {
+ matches.push(grid[right][y]);
+ right++;
+ }
+ if (matches.length >= 3) return matches;
+ // Check vertical matches
+ matches = [crystal];
+ var up = y - 1;
+ while (up >= 0 && grid[x][up] && grid[x][up].crystalType === type) {
+ matches.push(grid[x][up]);
+ up--;
+ }
+ var down = y + 1;
+ while (down < GRID_SIZE && grid[x][down] && grid[x][down].crystalType === type) {
+ matches.push(grid[x][down]);
+ down++;
+ }
+ return matches.length >= 3 ? matches : [];
+}
+function processMatches() {
+ var allMatches = [];
+ // Find all matches
+ for (var x = 0; x < GRID_SIZE; x++) {
+ for (var y = 0; y < GRID_SIZE; y++) {
+ var matches = checkMatchAt(x, y);
+ if (matches.length >= 3) {
+ for (var i = 0; i < matches.length; i++) {
+ if (allMatches.indexOf(matches[i]) === -1) {
+ allMatches.push(matches[i]);
+ }
+ }
+ }
+ }
+ }
+ if (allMatches.length > 0) {
+ // Calculate score
+ score += allMatches.length * 100;
+ // Remove matched crystals
+ for (var i = 0; i < allMatches.length; i++) {
+ var crystal = allMatches[i];
+ game.removeChild(crystal);
+ grid[crystal.gridX][crystal.gridY] = null;
+ }
+ // Drop crystals down
+ dropCrystals();
+ updateUI();
+ checkWinCondition();
+ }
+}
+function dropCrystals() {
+ for (var x = 0; x < GRID_SIZE; x++) {
+ var writeIndex = GRID_SIZE - 1;
+ // Move existing crystals down
+ for (var y = GRID_SIZE - 1; y >= 0; y--) {
+ if (grid[x][y] !== null) {
+ if (y !== writeIndex) {
+ grid[x][writeIndex] = grid[x][y];
+ grid[x][y] = null;
+ grid[x][writeIndex].gridY = writeIndex;
+ grid[x][writeIndex].setGridPosition(x, writeIndex);
+ }
+ writeIndex--;
+ }
+ }
+ // Fill empty spaces with new crystals
+ for (var emptyY = writeIndex; emptyY >= 0; emptyY--) {
+ var crystalType = crystalTypes[Math.floor(Math.random() * crystalTypes.length)];
+ var newCrystal = new Crystal(crystalType);
+ newCrystal.setGridPosition(x, emptyY);
+ grid[x][emptyY] = newCrystal;
+ game.addChild(newCrystal);
+ }
+ }
+ // Check for new matches after dropping
+ LK.setTimeout(function () {
+ processMatches();
+ }, 400);
+}
+function updateUI() {
+ scoreText.setText('Score: ' + score);
+ movesText.setText('Moves: ' + movesLeft);
+}
+function checkWinCondition() {
+ if (score >= targetScore) {
+ gameState = 'won';
+ LK.showYouWin();
+ } else if (movesLeft <= 0) {
+ gameState = 'lost';
+ LK.showGameOver();
+ }
+}
+// Initialize game
+createGridBackground();
+initializeGrid();
+updateUI();
+game.update = function () {
+ // Game loop - matches are processed through event system
+};
\ No newline at end of file