User prompt
make the tile a little more vibrant ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
add rainbow color
User prompt
remove the color yellow and a rainbow
User prompt
make the color more vibrante ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
when you open the menu make it bigger
User prompt
give more color choices
User prompt
the background is not changing
User prompt
make a menu button to change the background
User prompt
remove the bug in the tutorial
User prompt
only solve the first row
User prompt
there is a bug in the tutorial
User prompt
there is a bug
User prompt
there is a bug
User prompt
make the tutorial move the block until it is complete in the first level ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
there is a bug when the tutorial move the block in the first level ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
make the tutorial move the block step by step ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
make the got it button a little bigger
User prompt
there is a bug the tutorial button does not work
User prompt
make the tutorial button work
User prompt
make the tutorial button smaller
User prompt
put the the welcome to puzzle it button in the middle and make it small
User prompt
make a tutorial in the first level
User prompt
when level compele show new round button
User prompt
move the moves: block to the up left
User prompt
add a remix button t remix the block
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// PuzzleTile: Represents a single tile in the puzzle grid.
var PuzzleTile = Container.expand(function () {
var self = Container.call(this);
// Properties
self.gridX = 0; // grid position x
self.gridY = 0; // grid position y
self.correctX = 0; // correct grid position x
self.correctY = 0; // correct grid position y
self.tileIndex = 0; // index in the tile array
self.isEmpty = false; // is this the empty tile?
// The tile's visual
var tileAsset = self.attachAsset('tile', {
anchorX: 0,
anchorY: 0
});
// For MVP, we color each tile differently for visual distinction
self.setColor = function (color) {
tileAsset.color = color;
// Use tween to smoothly animate the tint change for more vibrant effect
tween(tileAsset, {
tint: color
}, {
duration: 300,
easing: tween.easeOut
});
};
// Set the label (number) for the tile
self.setLabel = function (label) {
if (self.labelText) {
self.labelText.setText(label);
} else {
var txt = new Text2(label + '', {
size: 120,
fill: 0x222222
});
txt.anchor.set(0.5, 0.5);
txt.x = tileAsset.width / 2;
txt.y = tileAsset.height / 2;
self.addChild(txt);
self.labelText = txt;
}
};
// Hide label for empty tile
self.hideLabel = function () {
if (self.labelText) {
self.labelText.visible = false;
}
};
// Show label
self.showLabel = function () {
if (self.labelText) {
self.labelText.visible = true;
}
};
// Animate to a new position
self.moveTo = function (x, y, duration) {
tween(self, {
x: x,
y: y
}, {
duration: duration || 200,
easing: tween.cubicOut
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222222
});
/****
* Game Code
****/
// In the future, this can be replaced with a real image or a procedurally generated pattern.
// For MVP, we use a colored box as a placeholder for each tile, with a random color per game.
// We'll use a single image asset for the puzzle, which will be randomly generated each game.
// --- Puzzle Settings ---
var gridSize = 4; // 4x4 grid (15-puzzle style)
var tileSize = 400; // px, will be scaled to fit screen
var tileSpacing = 12; // px gap between tiles
var puzzleOffsetX = 0;
var puzzleOffsetY = 0;
var puzzleWidth = gridSize * tileSize + (gridSize - 1) * tileSpacing;
var puzzleHeight = gridSize * tileSize + (gridSize - 1) * tileSpacing;
// --- State ---
var tiles = []; // 2D array [y][x] of PuzzleTile
var tileList = []; // flat array of all PuzzleTile
var emptyTile = null; // reference to the empty tile
var moveCount = 0;
var startTime = 0;
var timerInterval = null;
var isSolved = false;
// --- UI ---
var moveText = new Text2('Moves: 0', {
size: 90,
fill: 0xFFFFFF
});
moveText.anchor.set(0, 0); // Anchor to top-left for easier positioning
LK.gui.topLeft.addChild(moveText); // Add to topLeft GUI container
var timeText = new Text2('Time: 0s', {
size: 90,
fill: 0xFFFFFF
});
timeText.anchor.set(0.5, 0);
LK.gui.top.addChild(timeText); // Keep timeText in the top-center
// Position UI
moveText.x = 20; // Small margin from the left edge
moveText.y = 120; // Position below the platform menu icon area
timeText.x = LK.gui.top.width / 2; // Center timeText
timeText.y = 20;
// --- Remix Button ---
var remixBtn = new Text2('Remix', {
size: 90,
fill: 0xFFD700
});
remixBtn.anchor.set(0.5, 0);
remixBtn.x = LK.gui.top.width / 2;
remixBtn.y = 120;
remixBtn.interactive = true;
remixBtn.buttonMode = true;
remixBtn.down = function (x, y, obj) {
if (isSolved) return;
shufflePuzzle();
moveCount = 0;
startTime = Date.now();
updateUI();
};
LK.gui.top.addChild(remixBtn);
// --- New Round Button ---
var newRoundBtn = new Text2('New Round', {
size: 90,
fill: 0x4CAF50 // A nice green color for the new round button
});
newRoundBtn.anchor.set(0.5, 0);
newRoundBtn.x = LK.gui.top.width / 2;
newRoundBtn.y = remixBtn.y + remixBtn.height + 30; // Position below the Remix button with some padding
newRoundBtn.interactive = true;
newRoundBtn.buttonMode = true;
newRoundBtn.visible = false; // Initially hidden
newRoundBtn.down = function (x, y, obj) {
createPuzzle(); // This will re-initialize the game, hide this button, and reset isSolved
};
LK.gui.top.addChild(newRoundBtn);
// --- Background Menu Button ---
var bgMenuBtn = new Text2('BG', {
size: 60,
fill: 0xFFFFFF
});
bgMenuBtn.anchor.set(1, 0);
bgMenuBtn.x = LK.gui.topRight.width - 20;
bgMenuBtn.y = 20;
bgMenuBtn.interactive = true;
bgMenuBtn.buttonMode = true;
bgMenuBtn.down = function (x, y, obj) {
showBackgroundMenu();
};
LK.gui.topRight.addChild(bgMenuBtn);
// --- Background Selection Variables ---
var backgroundMenu = null;
var backgroundColors = [0x222222,
// Dark gray (default)
0x00FF00,
// Bright green
0x0080FF,
// Bright blue
0xFF00FF,
// Bright magenta
0xFF0040,
// Bright red
0xFF8000,
// Bright orange
0x8000FF,
// Bright purple
'rainbow' // Rainbow option
];
var currentBgIndex = 0;
// --- Rainbow Background Variables ---
var rainbowInterval = null;
var rainbowHue = 0;
// --- Helper Functions ---
// Generate a random color palette for the puzzle
function generateColorPalette(n) {
var colors = [];
var baseHue = Math.floor(Math.random() * 360);
for (var i = 0; i < n; i++) {
// HSL to RGB conversion with more vibrant saturation and lightness
var hue = (baseHue + i * (360 / n)) % 360;
var rgb = hslToRgb(hue / 360, 0.9, 0.7); // Increased saturation to 0.9 and lightness to 0.7
var color = rgb[0] << 16 | rgb[1] << 8 | rgb[2];
colors.push(color);
}
return colors;
}
// HSL to RGB helper
function hslToRgb(h, s, l) {
var r, g, b;
if (s == 0) {
r = g = b = l;
} else {
var hue2rgb = function hue2rgb(p, q, t) {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1 / 6) return p + (q - p) * 6 * t;
if (t < 1 / 2) return q;
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
return p;
};
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
}
// Shuffle an array in-place
function shuffleArray(arr) {
for (var i = arr.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
// Check if the puzzle is solved
function checkSolved() {
for (var y = 0; y < gridSize; y++) {
for (var x = 0; x < gridSize; x++) {
var tile = tiles[y][x];
if (tile.gridX !== tile.correctX || tile.gridY !== tile.correctY) {
return false;
}
}
}
return true;
}
// Update move and time UI
function updateUI() {
moveText.setText('Moves: ' + moveCount);
var elapsed = Math.floor((Date.now() - startTime) / 1000);
timeText.setText('Time: ' + elapsed + 's');
}
// --- Puzzle Generation ---
function createPuzzle() {
if (typeof newRoundBtn !== 'undefined' && newRoundBtn) {
newRoundBtn.visible = false;
}
if (typeof hideTutorial === 'function') {
hideTutorial();
}
// Remove old tiles
for (var i = 0; i < tileList.length; i++) {
tileList[i].destroy();
}
tiles = [];
tileList = [];
emptyTile = null;
isSolved = false;
moveCount = 0;
updateUI();
// Generate color palette
var numTiles = gridSize * gridSize;
var colors = generateColorPalette(numTiles - 1);
// Calculate tile size to fit screen
var maxWidth = 2048 - 200;
var maxHeight = 2732 - 400;
tileSize = Math.floor(Math.min((maxWidth - (gridSize - 1) * tileSpacing) / gridSize, (maxHeight - (gridSize - 1) * tileSpacing) / gridSize));
puzzleWidth = gridSize * tileSize + (gridSize - 1) * tileSpacing;
puzzleHeight = gridSize * tileSize + (gridSize - 1) * tileSpacing;
puzzleOffsetX = Math.floor((2048 - puzzleWidth) / 2);
puzzleOffsetY = Math.floor((2732 - puzzleHeight) / 2) + 80;
// Create tiles in solved order
var idx = 0;
for (var y = 0; y < gridSize; y++) {
tiles[y] = [];
for (var x = 0; x < gridSize; x++) {
var tile = new PuzzleTile();
tile.gridX = x;
tile.gridY = y;
tile.correctX = x;
tile.correctY = y;
tile.tileIndex = idx;
tile.x = puzzleOffsetX + x * (tileSize + tileSpacing);
tile.y = puzzleOffsetY + y * (tileSize + tileSpacing);
tile.width = tileSize;
tile.height = tileSize;
tile.setColor(colors[idx] || 0x222222);
tile.setLabel(idx + 1);
tile.isEmpty = false;
tileList.push(tile);
tiles[y][x] = tile;
game.addChild(tile);
idx++;
}
}
// Make last tile the empty tile
var lastTile = tiles[gridSize - 1][gridSize - 1];
lastTile.isEmpty = true;
lastTile.setColor(0x222222);
lastTile.hideLabel();
emptyTile = lastTile;
// Shuffle tiles
shufflePuzzle();
// Start timer
startTime = Date.now();
if (timerInterval) LK.clearInterval(timerInterval);
timerInterval = LK.setInterval(updateUI, 500);
}
// Shuffle the puzzle by simulating random valid moves
function shufflePuzzle() {
var moves = [[0, 1], [1, 0], [0, -1], [-1, 0]];
var prevX = emptyTile.gridX,
prevY = emptyTile.gridY;
var shuffleCount = 200 + Math.floor(Math.random() * 100);
for (var i = 0; i < shuffleCount; i++) {
var possible = [];
for (var d = 0; d < moves.length; d++) {
var nx = emptyTile.gridX + moves[d][0];
var ny = emptyTile.gridY + moves[d][1];
if (nx >= 0 && nx < gridSize && ny >= 0 && ny < gridSize) {
if (!(nx === prevX && ny === prevY)) {
possible.push([nx, ny]);
}
}
}
if (possible.length === 0) continue;
var pick = possible[Math.floor(Math.random() * possible.length)];
var tile = tiles[pick[1]][pick[0]];
swapWithEmpty(tile, false);
prevX = emptyTile.gridX;
prevY = emptyTile.gridY;
}
// After shuffling, update all tile positions visually
for (var y = 0; y < gridSize; y++) {
for (var x = 0; x < gridSize; x++) {
var tile = tiles[y][x];
tile.x = puzzleOffsetX + x * (tileSize + tileSpacing);
tile.y = puzzleOffsetY + y * (tileSize + tileSpacing);
tile.gridX = x;
tile.gridY = y;
}
}
}
// Swap a tile with the empty tile (if adjacent)
function swapWithEmpty(tile, animate) {
if (tile.isEmpty) return false;
var dx = Math.abs(tile.gridX - emptyTile.gridX);
var dy = Math.abs(tile.gridY - emptyTile.gridY);
if (dx === 1 && dy === 0 || dx === 0 && dy === 1) {
// Swap in tiles array
var tx = tile.gridX,
ty = tile.gridY;
var ex = emptyTile.gridX,
ey = emptyTile.gridY;
tiles[ty][tx] = emptyTile;
tiles[ey][ex] = tile;
// Swap grid positions
var tmpX = tile.gridX,
tmpY = tile.gridY;
tile.gridX = emptyTile.gridX;
tile.gridY = emptyTile.gridY;
emptyTile.gridX = tmpX;
emptyTile.gridY = tmpY;
// Animate movement
var tileTargetX = puzzleOffsetX + tile.gridX * (tileSize + tileSpacing);
var tileTargetY = puzzleOffsetY + tile.gridY * (tileSize + tileSpacing);
var emptyTargetX = puzzleOffsetX + emptyTile.gridX * (tileSize + tileSpacing);
var emptyTargetY = puzzleOffsetY + emptyTile.gridY * (tileSize + tileSpacing);
if (animate !== false) {
tile.moveTo(tileTargetX, tileTargetY, 120);
emptyTile.moveTo(emptyTargetX, emptyTargetY, 120);
} else {
tile.x = tileTargetX;
tile.y = tileTargetY;
emptyTile.x = emptyTargetX;
emptyTile.y = emptyTargetY;
}
return true;
}
return false;
}
// --- Input Handling ---
// Find which tile was pressed
function getTileAtPos(x, y) {
for (var i = 0; i < tileList.length; i++) {
var tile = tileList[i];
if (tile.isEmpty) continue;
var tx = tile.x,
ty = tile.y;
var tw = tile.width,
th = tile.height;
if (x >= tx && x <= tx + tw && y >= ty && y <= ty + th) {
return tile;
}
}
return null;
}
// Handle tap/click on the puzzle
game.down = function (x, y, obj) {
if (isSolved) return;
var tile = getTileAtPos(x, y);
if (!tile) return;
var moved = swapWithEmpty(tile, true);
if (moved) {
moveCount++;
updateUI();
if (checkSolved()) {
isSolved = true;
updateUI();
LK.effects.flashScreen(0x44ff44, 800);
// Instead of showing YouWin screen, show the New Round button
if (typeof newRoundBtn !== 'undefined' && newRoundBtn) {
newRoundBtn.visible = true;
}
// LK.setTimeout(function () { // Original YouWin call removed
// LK.showYouWin();
// }, 900);
}
}
};
// --- Game Update ---
game.update = function () {
// No per-frame logic needed for MVP
};
// --- Tutorial Overlay ---
var tutorialOverlay = null;
var tutorialStep = 0;
var tutorialActive = false;
// Show tutorial overlay for the first level
function showTutorial() {
tutorialActive = true;
tutorialStep = 0;
if (tutorialOverlay) {
tutorialOverlay.destroy();
tutorialOverlay = null;
}
tutorialOverlay = new Container();
var bg = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 20,
scaleY: 20,
x: 2048 / 2,
y: 2732 / 2
});
bg.alpha = 0.7;
tutorialOverlay.addChild(bg);
var tutText = new Text2("Welcome to Puzzle It!\n\nWatch how to move the tiles...", {
size: 100,
fill: 0xffffff
});
tutText.anchor.set(0.5, 0.5);
tutText.x = 2048 / 2;
tutText.y = 2732 / 2 - 200;
tutorialOverlay.addChild(tutText);
var tutBtn = new Text2("Got it!", {
size: 80,
fill: 0x4CAF50
});
tutBtn.anchor.set(0.5, 0.5);
tutBtn.x = 2048 / 2;
tutBtn.y = 2732 / 2 + 300;
tutBtn.interactive = true;
tutBtn.buttonMode = true;
tutBtn.visible = false; // Hide button initially
tutorialOverlay.addChild(tutBtn);
// Add the tutorial overlay to the game directly instead of LK.gui.center
game.addChild(tutorialOverlay);
// Set up the button's click handler after it's added to the display tree
tutBtn.down = function (x, y, obj) {
hideTutorial();
};
// Start the step-by-step tutorial
startTutorialSteps(tutText, tutBtn);
}
// Start step-by-step tutorial movements
function startTutorialSteps(tutText, tutBtn) {
var stepDelay = 2000; // 2 seconds between steps
var moveDelay = 1000; // 1 second to show movement
var steps = [{
text: "Step 1: Move tile 15 up...",
tileToMove: function tileToMove() {
// Find tile with number 15
for (var i = 0; i < tileList.length; i++) {
if (tileList[i].labelText && tileList[i].labelText.text === "15") {
return tileList[i];
}
}
return null;
}
}, {
text: "Step 2: Move tile 14 right...",
tileToMove: function tileToMove() {
// Find tile with number 14
for (var i = 0; i < tileList.length; i++) {
if (tileList[i].labelText && tileList[i].labelText.text === "14") {
return tileList[i];
}
}
return null;
}
}, {
text: "Step 3: Move tile 11 down...",
tileToMove: function tileToMove() {
// Find tile with number 11
for (var i = 0; i < tileList.length; i++) {
if (tileList[i].labelText && tileList[i].labelText.text === "11") {
return tileList[i];
}
}
return null;
}
}];
var currentStep = 0;
function performNextStep() {
if (currentStep >= steps.length) {
// Tutorial complete
tutText.setText("Great! Now you try.\n\nTap a tile next to the empty space to move it.\n\nPut the numbers in order to win.");
tutBtn.visible = true;
return;
}
var step = steps[currentStep];
tutText.setText(step.text);
// Wait a moment, then perform the move
LK.setTimeout(function () {
var tile = step.tileToMove();
if (tile && swapWithEmpty(tile, true)) {
// Move was successful, wait for animation then continue
LK.setTimeout(function () {
currentStep++;
performNextStep();
}, moveDelay);
} else {
// Move failed, skip to next step
currentStep++;
performNextStep();
}
}, stepDelay);
}
// Start the tutorial steps
performNextStep();
}
// Hide tutorial overlay
function hideTutorial() {
tutorialActive = false;
if (tutorialOverlay) {
game.removeChild(tutorialOverlay);
tutorialOverlay.destroy();
tutorialOverlay = null;
}
}
// Show background color selection menu
function showBackgroundMenu() {
if (backgroundMenu) {
hideBackgroundMenu();
return;
}
backgroundMenu = new Container();
// Semi-transparent background
var menuBg = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 12,
scaleY: 8,
x: 2048 / 2,
y: 2732 / 2
});
menuBg.alpha = 0.9;
menuBg.tint = 0x000000;
backgroundMenu.addChild(menuBg);
// Title
var titleText = new Text2("Choose Background", {
size: 80,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0.5);
titleText.x = 2048 / 2;
titleText.y = 2732 / 2 - 300;
backgroundMenu.addChild(titleText);
// Color options
var colorsPerRow = 4;
var colorSize = 120;
var colorSpacing = 40;
var startX = 2048 / 2 - (colorsPerRow * colorSize + (colorsPerRow - 1) * colorSpacing) / 2 + colorSize / 2;
var startY = 2732 / 2 - 100;
for (var i = 0; i < backgroundColors.length; i++) {
var row = Math.floor(i / colorsPerRow);
var col = i % colorsPerRow;
var colorBtn = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: colorSize / 100,
scaleY: colorSize / 100,
x: startX + col * (colorSize + colorSpacing),
y: startY + row * (colorSize + colorSpacing)
});
if (backgroundColors[i] === 'rainbow') {
// Create a rainbow gradient effect for the rainbow button
colorBtn.tint = 0xFF0000; // Start with red, will be animated
// Add a visual indicator that this is the rainbow option
var rainbowText = new Text2("🌈", {
size: 60,
fill: 0xFFFFFF
});
rainbowText.anchor.set(0.5, 0.5);
rainbowText.x = 0;
rainbowText.y = 0;
colorBtn.addChild(rainbowText);
} else {
colorBtn.tint = backgroundColors[i];
}
colorBtn.interactive = true;
colorBtn.buttonMode = true;
colorBtn.colorIndex = i;
// Add selection indicator for current background
if (i === currentBgIndex) {
var indicator = LK.getAsset('centerCircle', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: (colorSize + 20) / 100,
scaleY: (colorSize + 20) / 100,
x: 0,
y: 0
});
indicator.tint = 0xFFD700;
indicator.alpha = 0.8;
colorBtn.addChild(indicator);
}
(function (colorIndex) {
colorBtn.down = function (x, y, obj) {
currentBgIndex = colorIndex;
if (backgroundColors[colorIndex] === 'rainbow') {
startRainbowBackground();
} else {
stopRainbowBackground();
game.setBackgroundColor(backgroundColors[colorIndex]);
}
hideBackgroundMenu();
};
})(i);
backgroundMenu.addChild(colorBtn);
}
// Close button
var closeBtn = new Text2("Close", {
size: 70,
fill: 0xFF4444
});
closeBtn.anchor.set(0.5, 0.5);
closeBtn.x = 2048 / 2;
closeBtn.y = 2732 / 2 + 250;
closeBtn.interactive = true;
closeBtn.buttonMode = true;
closeBtn.down = function (x, y, obj) {
hideBackgroundMenu();
};
backgroundMenu.addChild(closeBtn);
game.addChild(backgroundMenu);
}
// Hide background selection menu
function hideBackgroundMenu() {
if (backgroundMenu) {
game.removeChild(backgroundMenu);
backgroundMenu.destroy();
backgroundMenu = null;
}
}
// Start rainbow background animation
function startRainbowBackground() {
stopRainbowBackground(); // Stop any existing rainbow
rainbowInterval = LK.setInterval(function () {
rainbowHue = (rainbowHue + 2) % 360; // Increment hue
var rgb = hslToRgb(rainbowHue / 360, 0.8, 0.5); // High saturation, medium lightness
var color = rgb[0] << 16 | rgb[1] << 8 | rgb[2];
game.setBackgroundColor(color);
}, 50); // Update every 50ms for smooth animation
}
// Stop rainbow background animation
function stopRainbowBackground() {
if (rainbowInterval) {
LK.clearInterval(rainbowInterval);
rainbowInterval = null;
}
}
// --- Start Game ---
createPuzzle();
;
// Show tutorial only for the first level (first time game is loaded)
showTutorial();
// Block input while tutorial is active
var origGameDown = game.down;
game.down = function (x, y, obj) {
if (tutorialActive) return;
origGameDown(x, y, obj);
}; ===================================================================
--- original.js
+++ change.js
@@ -23,9 +23,15 @@
});
// For MVP, we color each tile differently for visual distinction
self.setColor = function (color) {
tileAsset.color = color;
- tileAsset.tint = color;
+ // Use tween to smoothly animate the tint change for more vibrant effect
+ tween(tileAsset, {
+ tint: color
+ }, {
+ duration: 300,
+ easing: tween.easeOut
+ });
};
// Set the label (number) for the tile
self.setLabel = function (label) {
if (self.labelText) {
@@ -188,11 +194,11 @@
function generateColorPalette(n) {
var colors = [];
var baseHue = Math.floor(Math.random() * 360);
for (var i = 0; i < n; i++) {
- // HSL to RGB conversion
+ // HSL to RGB conversion with more vibrant saturation and lightness
var hue = (baseHue + i * (360 / n)) % 360;
- var rgb = hslToRgb(hue / 360, 0.6, 0.6);
+ var rgb = hslToRgb(hue / 360, 0.9, 0.7); // Increased saturation to 0.9 and lightness to 0.7
var color = rgb[0] << 16 | rgb[1] << 8 | rgb[2];
colors.push(color);
}
return colors;