User prompt
in frist level dont add all the colours and as the level up add one more colour make 7 levels and dont reapeat the colours
User prompt
add 50 levels in it in frist level have 3 clours then add 3 more colours in father level add one more colours as the level is up .inc speed by 4 make road map of level which unlocks when you play previous one and if gamer win the level there is a popup appear then next level start
User prompt
add black blue and purple colours and more colours in anothor levels
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'expand')' in or related to this line: 'var Gem = Container.expand(function (type, speed) {' Line Number: 30
Code edit (1 edits merged)
Please save this source code
User prompt
Gem Sorter: Color Match Mania
User prompt
Please continue polishing my design document.
Initial prompt
Sort different colored gems into the right slots.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0 }); /**** * Classes ****/ var Gem = Container.expand(function (type, speed) { var self = Container.call(this); self.type = type || 'red'; self.speed = speed || 3; self.matched = false; self.isSpecial = false; var assetId = 'gem_' + self.type; var gemGraphics = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { if (!self.matched) { self.y += self.speed; } }; self.down = function (x, y, obj) { // This gem is being dragged if (!self.matched) { currentDraggedGem = self; } }; self.makeSpecial = function () { self.isSpecial = true; tween(gemGraphics, { alpha: 0.5 }, { duration: 500, easing: tween.easeInOut }); tween.stop(gemGraphics, { alpha: true }); tween(gemGraphics, { alpha: 1 }, { duration: 500, easing: tween.easeInOut }); var specialGfx = self.attachAsset('special_gem', { anchorX: 0.5, anchorY: 0.5, alpha: 0.3 }); }; return self; }); var Container = Container.expand(function (type) { var self = Container.call(this); self.type = type || 'red'; var baseContainer = self.attachAsset('container', { anchorX: 0.5, anchorY: 0.5 }); var colorIndicator = self.attachAsset('container_' + self.type, { anchorX: 0.5, anchorY: 0.5, y: -15, scaleX: 0.8, scaleY: 0.5 }); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x333333 }); /**** * Game Code ****/ // Game configuration var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var CONTAINER_Y = GAME_HEIGHT - 100; var MAX_LIVES = 3; var SPECIAL_GEM_CHANCE = 0.1; // Game state variables var score = 0; var lives = MAX_LIVES; var level = 1; var gameActive = true; var gems = []; var containers = []; var currentDraggedGem = null; var gemSpawnInterval = 2000; // milliseconds var gemSpeed = 3; var availableColors = ['red', 'blue', 'green']; // Start with 3 colors // UI elements var scoreTxt = new Text2('Score: 0', { size: 70, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); scoreTxt.y = 100; var levelTxt = new Text2('Level: 1', { size: 70, fill: 0xFFFFFF }); levelTxt.anchor.set(0, 0); LK.gui.topRight.addChild(levelTxt); levelTxt.x = -250; levelTxt.y = 100; var livesContainer = new Container(); livesContainer.x = 200; livesContainer.y = 120; LK.gui.topLeft.addChild(livesContainer); // Initialize lives display function updateLivesDisplay() { // Clear existing lives while (livesContainer.children.length > 0) { livesContainer.removeChildAt(0); } // Add life icons for (var i = 0; i < lives; i++) { var lifeIcon = LK.getAsset('life', { anchorX: 0.5, anchorY: 0.5, x: i * 60, y: 0 }); livesContainer.addChild(lifeIcon); } } // Create color containers at the bottom function createContainers() { // Clear existing containers for (var i = 0; i < containers.length; i++) { if (containers[i] && containers[i].parent) { containers[i].parent.removeChild(containers[i]); } } containers = []; // Calculate spacing and create new containers var containerWidth = 150; var totalWidth = containerWidth * availableColors.length; var startX = (GAME_WIDTH - totalWidth) / 2 + containerWidth / 2; var spacing = containerWidth * 1.5; for (var i = 0; i < availableColors.length; i++) { var container = new Container(availableColors[i]); container.x = startX + i * spacing; container.y = CONTAINER_Y; game.addChild(container); containers.push(container); } } // Spawn a new gem function spawnGem() { if (!gameActive) { return; } var randomColorIndex = Math.floor(Math.random() * availableColors.length); var gemType = availableColors[randomColorIndex]; var gem = new Gem(gemType, gemSpeed); // Random X position within boundaries var padding = 120; // Gem width gem.x = padding + Math.random() * (GAME_WIDTH - padding * 2); gem.y = -100; // Start above screen // Small chance to create a special gem if (Math.random() < SPECIAL_GEM_CHANCE) { gem.makeSpecial(); } game.addChild(gem); gems.push(gem); // Schedule next gem spawn var randomDelay = Math.random() * 500; // Add some randomness LK.setTimeout(spawnGem, gemSpawnInterval + randomDelay); } // Check if a gem is on a container and handle matching function checkGemContainerCollision(gem) { if (gem.matched) { return; } for (var i = 0; i < containers.length; i++) { var container = containers[i]; if (gem.intersects(container)) { if (gem.type === container.type) { // Correct match gem.matched = true; // Score points var points = 10; if (gem.isSpecial) { points = 30; LK.getSound('special').play(); // Special gem effect: slow down all gems temporarily var originalSpeed = gemSpeed; gemSpeed = gemSpeed / 2; LK.setTimeout(function () { gemSpeed = originalSpeed; }, 3000); } else { LK.getSound('match').play(); } // Update score and display score += points; scoreTxt.setText('Score: ' + score); // Animate gem disappearing tween(gem, { alpha: 0, scaleX: 0.2, scaleY: 0.2 }, { duration: 300, onFinish: function onFinish() { // Remove from game removeGem(gem); } }); // Flash container LK.effects.flashObject(container, 0xffffff, 500); return true; } else { // Wrong container LK.getSound('wrong').play(); lives--; updateLivesDisplay(); if (lives <= 0) { gameOver(); } // Flash container red LK.effects.flashObject(container, 0xff0000, 500); // Animate gem disappearing tween(gem, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { // Remove from game removeGem(gem); } }); return true; } } } return false; } // Remove a gem from the game function removeGem(gemToRemove) { for (var i = gems.length - 1; i >= 0; i--) { if (gems[i] === gemToRemove) { // Remove from array gems.splice(i, 1); // Remove from display if (gemToRemove.parent) { gemToRemove.parent.removeChild(gemToRemove); } break; } } } // Game over function function gameOver() { gameActive = false; // Check for high score if (score > storage.highScore) { storage.highScore = score; } // Show game over screen LK.showGameOver(); } // Level up function function levelUp() { level++; levelTxt.setText('Level: ' + level); LK.getSound('levelup').play(); // Add new color every 2 levels if (level % 2 === 0 && availableColors.length < 5) { if (level === 2) { availableColors.push('yellow'); } else if (level === 4) { availableColors.push('purple'); } createContainers(); } // Increase difficulty gemSpeed += 0.5; gemSpawnInterval = Math.max(500, gemSpawnInterval - 300); // Flash screen effect LK.effects.flashScreen(0xffffff, 500); } // Initialize the game function initGame() { score = 0; lives = MAX_LIVES; level = 1; gameActive = true; gems = []; gemSpeed = 3; gemSpawnInterval = 2000; availableColors = ['red', 'blue', 'green']; scoreTxt.setText('Score: 0'); levelTxt.setText('Level: 1'); updateLivesDisplay(); createContainers(); // Start spawning gems LK.setTimeout(spawnGem, 1000); // Start music LK.playMusic('bgmusic'); } // Game event handlers game.down = function (x, y, obj) { // Handle checking which gem was clicked for (var i = 0; i < gems.length; i++) { var gem = gems[i]; var localPoint = gem.toLocal({ x: x, y: y }); if (localPoint.x >= -gem.width / 2 && localPoint.x <= gem.width / 2 && localPoint.y >= -gem.height / 2 && localPoint.y <= gem.height / 2) { currentDraggedGem = gem; break; } } }; game.move = function (x, y, obj) { // Update dragged gem position if (currentDraggedGem && !currentDraggedGem.matched) { currentDraggedGem.x = x; currentDraggedGem.y = y; } }; game.up = function (x, y, obj) { // Check if the gem was dropped on a container if (currentDraggedGem && !currentDraggedGem.matched) { checkGemContainerCollision(currentDraggedGem); } currentDraggedGem = null; }; // Main game loop game.update = function () { if (!gameActive) { return; } // Process all gems for (var i = gems.length - 1; i >= 0; i--) { var gem = gems[i]; // Skip gems being dragged if (gem === currentDraggedGem) { continue; } // Check if gem hit bottom if (gem.y > GAME_HEIGHT + 100) { if (!gem.matched) { lives--; updateLivesDisplay(); if (lives <= 0) { gameOver(); return; } } removeGem(gem); continue; } } // Check for level up (based on score) var scoreTrigger = level * 100; if (score >= scoreTrigger && score < scoreTrigger + 10) { levelUp(); } }; // Initialize game initGame();
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,378 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1", {
+ highScore: 0
+});
+
+/****
+* Classes
+****/
+var Gem = Container.expand(function (type, speed) {
+ var self = Container.call(this);
+ self.type = type || 'red';
+ self.speed = speed || 3;
+ self.matched = false;
+ self.isSpecial = false;
+ var assetId = 'gem_' + self.type;
+ var gemGraphics = self.attachAsset(assetId, {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ self.update = function () {
+ if (!self.matched) {
+ self.y += self.speed;
+ }
+ };
+ self.down = function (x, y, obj) {
+ // This gem is being dragged
+ if (!self.matched) {
+ currentDraggedGem = self;
+ }
+ };
+ self.makeSpecial = function () {
+ self.isSpecial = true;
+ tween(gemGraphics, {
+ alpha: 0.5
+ }, {
+ duration: 500,
+ easing: tween.easeInOut
+ });
+ tween.stop(gemGraphics, {
+ alpha: true
+ });
+ tween(gemGraphics, {
+ alpha: 1
+ }, {
+ duration: 500,
+ easing: tween.easeInOut
+ });
+ var specialGfx = self.attachAsset('special_gem', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ alpha: 0.3
+ });
+ };
+ return self;
+});
+var Container = Container.expand(function (type) {
+ var self = Container.call(this);
+ self.type = type || 'red';
+ var baseContainer = self.attachAsset('container', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ var colorIndicator = self.attachAsset('container_' + self.type, {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ y: -15,
+ scaleX: 0.8,
+ scaleY: 0.5
+ });
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x333333
+});
+
+/****
+* Game Code
+****/
+// Game configuration
+var GAME_WIDTH = 2048;
+var GAME_HEIGHT = 2732;
+var CONTAINER_Y = GAME_HEIGHT - 100;
+var MAX_LIVES = 3;
+var SPECIAL_GEM_CHANCE = 0.1;
+// Game state variables
+var score = 0;
+var lives = MAX_LIVES;
+var level = 1;
+var gameActive = true;
+var gems = [];
+var containers = [];
+var currentDraggedGem = null;
+var gemSpawnInterval = 2000; // milliseconds
+var gemSpeed = 3;
+var availableColors = ['red', 'blue', 'green']; // Start with 3 colors
+// UI elements
+var scoreTxt = new Text2('Score: 0', {
+ size: 70,
+ fill: 0xFFFFFF
+});
+scoreTxt.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreTxt);
+scoreTxt.y = 100;
+var levelTxt = new Text2('Level: 1', {
+ size: 70,
+ fill: 0xFFFFFF
+});
+levelTxt.anchor.set(0, 0);
+LK.gui.topRight.addChild(levelTxt);
+levelTxt.x = -250;
+levelTxt.y = 100;
+var livesContainer = new Container();
+livesContainer.x = 200;
+livesContainer.y = 120;
+LK.gui.topLeft.addChild(livesContainer);
+// Initialize lives display
+function updateLivesDisplay() {
+ // Clear existing lives
+ while (livesContainer.children.length > 0) {
+ livesContainer.removeChildAt(0);
+ }
+ // Add life icons
+ for (var i = 0; i < lives; i++) {
+ var lifeIcon = LK.getAsset('life', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: i * 60,
+ y: 0
+ });
+ livesContainer.addChild(lifeIcon);
+ }
+}
+// Create color containers at the bottom
+function createContainers() {
+ // Clear existing containers
+ for (var i = 0; i < containers.length; i++) {
+ if (containers[i] && containers[i].parent) {
+ containers[i].parent.removeChild(containers[i]);
+ }
+ }
+ containers = [];
+ // Calculate spacing and create new containers
+ var containerWidth = 150;
+ var totalWidth = containerWidth * availableColors.length;
+ var startX = (GAME_WIDTH - totalWidth) / 2 + containerWidth / 2;
+ var spacing = containerWidth * 1.5;
+ for (var i = 0; i < availableColors.length; i++) {
+ var container = new Container(availableColors[i]);
+ container.x = startX + i * spacing;
+ container.y = CONTAINER_Y;
+ game.addChild(container);
+ containers.push(container);
+ }
+}
+// Spawn a new gem
+function spawnGem() {
+ if (!gameActive) {
+ return;
+ }
+ var randomColorIndex = Math.floor(Math.random() * availableColors.length);
+ var gemType = availableColors[randomColorIndex];
+ var gem = new Gem(gemType, gemSpeed);
+ // Random X position within boundaries
+ var padding = 120; // Gem width
+ gem.x = padding + Math.random() * (GAME_WIDTH - padding * 2);
+ gem.y = -100; // Start above screen
+ // Small chance to create a special gem
+ if (Math.random() < SPECIAL_GEM_CHANCE) {
+ gem.makeSpecial();
+ }
+ game.addChild(gem);
+ gems.push(gem);
+ // Schedule next gem spawn
+ var randomDelay = Math.random() * 500; // Add some randomness
+ LK.setTimeout(spawnGem, gemSpawnInterval + randomDelay);
+}
+// Check if a gem is on a container and handle matching
+function checkGemContainerCollision(gem) {
+ if (gem.matched) {
+ return;
+ }
+ for (var i = 0; i < containers.length; i++) {
+ var container = containers[i];
+ if (gem.intersects(container)) {
+ if (gem.type === container.type) {
+ // Correct match
+ gem.matched = true;
+ // Score points
+ var points = 10;
+ if (gem.isSpecial) {
+ points = 30;
+ LK.getSound('special').play();
+ // Special gem effect: slow down all gems temporarily
+ var originalSpeed = gemSpeed;
+ gemSpeed = gemSpeed / 2;
+ LK.setTimeout(function () {
+ gemSpeed = originalSpeed;
+ }, 3000);
+ } else {
+ LK.getSound('match').play();
+ }
+ // Update score and display
+ score += points;
+ scoreTxt.setText('Score: ' + score);
+ // Animate gem disappearing
+ tween(gem, {
+ alpha: 0,
+ scaleX: 0.2,
+ scaleY: 0.2
+ }, {
+ duration: 300,
+ onFinish: function onFinish() {
+ // Remove from game
+ removeGem(gem);
+ }
+ });
+ // Flash container
+ LK.effects.flashObject(container, 0xffffff, 500);
+ return true;
+ } else {
+ // Wrong container
+ LK.getSound('wrong').play();
+ lives--;
+ updateLivesDisplay();
+ if (lives <= 0) {
+ gameOver();
+ }
+ // Flash container red
+ LK.effects.flashObject(container, 0xff0000, 500);
+ // Animate gem disappearing
+ tween(gem, {
+ alpha: 0
+ }, {
+ duration: 300,
+ onFinish: function onFinish() {
+ // Remove from game
+ removeGem(gem);
+ }
+ });
+ return true;
+ }
+ }
+ }
+ return false;
+}
+// Remove a gem from the game
+function removeGem(gemToRemove) {
+ for (var i = gems.length - 1; i >= 0; i--) {
+ if (gems[i] === gemToRemove) {
+ // Remove from array
+ gems.splice(i, 1);
+ // Remove from display
+ if (gemToRemove.parent) {
+ gemToRemove.parent.removeChild(gemToRemove);
+ }
+ break;
+ }
+ }
+}
+// Game over function
+function gameOver() {
+ gameActive = false;
+ // Check for high score
+ if (score > storage.highScore) {
+ storage.highScore = score;
+ }
+ // Show game over screen
+ LK.showGameOver();
+}
+// Level up function
+function levelUp() {
+ level++;
+ levelTxt.setText('Level: ' + level);
+ LK.getSound('levelup').play();
+ // Add new color every 2 levels
+ if (level % 2 === 0 && availableColors.length < 5) {
+ if (level === 2) {
+ availableColors.push('yellow');
+ } else if (level === 4) {
+ availableColors.push('purple');
+ }
+ createContainers();
+ }
+ // Increase difficulty
+ gemSpeed += 0.5;
+ gemSpawnInterval = Math.max(500, gemSpawnInterval - 300);
+ // Flash screen effect
+ LK.effects.flashScreen(0xffffff, 500);
+}
+// Initialize the game
+function initGame() {
+ score = 0;
+ lives = MAX_LIVES;
+ level = 1;
+ gameActive = true;
+ gems = [];
+ gemSpeed = 3;
+ gemSpawnInterval = 2000;
+ availableColors = ['red', 'blue', 'green'];
+ scoreTxt.setText('Score: 0');
+ levelTxt.setText('Level: 1');
+ updateLivesDisplay();
+ createContainers();
+ // Start spawning gems
+ LK.setTimeout(spawnGem, 1000);
+ // Start music
+ LK.playMusic('bgmusic');
+}
+// Game event handlers
+game.down = function (x, y, obj) {
+ // Handle checking which gem was clicked
+ for (var i = 0; i < gems.length; i++) {
+ var gem = gems[i];
+ var localPoint = gem.toLocal({
+ x: x,
+ y: y
+ });
+ if (localPoint.x >= -gem.width / 2 && localPoint.x <= gem.width / 2 && localPoint.y >= -gem.height / 2 && localPoint.y <= gem.height / 2) {
+ currentDraggedGem = gem;
+ break;
+ }
+ }
+};
+game.move = function (x, y, obj) {
+ // Update dragged gem position
+ if (currentDraggedGem && !currentDraggedGem.matched) {
+ currentDraggedGem.x = x;
+ currentDraggedGem.y = y;
+ }
+};
+game.up = function (x, y, obj) {
+ // Check if the gem was dropped on a container
+ if (currentDraggedGem && !currentDraggedGem.matched) {
+ checkGemContainerCollision(currentDraggedGem);
+ }
+ currentDraggedGem = null;
+};
+// Main game loop
+game.update = function () {
+ if (!gameActive) {
+ return;
+ }
+ // Process all gems
+ for (var i = gems.length - 1; i >= 0; i--) {
+ var gem = gems[i];
+ // Skip gems being dragged
+ if (gem === currentDraggedGem) {
+ continue;
+ }
+ // Check if gem hit bottom
+ if (gem.y > GAME_HEIGHT + 100) {
+ if (!gem.matched) {
+ lives--;
+ updateLivesDisplay();
+ if (lives <= 0) {
+ gameOver();
+ return;
+ }
+ }
+ removeGem(gem);
+ continue;
+ }
+ }
+ // Check for level up (based on score)
+ var scoreTrigger = level * 100;
+ if (score >= scoreTrigger && score < scoreTrigger + 10) {
+ levelUp();
+ }
+};
+// Initialize game
+initGame();
\ No newline at end of file