Code edit (1 edits merged)
Please save this source code
User prompt
Color Match Rush
Initial prompt
yes I want Color Match Rush is a fast-paced puzzle game where players match falling colored blocks with corresponding target zones at the bottom of the screen. As blocks fall from the top, players must swipe them into matching color zones before they reach the bottom. Each successful match adds to the score, while mismatches deduct points. The game increases in difficulty with faster falling blocks, color-changing blocks, and special power-ups that can clear multiple blocks at once. Players race against time to achieve the highest score possible before the difficulty becomes overwhelming.
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Block = Container.expand(function (colorType) {
var self = Container.call(this);
self.colorType = colorType;
self.isMatched = false;
self.isDragging = false;
self.velocity = {
x: 0,
y: 2 + Math.random() * 2
}; // Random initial falling speed
// Colors map
var colorMap = {
'red': 'redBlock',
'blue': 'blueBlock',
'green': 'greenBlock',
'yellow': 'yellowBlock'
};
// Create and attach the block graphics
self.blockGraphics = self.attachAsset(colorMap[colorType], {
anchorX: 0.5,
anchorY: 0.5
});
// Set initial alpha slightly transparent
self.blockGraphics.alpha = 0.9;
// Handle touch/mouse events
self.down = function (x, y, obj) {
self.isDragging = true;
// Store initial touch position for swipe calculation
self.touchStartX = x;
self.touchStartY = y;
};
self.up = function (x, y, obj) {
if (self.isDragging) {
// Calculate swipe direction
var deltaX = x - self.touchStartX;
var deltaY = y - self.touchStartY;
// Apply a velocity based on swipe
if (Math.abs(deltaX) > 20) {
// Minimum swipe threshold
self.velocity.x = deltaX / 10; // Scale down swipe to reasonable velocity
}
self.isDragging = false;
}
};
self.update = function () {
if (!self.isMatched) {
// Apply gravity and movement
self.y += self.velocity.y;
self.x += self.velocity.x;
// Slow down horizontal velocity (drag)
self.velocity.x *= 0.95;
// Keep block within game boundaries
if (self.x < 75) {
self.x = 75;
self.velocity.x *= -0.5; // Bounce off wall with reduced speed
} else if (self.x > 2048 - 75) {
self.x = 2048 - 75;
self.velocity.x *= -0.5; // Bounce off wall with reduced speed
}
}
};
return self;
});
var TargetZone = Container.expand(function (colorType, position) {
var self = Container.call(this);
self.colorType = colorType;
self.position = position;
// Create and attach target zone base
var zoneBase = self.attachAsset('targetZone', {
anchorX: 0.5,
anchorY: 0.5
});
// Set alpha for better visibility
zoneBase.alpha = 0.5;
// Tint the zone to match its color type
switch (colorType) {
case 'red':
zoneBase.tint = 0xff0000;
break;
case 'blue':
zoneBase.tint = 0x0000ff;
break;
case 'green':
zoneBase.tint = 0x00ff00;
break;
case 'yellow':
zoneBase.tint = 0xffff00;
break;
}
// Add label to identify target
var label = new Text2(colorType.toUpperCase(), {
size: 40,
fill: 0xFFFFFF
});
label.anchor.set(0.5, 0.5);
self.addChild(label);
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x333333
});
/****
* Game Code
****/
// Game variables
var blocks = [];
var targetZones = [];
var score = 0;
var level = 1;
var spawnInterval = 2000; // Time in ms between block spawns
var gameOver = false;
var colors = ['red', 'blue', 'green', 'yellow'];
// Initialize game
function initGame() {
// Set up score text
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.y = 50; // Add some padding from the top
// Set up level indicator
var levelTxt = new Text2('Level: 1', {
size: 40,
fill: 0xFFFFFF
});
levelTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(levelTxt);
levelTxt.x = -150; // Offset from right edge
levelTxt.y = 30; // Add some padding from the top
// Create target zones
createTargetZones();
// Start spawning blocks
startBlockSpawner();
// Play background music
LK.playMusic('gameMusic', {
fade: {
start: 0,
end: 0.7,
duration: 1000
}
});
}
// Create the target zones at the bottom of the screen
function createTargetZones() {
var zoneWidth = 300;
var totalWidth = zoneWidth * colors.length;
var startX = (2048 - totalWidth) / 2 + zoneWidth / 2;
for (var i = 0; i < colors.length; i++) {
var zone = new TargetZone(colors[i], i);
zone.x = startX + i * zoneWidth;
zone.y = 2732 - 100; // Position near bottom
targetZones.push(zone);
game.addChild(zone);
}
}
// Start the block spawner timer
function startBlockSpawner() {
// Spawn a block immediately
spawnBlock();
// Set up interval for continued spawning
var spawner = LK.setInterval(function () {
if (!gameOver) {
spawnBlock();
}
}, spawnInterval);
}
// Spawn a new block
function spawnBlock() {
var colorIndex = Math.floor(Math.random() * colors.length);
var newBlock = new Block(colors[colorIndex]);
// Position randomly along the top
newBlock.x = 200 + Math.random() * (2048 - 400);
newBlock.y = -75; // Start above the screen
blocks.push(newBlock);
game.addChild(newBlock);
}
// Check for matches between blocks and target zones
function checkMatches() {
for (var i = blocks.length - 1; i >= 0; i--) {
var block = blocks[i];
// Skip if already matched
if (block.isMatched) {
continue;
}
// Check if the block is at the bottom of the screen
if (block.y >= 2732 - 200) {
// Check for matches with target zones
var matched = false;
for (var j = 0; j < targetZones.length; j++) {
var zone = targetZones[j];
if (block.intersects(zone)) {
// Check if colors match
if (block.colorType === zone.colorType) {
// Match! Add score
score += 10;
matched = true;
// Play match sound
LK.getSound('match').play();
// Visual feedback for match
LK.effects.flashObject(block, 0xFFFFFF, 300);
tween(block, {
alpha: 0,
scaleX: 0.2,
scaleY: 0.2
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
block.destroy();
blocks.splice(i, 1);
}
});
} else {
// Mismatch! Subtract score
score = Math.max(0, score - 5);
matched = true;
// Play mismatch sound
LK.getSound('mismatch').play();
// Visual feedback for mismatch
LK.effects.flashObject(block, 0xFF0000, 300);
tween(block, {
alpha: 0,
rotation: Math.PI * 2
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
block.destroy();
blocks.splice(i, 1);
}
});
}
// Mark as matched so we don't process it again
block.isMatched = true;
break;
}
}
// If block reached bottom but didn't match any zone
if (!matched && block.y >= 2732) {
// Penalty for missing
score = Math.max(0, score - 3);
// Visual feedback
tween(block, {
alpha: 0
}, {
duration: 200,
onFinish: function onFinish() {
block.destroy();
blocks.splice(i, 1);
}
});
}
}
}
// Update score display
updateScoreAndLevel();
}
// Update the score and level display
function updateScoreAndLevel() {
// Update score text
var scoreTxt = LK.gui.top.children[0];
scoreTxt.setText('Score: ' + score);
// Check for level up (every 100 points)
var newLevel = Math.floor(score / 100) + 1;
if (newLevel > level) {
level = newLevel;
var levelTxt = LK.gui.topRight.children[0];
levelTxt.setText('Level: ' + level);
// Increase difficulty
spawnInterval = Math.max(500, 2000 - (level - 1) * 200);
// Visual feedback for level up
LK.effects.flashScreen(0x00FF00, 500);
}
// Set the official score in LK
LK.setScore(score);
// Check win condition (level 10 reached)
if (level >= 10) {
LK.showYouWin();
}
}
// Check if game is over (too many blocks on screen)
function checkGameOver() {
// Count active blocks
var activeBlocks = 0;
for (var i = 0; i < blocks.length; i++) {
if (!blocks[i].isMatched) {
activeBlocks++;
}
}
// If too many active blocks, game over
if (activeBlocks >= 15) {
gameOver = true;
LK.showGameOver();
}
}
// Track dragging
var draggedBlock = null;
// Game event handlers
game.down = function (x, y, obj) {
// Check if we clicked on a block
for (var i = blocks.length - 1; i >= 0; i--) {
var block = blocks[i];
var blockPos = {
x: block.x,
y: block.y
};
var localPos = game.toLocal(blockPos);
// Check if click is within block bounds
if (Math.abs(x - localPos.x) < 75 && Math.abs(y - localPos.y) < 75) {
draggedBlock = block;
block.down(x, y, obj);
break;
}
}
};
game.up = function (x, y, obj) {
if (draggedBlock) {
draggedBlock.up(x, y, obj);
draggedBlock = null;
}
};
game.move = function (x, y, obj) {
if (draggedBlock) {
// Calculate movement relative to game
var deltaX = x - draggedBlock.touchStartX;
// Apply horizontal movement only (vertical falls automatically)
draggedBlock.x += deltaX;
// Update start position for next move
draggedBlock.touchStartX = x;
}
};
// Main game update loop
game.update = function () {
if (!gameOver) {
// Update all blocks
for (var i = 0; i < blocks.length; i++) {
blocks[i].update();
}
// Check for matches and update score
checkMatches();
// Check for game over condition
checkGameOver();
// Increase difficulty over time by adjusting block fall speed
if (LK.ticks % 600 === 0) {
// Every 10 seconds
for (var i = 0; i < blocks.length; i++) {
blocks[i].velocity.y *= 1.05; // 5% increase in speed
}
}
}
};
// Initialize the game
initGame(); ===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,368 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1");
+
+/****
+* Classes
+****/
+var Block = Container.expand(function (colorType) {
+ var self = Container.call(this);
+ self.colorType = colorType;
+ self.isMatched = false;
+ self.isDragging = false;
+ self.velocity = {
+ x: 0,
+ y: 2 + Math.random() * 2
+ }; // Random initial falling speed
+ // Colors map
+ var colorMap = {
+ 'red': 'redBlock',
+ 'blue': 'blueBlock',
+ 'green': 'greenBlock',
+ 'yellow': 'yellowBlock'
+ };
+ // Create and attach the block graphics
+ self.blockGraphics = self.attachAsset(colorMap[colorType], {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Set initial alpha slightly transparent
+ self.blockGraphics.alpha = 0.9;
+ // Handle touch/mouse events
+ self.down = function (x, y, obj) {
+ self.isDragging = true;
+ // Store initial touch position for swipe calculation
+ self.touchStartX = x;
+ self.touchStartY = y;
+ };
+ self.up = function (x, y, obj) {
+ if (self.isDragging) {
+ // Calculate swipe direction
+ var deltaX = x - self.touchStartX;
+ var deltaY = y - self.touchStartY;
+ // Apply a velocity based on swipe
+ if (Math.abs(deltaX) > 20) {
+ // Minimum swipe threshold
+ self.velocity.x = deltaX / 10; // Scale down swipe to reasonable velocity
+ }
+ self.isDragging = false;
+ }
+ };
+ self.update = function () {
+ if (!self.isMatched) {
+ // Apply gravity and movement
+ self.y += self.velocity.y;
+ self.x += self.velocity.x;
+ // Slow down horizontal velocity (drag)
+ self.velocity.x *= 0.95;
+ // Keep block within game boundaries
+ if (self.x < 75) {
+ self.x = 75;
+ self.velocity.x *= -0.5; // Bounce off wall with reduced speed
+ } else if (self.x > 2048 - 75) {
+ self.x = 2048 - 75;
+ self.velocity.x *= -0.5; // Bounce off wall with reduced speed
+ }
+ }
+ };
+ return self;
+});
+var TargetZone = Container.expand(function (colorType, position) {
+ var self = Container.call(this);
+ self.colorType = colorType;
+ self.position = position;
+ // Create and attach target zone base
+ var zoneBase = self.attachAsset('targetZone', {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Set alpha for better visibility
+ zoneBase.alpha = 0.5;
+ // Tint the zone to match its color type
+ switch (colorType) {
+ case 'red':
+ zoneBase.tint = 0xff0000;
+ break;
+ case 'blue':
+ zoneBase.tint = 0x0000ff;
+ break;
+ case 'green':
+ zoneBase.tint = 0x00ff00;
+ break;
+ case 'yellow':
+ zoneBase.tint = 0xffff00;
+ break;
+ }
+ // Add label to identify target
+ var label = new Text2(colorType.toUpperCase(), {
+ size: 40,
+ fill: 0xFFFFFF
+ });
+ label.anchor.set(0.5, 0.5);
+ self.addChild(label);
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x333333
+});
+
+/****
+* Game Code
+****/
+// Game variables
+var blocks = [];
+var targetZones = [];
+var score = 0;
+var level = 1;
+var spawnInterval = 2000; // Time in ms between block spawns
+var gameOver = false;
+var colors = ['red', 'blue', 'green', 'yellow'];
+// Initialize game
+function initGame() {
+ // Set up score text
+ var scoreTxt = new Text2('Score: 0', {
+ size: 60,
+ fill: 0xFFFFFF
+ });
+ scoreTxt.anchor.set(0.5, 0);
+ LK.gui.top.addChild(scoreTxt);
+ scoreTxt.y = 50; // Add some padding from the top
+ // Set up level indicator
+ var levelTxt = new Text2('Level: 1', {
+ size: 40,
+ fill: 0xFFFFFF
+ });
+ levelTxt.anchor.set(0, 0);
+ LK.gui.topRight.addChild(levelTxt);
+ levelTxt.x = -150; // Offset from right edge
+ levelTxt.y = 30; // Add some padding from the top
+ // Create target zones
+ createTargetZones();
+ // Start spawning blocks
+ startBlockSpawner();
+ // Play background music
+ LK.playMusic('gameMusic', {
+ fade: {
+ start: 0,
+ end: 0.7,
+ duration: 1000
+ }
+ });
+}
+// Create the target zones at the bottom of the screen
+function createTargetZones() {
+ var zoneWidth = 300;
+ var totalWidth = zoneWidth * colors.length;
+ var startX = (2048 - totalWidth) / 2 + zoneWidth / 2;
+ for (var i = 0; i < colors.length; i++) {
+ var zone = new TargetZone(colors[i], i);
+ zone.x = startX + i * zoneWidth;
+ zone.y = 2732 - 100; // Position near bottom
+ targetZones.push(zone);
+ game.addChild(zone);
+ }
+}
+// Start the block spawner timer
+function startBlockSpawner() {
+ // Spawn a block immediately
+ spawnBlock();
+ // Set up interval for continued spawning
+ var spawner = LK.setInterval(function () {
+ if (!gameOver) {
+ spawnBlock();
+ }
+ }, spawnInterval);
+}
+// Spawn a new block
+function spawnBlock() {
+ var colorIndex = Math.floor(Math.random() * colors.length);
+ var newBlock = new Block(colors[colorIndex]);
+ // Position randomly along the top
+ newBlock.x = 200 + Math.random() * (2048 - 400);
+ newBlock.y = -75; // Start above the screen
+ blocks.push(newBlock);
+ game.addChild(newBlock);
+}
+// Check for matches between blocks and target zones
+function checkMatches() {
+ for (var i = blocks.length - 1; i >= 0; i--) {
+ var block = blocks[i];
+ // Skip if already matched
+ if (block.isMatched) {
+ continue;
+ }
+ // Check if the block is at the bottom of the screen
+ if (block.y >= 2732 - 200) {
+ // Check for matches with target zones
+ var matched = false;
+ for (var j = 0; j < targetZones.length; j++) {
+ var zone = targetZones[j];
+ if (block.intersects(zone)) {
+ // Check if colors match
+ if (block.colorType === zone.colorType) {
+ // Match! Add score
+ score += 10;
+ matched = true;
+ // Play match sound
+ LK.getSound('match').play();
+ // Visual feedback for match
+ LK.effects.flashObject(block, 0xFFFFFF, 300);
+ tween(block, {
+ alpha: 0,
+ scaleX: 0.2,
+ scaleY: 0.2
+ }, {
+ duration: 300,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ block.destroy();
+ blocks.splice(i, 1);
+ }
+ });
+ } else {
+ // Mismatch! Subtract score
+ score = Math.max(0, score - 5);
+ matched = true;
+ // Play mismatch sound
+ LK.getSound('mismatch').play();
+ // Visual feedback for mismatch
+ LK.effects.flashObject(block, 0xFF0000, 300);
+ tween(block, {
+ alpha: 0,
+ rotation: Math.PI * 2
+ }, {
+ duration: 300,
+ easing: tween.easeIn,
+ onFinish: function onFinish() {
+ block.destroy();
+ blocks.splice(i, 1);
+ }
+ });
+ }
+ // Mark as matched so we don't process it again
+ block.isMatched = true;
+ break;
+ }
+ }
+ // If block reached bottom but didn't match any zone
+ if (!matched && block.y >= 2732) {
+ // Penalty for missing
+ score = Math.max(0, score - 3);
+ // Visual feedback
+ tween(block, {
+ alpha: 0
+ }, {
+ duration: 200,
+ onFinish: function onFinish() {
+ block.destroy();
+ blocks.splice(i, 1);
+ }
+ });
+ }
+ }
+ }
+ // Update score display
+ updateScoreAndLevel();
+}
+// Update the score and level display
+function updateScoreAndLevel() {
+ // Update score text
+ var scoreTxt = LK.gui.top.children[0];
+ scoreTxt.setText('Score: ' + score);
+ // Check for level up (every 100 points)
+ var newLevel = Math.floor(score / 100) + 1;
+ if (newLevel > level) {
+ level = newLevel;
+ var levelTxt = LK.gui.topRight.children[0];
+ levelTxt.setText('Level: ' + level);
+ // Increase difficulty
+ spawnInterval = Math.max(500, 2000 - (level - 1) * 200);
+ // Visual feedback for level up
+ LK.effects.flashScreen(0x00FF00, 500);
+ }
+ // Set the official score in LK
+ LK.setScore(score);
+ // Check win condition (level 10 reached)
+ if (level >= 10) {
+ LK.showYouWin();
+ }
+}
+// Check if game is over (too many blocks on screen)
+function checkGameOver() {
+ // Count active blocks
+ var activeBlocks = 0;
+ for (var i = 0; i < blocks.length; i++) {
+ if (!blocks[i].isMatched) {
+ activeBlocks++;
+ }
+ }
+ // If too many active blocks, game over
+ if (activeBlocks >= 15) {
+ gameOver = true;
+ LK.showGameOver();
+ }
+}
+// Track dragging
+var draggedBlock = null;
+// Game event handlers
+game.down = function (x, y, obj) {
+ // Check if we clicked on a block
+ for (var i = blocks.length - 1; i >= 0; i--) {
+ var block = blocks[i];
+ var blockPos = {
+ x: block.x,
+ y: block.y
+ };
+ var localPos = game.toLocal(blockPos);
+ // Check if click is within block bounds
+ if (Math.abs(x - localPos.x) < 75 && Math.abs(y - localPos.y) < 75) {
+ draggedBlock = block;
+ block.down(x, y, obj);
+ break;
+ }
+ }
+};
+game.up = function (x, y, obj) {
+ if (draggedBlock) {
+ draggedBlock.up(x, y, obj);
+ draggedBlock = null;
+ }
+};
+game.move = function (x, y, obj) {
+ if (draggedBlock) {
+ // Calculate movement relative to game
+ var deltaX = x - draggedBlock.touchStartX;
+ // Apply horizontal movement only (vertical falls automatically)
+ draggedBlock.x += deltaX;
+ // Update start position for next move
+ draggedBlock.touchStartX = x;
+ }
+};
+// Main game update loop
+game.update = function () {
+ if (!gameOver) {
+ // Update all blocks
+ for (var i = 0; i < blocks.length; i++) {
+ blocks[i].update();
+ }
+ // Check for matches and update score
+ checkMatches();
+ // Check for game over condition
+ checkGameOver();
+ // Increase difficulty over time by adjusting block fall speed
+ if (LK.ticks % 600 === 0) {
+ // Every 10 seconds
+ for (var i = 0; i < blocks.length; i++) {
+ blocks[i].velocity.y *= 1.05; // 5% increase in speed
+ }
+ }
+ }
+};
+// Initialize the game
+initGame();
\ No newline at end of file