/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var BrushStroke = Container.expand(function (color, size) {
var self = Container.call(this);
var stroke = self.attachAsset('brushStroke', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: size / 30,
scaleY: size / 30
});
stroke.tint = color;
return self;
});
var Button = Container.expand(function (label, color) {
var self = Container.call(this);
var background = self.attachAsset('buttonBg', {
anchorX: 0.5,
anchorY: 0.5
});
var text = new Text2(label, {
size: 30,
fill: 0xFFFFFF
});
text.anchor.set(0.5, 0.5);
self.addChild(text);
if (color !== undefined) {
background.tint = color;
}
self.down = function () {
tween(background, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100
});
};
self.up = function () {
tween(background, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
};
return self;
});
var ColorButton = Container.expand(function (color) {
var self = Container.call(this);
var button = self.attachAsset('colorButton', {
anchorX: 0.5,
anchorY: 0.5
});
button.tint = color;
self.color = color;
self.down = function () {
tween(button, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100
});
};
self.up = function () {
tween(button, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
};
return self;
});
var ColorPalette = Container.expand(function () {
var self = Container.call(this);
var background = LK.getAsset('colorPanel', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1881 / 1880,
// Set to exact size 1881
scaleY: 1899 / 277 // Set to exact size 1899
});
self.addChild(background);
var colorButtons = [];
// Generate 256 color gradient palette
var paletteColors = [];
var buttonSize = 90; // Increased from 30 to 90 (3x larger)
var spacing = 12; // Increased from 4 to 12 (3x larger)
var columns = 16;
var rows = 16;
// Generate rainbow gradient colors for the full 256 color palette
for (var i = 0; i < 256; i++) {
var hue = i / 256;
var r, g, b;
// Convert HSV to RGB (simplified rainbow gradient)
if (hue < 1 / 6) {
r = 1;
g = hue * 6;
b = 0;
} else if (hue < 2 / 6) {
r = (2 / 6 - hue) * 6;
g = 1;
b = 0;
} else if (hue < 3 / 6) {
r = 0;
g = 1;
b = (hue - 2 / 6) * 6;
} else if (hue < 4 / 6) {
r = 0;
g = (4 / 6 - hue) * 6;
b = 1;
} else if (hue < 5 / 6) {
r = (hue - 4 / 6) * 6;
b = 1;
g = 0;
} else {
r = 1;
g = 0;
b = (1 - hue) * 6;
}
// Convert to 0-255 range
var red = Math.floor(r * 255);
var green = Math.floor(g * 255);
var blue = Math.floor(b * 255);
var color = red << 16 | green << 8 | blue;
paletteColors.push(color);
}
for (var i = 0; i < paletteColors.length; i++) {
var row = Math.floor(i / columns);
var col = i % columns;
var colorBtn = new ColorButton(paletteColors[i]);
colorBtn.x = col * (buttonSize + spacing) - (columns - 1) * (buttonSize + spacing) / 2;
colorBtn.y = row * (buttonSize + spacing) - (rows - 1) * (buttonSize + spacing) / 2;
colorBtn.scaleX = 4.5; // Increased from 1.5 to 4.5 (3x larger)
colorBtn.scaleY = 4.5; // Increased from 1.5 to 4.5 (3x larger)
self.addChild(colorBtn);
// Create a closure to capture the current color
(function (color, btn) {
btn.down = function () {
currentColor = color;
self.visible = false;
// Notify the game that a color was selected
if (self.onColorSelected) {
self.onColorSelected(color);
}
};
})(paletteColors[i], colorBtn);
colorButtons.push(colorBtn);
}
// Add selector ring
var selector = LK.getAsset('brushStroke', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 7.5,
// Increased from 2.5 to 7.5 (3x larger)
scaleY: 7.5 // Increased from 2.5 to 7.5 (3x larger)
});
selector.tint = 0xFFFFFF;
selector.alpha = 0.7;
self.addChild(selector);
// Set selector initial position
selector.x = colorButtons[0].x;
selector.y = colorButtons[0].y;
// Hide palette initially
self.visible = false;
// Method to update selector position
self.updateSelector = function (color) {
for (var i = 0; i < paletteColors.length; i++) {
if (paletteColors[i] === color) {
selector.x = colorButtons[i].x;
selector.y = colorButtons[i].y;
break;
}
}
};
return self;
});
var CompletedEgg = Container.expand(function (baseColor) {
var self = Container.call(this);
var eggGraphic = self.attachAsset('completedEgg', {
anchorX: 0.5,
anchorY: 0.5
});
eggGraphic.tint = baseColor || 0xFFFFFF;
// Add some random decoration to make each egg look unique
for (var i = 0; i < 5; i++) {
var glitter = self.attachAsset('glitter', {
anchorX: 0.5,
anchorY: 0.5,
x: (Math.random() - 0.5) * 80,
y: (Math.random() - 0.5) * 120
});
glitter.tint = 0xFFD700 + Math.floor(Math.random() * 0x555555);
}
return self;
});
var EasterEgg = Container.expand(function () {
var self = Container.call(this);
var eggBase = self.attachAsset('eggBase', {
anchorX: 0.5,
anchorY: 0.5
});
var designContainer = new Container();
self.designContainer = designContainer; // Make accessible outside
self.addChild(designContainer);
self.addDesign = function (x, y, designElement) {
var localPosition = designContainer.toLocal({
x: x,
y: y
}, game);
// Check if the point is within the bounds of the eggBase
// Convert to egg's local coordinates for hit testing
var eggLocalPosition = self.toLocal({
x: x,
y: y
}, game);
// Calculate distance from center of egg
var dx = eggLocalPosition.x;
var dy = eggLocalPosition.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Check if point is inside the egg (ellipse)
// Using the egg's dimensions to determine the ellipse bounds
var eggWidth = eggBase.width / 2;
var eggHeight = eggBase.height / 2;
// Formula for point in ellipse: (x/a)² + (y/b)² <= 1
// where a is half-width and b is half-height
var isInEgg = dx * dx / (eggWidth * eggWidth) + dy * dy / (eggHeight * eggHeight) <= 1;
// Only add design if point is inside the egg
if (isInEgg) {
designElement.x = localPosition.x;
designElement.y = localPosition.y;
designContainer.addChild(designElement);
// Add to design history for undo functionality
designHistory.push({
element: designElement,
index: designContainer.children.length - 1
});
}
};
self.clearDesigns = function () {
while (designContainer.children.length > 0) {
designContainer.removeChild(designContainer.children[0]);
}
};
self.rotate = function (angle) {
eggBase.rotation += angle;
designContainer.rotation += angle;
};
self.captureDesign = function () {
// In a real implementation, this would create a snapshot of the egg
// For this simplified version, we just create a new completed egg with the same tint
var completedEgg = new CompletedEgg(eggBase.tint);
return completedEgg;
};
return self;
});
var Eraser = Container.expand(function (size) {
var self = Container.call(this);
// Create a visual representation of the eraser
var eraserVisual = self.attachAsset('brushStroke', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: size / 30,
scaleY: size / 30
});
// Make it white with a border
eraserVisual.tint = 0xFFFFFF;
eraserVisual.alpha = 0.7;
return self;
});
var Slider = Container.expand(function (minVal, maxVal, defaultVal, width, color) {
var self = Container.call(this);
// Track properties
self.minValue = minVal || 0;
self.maxValue = maxVal || 100;
self.value = defaultVal || 50;
self.trackWidth = width || 300;
self.trackColor = color || 0xCCCCCC;
// Create track
var track = LK.getAsset('buttonBg', {
anchorX: 0,
anchorY: 0.5,
scaleX: self.trackWidth / 120,
scaleY: 0.3
});
track.tint = self.trackColor;
self.addChild(track);
self.track = track; // Store track reference for external access
// Create handle
var handle = LK.getAsset('colorButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
handle.tint = 0xFFFFFF;
handle.x = (self.value - self.minValue) / (self.maxValue - self.minValue) * self.trackWidth;
self.addChild(handle);
self.handle = handle;
// No value label is needed
// Method definitions
// Convert value to x position
self.getXForValue = function (val) {
return (val - self.minValue) / (self.maxValue - self.minValue) * self.trackWidth;
};
// Convert x position to value
self.getValueForX = function (x) {
return self.minValue + x / self.trackWidth * (self.maxValue - self.minValue);
};
// Update handle position
self.updateHandlePosition = function () {
handle.x = self.getXForValue(self.value);
};
// Set value
self.setValue = function (val) {
self.value = Math.max(self.minValue, Math.min(self.maxValue, val));
self.updateHandlePosition();
if (self.onValueChanged) {
self.onValueChanged(self.value);
}
};
// Handle drag
self.down = function (x, y) {
self.isDragging = true;
self.setValue(self.getValueForX(x));
};
self.move = function (x, y) {
if (self.isDragging) {
self.setValue(self.getValueForX(Math.max(0, Math.min(self.trackWidth, x))));
}
};
self.up = function () {
self.isDragging = false;
};
return self;
});
var Sticker = Container.expand(function (type, scale) {
var self = Container.call(this);
var stickerAsset;
if (type === 'star') {
stickerAsset = self.attachAsset('stickerStar', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: scale * 5,
scaleY: scale * 5
});
} else if (type === 'heart') {
stickerAsset = self.attachAsset('stickerHeart', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: scale * 5,
scaleY: scale * 5
});
}
self.down = function () {
tween(stickerAsset, {
scaleX: scale * 5 * 0.9,
scaleY: scale * 5 * 0.9
}, {
duration: 100
});
};
self.up = function () {
tween(stickerAsset, {
scaleX: scale * 5,
scaleY: scale * 5
}, {
duration: 100
});
};
return self;
});
var Watermark = Container.expand(function (text, opacity) {
var self = Container.call(this);
// Set default values if not provided
self.text = text || "FRVR Easter";
self.opacity = opacity || 0.35;
// Create corner text elements
function createCornerText(x, y, rotation) {
var cornerText = new Text2(self.text, {
size: 28,
fill: 0x333333
});
cornerText.anchor.set(0.5, 0.5);
cornerText.x = x;
cornerText.y = y;
cornerText.rotation = rotation || 0;
cornerText.alpha = self.opacity;
self.addChild(cornerText);
return cornerText;
}
// Create text for each corner, avoiding top-left 100x100 area
self.topRight = createCornerText(2048 - 120, 120, Math.PI / 4);
self.bottomRight = createCornerText(2048 - 120, 2732 - 120, -Math.PI / 4);
self.bottomLeft = createCornerText(120, 2732 - 120, Math.PI / 4);
// Top left is placed with extra margin to avoid the platform menu icon
self.topLeft = createCornerText(180, 180, -Math.PI / 4);
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xAFEEEE // Light turquoise background color
});
/****
* Game Code
****/
// Define color palette - arranged in rainbow gradient
var colors = [
// Black (left)
0x000000,
// Violet group
0x9400D3,
// Violet
0x4B0082,
// Indigo
0x8A2BE2,
// Blue Violet
// Blue group
0x0000FF,
// Blue
0x000080,
// Navy Blue
0x00FFFF,
// Cyan
0x008080,
// Teal
// Green group
0x00FF00,
// Green
0x32CD32,
// Lime Green
0x808000,
// Olive
// Red group
0x800000,
// Maroon
0xA52A2A,
// Brown
0xFF0000,
// Red
0xFF7F00,
// Orange
// Yellow group
0xFFD700,
// Gold
0xFFFF00,
// Yellow
// Pink group
0xFF69B4,
// Hot Pink
// Gray
0x808080,
// White (right)
0xFFFFFF];
// Define brush sizes
var brushSizes = [10, 20, 30];
// Initialize game variables
var currentColor = colors[0];
var currentBrushSize = brushSizes[1];
var currentEraserSize = 50;
var currentStickerSize = 1.2;
var currentTool = 'brush';
var previousTool = null;
var isPainting = false;
var lastX, lastY;
var selectedColorButton = null;
// Keep track of actions for undo functionality
var designHistory = [];
// Initialize empty savedEggs array
var savedEggs = [];
// Basket already created earlier
// Create main egg
var easterEgg = new EasterEgg();
easterEgg.x = 2048 / 2;
easterEgg.y = 2732 / 2 - 200;
game.addChild(easterEgg);
// Create UI components
// Tool panel
var toolPanel = LK.getAsset('toolPanel', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 5,
y: 2732 - 100 // Moved up by 20 units
});
game.addChild(toolPanel);
// Color panel
var colorPanel = LK.getAsset('colorPanel', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 - 345 // Moved down by 5 units
});
game.addChild(colorPanel);
// Add color buttons
var colorButtons = [];
for (var i = 0; i < colors.length; i++) {
var colorButton = new ColorButton(colors[i]);
// Position in two rows (10 in first row, 10 in second row)
if (i < 10) {
// First row
colorButton.x = i * 130 + 160; // Changed spacing from 145 to 130, moved left by 10 units
colorButton.y = 2732 - 410; // First row - moved up by 10 units
} else {
// Second row
colorButton.x = (i - 10) * 130 + 160; // Changed spacing from 145 to 130, moved left by 10 units
colorButton.y = 2732 - 280; // Second row
}
game.addChild(colorButton);
colorButtons.push(colorButton);
// Scale up by 2x
tween(colorButton, {
scaleX: 2,
scaleY: 2
}, {
duration: 300
});
// Add click handler
(function (color, button) {
colorButton.down = function () {
tween(colorButton, {
scaleX: 1.8,
scaleY: 1.8
}, {
duration: 100
});
currentColor = color;
};
colorButton.up = function () {
tween(colorButton, {
scaleX: 2,
scaleY: 2
}, {
duration: 100
});
// Stop any animations on previously selected button
if (selectedColorButton) {
tween.stop(selectedColorButton);
tween(selectedColorButton, {
scaleX: 2,
scaleY: 2
}, {
duration: 100
});
}
// Set new selected button
selectedColorButton = button;
// Start pulsing animation
function pulseButton() {
tween(selectedColorButton, {
scaleX: 2.2,
scaleY: 2.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(selectedColorButton, {
scaleX: 1.8,
scaleY: 1.8
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: pulseButton
});
}
});
}
// Start the pulsing animation
pulseButton();
};
})(colors[i], colorButton);
}
// Create tool buttons
// Calculate button width including scale factor
var buttonWidth = 120 * 2; // 120px width * 2 scale
var buttonSpacing = 25; // 25 units apart
var startX = 300; // Starting X position
// Create tool buttons
var brushButton = new Button("Brush", 0x6495ED);
brushButton.x = startX - 75; // Moved left by 25 more units
brushButton.y = 2732 - 100; // Moved up by 20 units
game.addChild(brushButton);
tween(brushButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 300
});
brushButton.down = function () {
tween(brushButton, {
scaleX: 1.98,
scaleY: 1.8
}, {
duration: 100
});
};
brushButton.up = function () {
tween(brushButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// Hide any previous tool's sliders first
eraserSizeSlider.visible = false;
eraserSizeLabel.visible = false;
// Show size slider when brush tool is selected
sizeSlider.visible = true;
sizeLabel.visible = true;
// Change label text to "Brush Size" when brush tool is selected
sizeLabel.setText("Brush Size");
// Update slider track color to match button
sizeSlider.trackColor = 0x6495ED; // Match brush button color
sizeSlider.track.tint = 0x6495ED;
// Store previous tool and set current tool to brush
previousTool = currentTool;
currentTool = 'brush';
// Stop any animations on buttons
tween.stop(brushButton);
tween.stop(stickerStarButton);
tween.stop(stickerHeartButton);
tween.stop(eraserButton);
tween.stop(rotateLeftButton);
tween.stop(rotateRightButton);
tween.stop(saveButton);
tween.stop(clearButton);
// Reset all buttons to normal size
tween(stickerStarButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(stickerHeartButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(eraserButton, {
scaleX: 2.2,
scaleY: 3.1
}, {
duration: 100
});
tween(rotateLeftButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(rotateRightButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(saveButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(clearButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// Start pulsing animation for brush button
function pulseBrushButton() {
tween(brushButton, {
scaleX: 2.4,
scaleY: 2.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(brushButton, {
scaleX: 2.0,
scaleY: 1.8
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: pulseBrushButton
});
}
});
}
// Start the pulsing animation
pulseBrushButton();
};
var stickerStarButton = new Button("Star", 0xFFD700);
stickerStarButton.x = startX + (buttonWidth + buttonSpacing) * 1 - 75; // Moved left by 25 more units
stickerStarButton.y = 2732 - 100; // Moved up by 20 units
game.addChild(stickerStarButton);
// Set background to gold color
stickerStarButton.children[0].tint = 0xFFD700; // Gold color
tween(stickerStarButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 300
});
stickerStarButton.down = function () {
tween(stickerStarButton, {
scaleX: 1.98,
scaleY: 1.8
}, {
duration: 100
});
};
stickerStarButton.up = function () {
tween(stickerStarButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// Store previous tool and set current tool to star
previousTool = currentTool;
currentTool = 'star';
// First hide any previously visible sliders
eraserSizeSlider.visible = false;
eraserSizeLabel.visible = false;
// Show size slider for star (not toggle)
sizeSlider.visible = true;
sizeLabel.visible = true;
// Change label text to "Sticker Size" when star tool is selected
sizeLabel.setText("Sticker Size");
// Update slider track color to match button
sizeSlider.trackColor = 0xFFD700; // Gold color to match button
sizeSlider.track.tint = 0xFFD700;
// Stop any animations on buttons
tween.stop(brushButton);
tween.stop(stickerStarButton);
tween.stop(stickerHeartButton);
tween.stop(eraserButton);
tween.stop(rotateLeftButton);
tween.stop(rotateRightButton);
tween.stop(saveButton);
tween.stop(clearButton);
// Reset all buttons to normal size
tween(brushButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(stickerHeartButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(eraserButton, {
scaleX: 2.2,
scaleY: 3.1
}, {
duration: 100
});
tween(rotateLeftButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(rotateRightButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(saveButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(clearButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// Start pulsing animation for star button
function pulseStarButton() {
tween(stickerStarButton, {
scaleX: 2.4,
scaleY: 2.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(stickerStarButton, {
scaleX: 2.0,
scaleY: 1.8
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: pulseStarButton
});
}
});
}
// Start the pulsing animation
pulseStarButton();
};
var stickerHeartButton = new Button("Heart", 0xFF0000);
stickerHeartButton.x = startX + (buttonWidth + buttonSpacing) * 2 - 75; // Moved left by 25 more units
stickerHeartButton.y = 2732 - 100; // Moved up by 20 units
game.addChild(stickerHeartButton);
tween(stickerHeartButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 300
});
stickerHeartButton.down = function () {
tween(stickerHeartButton, {
scaleX: 1.98,
scaleY: 1.8
}, {
duration: 100
});
};
stickerHeartButton.up = function () {
tween(stickerHeartButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// Store previous tool and set current tool to heart
previousTool = currentTool;
currentTool = 'heart';
// First hide any previously visible sliders
eraserSizeSlider.visible = false;
eraserSizeLabel.visible = false;
// Show size slider for heart (not toggle)
sizeSlider.visible = true;
// Update slider track color to match button
sizeSlider.trackColor = 0xFF0000; // Red color to match button
sizeSlider.track.tint = 0xFF0000;
// Keep handle white for better visibility
// Stop any animations on buttons
tween.stop(brushButton);
tween.stop(stickerStarButton);
tween.stop(stickerHeartButton);
tween.stop(eraserButton);
tween.stop(rotateLeftButton);
tween.stop(rotateRightButton);
tween.stop(saveButton);
tween.stop(clearButton);
// Reset all buttons to normal size
tween(brushButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(stickerStarButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(eraserButton, {
scaleX: 2.2,
scaleY: 3.1
}, {
duration: 100
});
tween(rotateLeftButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(rotateRightButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(saveButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(clearButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// Start pulsing animation for heart button
function pulseHeartButton() {
tween(stickerHeartButton, {
scaleX: 2.4,
scaleY: 2.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(stickerHeartButton, {
scaleX: 2.0,
scaleY: 1.8
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: pulseHeartButton
});
}
});
}
// Start the pulsing animation
pulseHeartButton();
};
var rotateLeftButton = new Button("< Rotate", 0x9370DB);
rotateLeftButton.x = startX + (buttonWidth + buttonSpacing) * 3 - 75; // Moved left by 25 more units
rotateLeftButton.y = 2732 - 100; // Moved up by 20 units
game.addChild(rotateLeftButton);
tween(rotateLeftButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 300
});
rotateLeftButton.down = function () {
tween(rotateLeftButton, {
scaleX: 1.98,
scaleY: 1.8
}, {
duration: 100
});
};
rotateLeftButton.up = function () {
tween(rotateLeftButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// Hide any open sliders
sizeSlider.visible = false;
eraserSizeSlider.visible = false;
eraserSizeLabel.visible = false;
// Store previous tool before rotation
previousTool = currentTool;
easterEgg.rotate(-Math.PI / 8);
};
// Add a thin grey vertical divider between rotate buttons
var divider = LK.getAsset('buttonBg', {
anchorX: 0.5,
anchorY: 0.5,
x: startX + (buttonWidth + buttonSpacing) * 3.5 - 75,
// Position between the two rotate buttons
y: 2732 - 100,
// Same Y as buttons
scaleX: 0.05,
// Make it thin
scaleY: 2 // Same height as buttons
});
divider.tint = 0xe6e6fa; // Light lavender color
game.addChild(divider);
var rotateRightButton = new Button("Rotate >", 0x9370DB);
rotateRightButton.x = startX + (buttonWidth + buttonSpacing) * 4 - 75; // Moved left by 25 more units
rotateRightButton.y = 2732 - 100; // Moved up by 20 units
game.addChild(rotateRightButton);
tween(rotateRightButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 300
});
rotateRightButton.down = function () {
tween(rotateRightButton, {
scaleX: 1.98,
scaleY: 1.8
}, {
duration: 100
});
};
rotateRightButton.up = function () {
tween(rotateRightButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// Hide any open sliders
sizeSlider.visible = false;
eraserSizeSlider.visible = false;
eraserSizeLabel.visible = false;
// Store previous tool before rotation
previousTool = currentTool;
easterEgg.rotate(Math.PI / 8);
};
var saveButton = new Button("Undo", 0x8B4513);
saveButton.x = startX + (buttonWidth + buttonSpacing) * 5 - 75; // Moved left by 25 more units
saveButton.y = 2732 - 100; // Moved up by 20 units
game.addChild(saveButton);
tween(saveButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 300
});
saveButton.down = function () {
tween(saveButton, {
scaleX: 1.98,
scaleY: 1.8
}, {
duration: 100
});
// Start continuous undo functionality
var performUndo = function performUndo() {
if (designHistory.length > 0) {
var lastDesign = designHistory.pop();
// Handle clear operation undo (restore all elements that were cleared)
if (lastDesign.clearOperation) {
// First clear any current elements to avoid duplicates
easterEgg.clearDesigns();
// Add back all elements that were cleared
for (var i = 0; i < lastDesign.elements.length; i++) {
easterEgg.designContainer.addChild(lastDesign.elements[i]);
}
LK.getSound('saveSound').play();
}
// Handle erased element undo (add back erased element)
else if (lastDesign.erased) {
easterEgg.designContainer.addChildAt(lastDesign.element, lastDesign.index);
LK.getSound('saveSound').play();
}
// Handle regular element undo (remove added element)
else if (easterEgg.designContainer && easterEgg.designContainer.children.length > 0) {
// Check if the element is still at the expected index
if (easterEgg.designContainer.children[lastDesign.index] === lastDesign.element) {
easterEgg.designContainer.removeChild(lastDesign.element);
} else {
// If not at expected index, find and remove it by reference
for (var i = 0; i < easterEgg.designContainer.children.length; i++) {
if (easterEgg.designContainer.children[i] === lastDesign.element) {
easterEgg.designContainer.removeChild(lastDesign.element);
break;
}
}
}
LK.getSound('saveSound').play();
}
}
};
// Perform first undo immediately
performUndo();
// Setup interval for continuous undo while button is pressed
saveButton.undoInterval = LK.setInterval(function () {
performUndo();
}, 150); // Undo every 150ms while pressed (2x faster)
};
saveButton.up = function () {
tween(saveButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// Hide any previous tool's sliders first
sizeSlider.visible = false;
eraserSizeSlider.visible = false;
eraserSizeLabel.visible = false;
// Stop continuous undo when releasing the button
if (saveButton.undoInterval) {
LK.clearInterval(saveButton.undoInterval);
saveButton.undoInterval = null;
}
// Deactivate previous tool and activate save tool
if (currentTool !== 'save') {
var _pulseSaveButton = function pulseSaveButton() {
tween(saveButton, {
scaleX: 2.4,
scaleY: 2.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(saveButton, {
scaleX: 2.0,
scaleY: 1.8
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: _pulseSaveButton
});
}
});
}; // Start the pulsing animation
// Stop any animations on buttons
tween.stop(brushButton);
tween.stop(stickerStarButton);
tween.stop(stickerHeartButton);
tween.stop(eraserButton);
tween.stop(rotateLeftButton);
tween.stop(rotateRightButton);
tween.stop(saveButton);
tween.stop(clearButton);
// Reset all buttons to normal size
tween(brushButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(stickerStarButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(stickerHeartButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(eraserButton, {
scaleX: 2.2,
scaleY: 3.1
}, {
duration: 100
});
tween(rotateLeftButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(rotateRightButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(clearButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// Store previous tool and set current tool to save
previousTool = currentTool;
currentTool = 'save';
// Start pulsing animation for save button
_pulseSaveButton();
}
};
var eraserButton = new Button("Eraser", 0x808080);
eraserButton.x = colorPanel.x + colorPanel.width / 2 - 145; // Moved right by 100 units
eraserButton.y = colorPanel.y - colorPanel.height / 2 + 139; // Moved down to match all colors button
game.addChild(eraserButton);
tween(eraserButton, {
scaleX: 2.2,
scaleY: 3.1
}, {
duration: 300
});
eraserButton.down = function () {
tween(eraserButton, {
scaleX: 1.98,
scaleY: 1.8
}, {
duration: 100
});
};
eraserButton.up = function () {
tween(eraserButton, {
scaleX: 2.2,
scaleY: 3.1
}, {
duration: 100
});
// Toggle eraser mode
if (currentTool === 'eraser') {
var _pulseBrushButton = function pulseBrushButton() {
tween(brushButton, {
scaleX: 2.4,
scaleY: 2.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(brushButton, {
scaleX: 2.0,
scaleY: 1.8
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: _pulseBrushButton
});
}
});
};
// Store previous tool and switch back to brush
previousTool = currentTool;
currentTool = 'brush';
// Stop animation on eraser button
tween.stop(eraserButton);
tween(eraserButton, {
scaleX: 2.2,
scaleY: 3.1
}, {
duration: 100
});
// Hide eraser size slider
eraserSizeSlider.visible = false;
eraserSizeLabel.visible = false;
// Start pulsing animation for brush button
_pulseBrushButton();
} else {
var _pulseEraserButton = function pulseEraserButton() {
tween(eraserButton, {
scaleX: 2.4,
scaleY: 3.3
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(eraserButton, {
scaleX: 2.0,
scaleY: 2.9
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: _pulseEraserButton
});
}
});
};
// Store previous tool and switch to eraser mode
previousTool = currentTool;
currentTool = 'eraser';
// Stop animations on all other buttons
tween.stop(brushButton);
tween.stop(stickerStarButton);
tween.stop(stickerHeartButton);
tween.stop(rotateLeftButton);
tween.stop(rotateRightButton);
tween.stop(clearButton);
// Reset all buttons to normal size
tween(brushButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(stickerStarButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(stickerHeartButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(rotateLeftButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(rotateRightButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(clearButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// First hide any previously visible sliders
sizeSlider.visible = false;
// Show eraser size slider
eraserSizeSlider.visible = true;
eraserSizeLabel.visible = true;
// Start pulsing animation for eraser button
_pulseEraserButton();
}
};
// Add color palette button
var allColorButton = new Button("All Colors", 0x9370DB);
allColorButton.x = colorPanel.x + colorPanel.width / 2 - 415; // Position it - moved left by 100 units (from -315 to -415)
allColorButton.y = colorPanel.y - colorPanel.height / 2 + 139; // Moved down by 4 units (from 135 to 139)
game.addChild(allColorButton);
tween(allColorButton, {
scaleX: 2.2,
scaleY: 3.1
}, {
duration: 300
});
// Apply rainbow gradient to all colors button
var btnBackground = allColorButton.children[0];
var rainbowColors = [0xFF0000, 0xFF7F00, 0xFFFF00, 0x00FF00, 0x0000FF, 0x4B0082, 0x9400D3];
var colorIndex = 0;
var duration = 3000; // 3 seconds for full rainbow cycle
// Function to cycle through rainbow colors
function cycleRainbowColors() {
tween(btnBackground, {
tint: rainbowColors[colorIndex]
}, {
duration: duration / rainbowColors.length,
onFinish: function onFinish() {
colorIndex = (colorIndex + 1) % rainbowColors.length;
cycleRainbowColors();
}
});
}
// Start the rainbow cycle
cycleRainbowColors();
allColorButton.down = function () {
tween(allColorButton, {
scaleX: 1.98,
scaleY: 1.8
}, {
duration: 100
});
};
allColorButton.up = function () {
// Reset to normal size first
tween(allColorButton, {
scaleX: 2.2,
scaleY: 3.1
}, {
duration: 100
});
// Toggle the full color palette
colorPalette.visible = !colorPalette.visible;
// Update selector position to match current selected color
if (colorPalette.visible) {
colorPalette.updateSelector(currentColor);
}
};
var clearButton = new Button("Clear", 0x444444);
clearButton.x = startX + (buttonWidth + buttonSpacing) * 6 - 75; // Moved next to save button
clearButton.y = 2732 - 100; // Moved up by 20 units
game.addChild(clearButton);
tween(clearButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 300
});
clearButton.down = function () {
tween(clearButton, {
scaleX: 1.98,
scaleY: 1.8
}, {
duration: 100
});
};
clearButton.up = function () {
tween(clearButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// Hide any open sliders
sizeSlider.visible = false;
eraserSizeSlider.visible = false;
eraserSizeLabel.visible = false;
// Store previous tool before clearing
previousTool = currentTool;
// Save the current design state for potential undo
if (easterEgg.designContainer && easterEgg.designContainer.children.length > 0) {
// Create a special history entry for the clear operation
designHistory.push({
clearOperation: true,
elements: easterEgg.designContainer.children.slice() // Make a copy of all elements
});
}
easterEgg.clearDesigns();
LK.getSound('clearSound').play();
};
// Function to toggle eraser tool
function toggleEraserThicknessSlider(visible) {
// Set eraser as current tool when enabled
if (visible) {
currentTool = 'eraser';
}
}
// Create basket display
var basket = LK.getAsset('basket', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 - 525 // Moved up by 25 units (from 500 to 525)
});
game.addChildAt(basket, 0); // Add at index 0 to ensure it's behind the egg
// Bring the easterEgg to the front to ensure proper display order
game.removeChild(easterEgg);
game.addChild(easterEgg);
// Title text
var titleText = new Text2("Easter Egg Artist", {
size: 100,
fill: 0x8B4513 // Dark brown
});
titleText.anchor.set(0.5, 0);
titleText.x = 2048 / 2;
titleText.y = 50;
game.addChild(titleText);
// Score display - hidden but kept in code for reference
var scoreText = new Text2("Eggs: 0", {
size: 60,
fill: 0x4B0082 // Indigo
});
scoreText.anchor.set(0, 0);
scoreText.x = 120;
scoreText.y = 120;
scoreText.visible = false; // Hide the score text
// Function to display saved eggs (placeholder for new implementation)
function displaySavedEggs() {
// Remove any existing displayed eggs
for (var i = game.children.length - 1; i >= 0; i--) {
if (game.children[i].isCompletedEgg) {
game.removeChild(game.children[i]);
}
}
// Display saved eggs (will be reimplemented)
for (var i = 0; i < savedEggs.length; i++) {
var eggData = savedEggs[i];
var displayedEgg = new CompletedEgg(eggData.color);
displayedEgg.x = eggData.x;
displayedEgg.y = eggData.y;
displayedEgg.isCompletedEgg = true;
game.addChild(displayedEgg);
}
}
// Display any saved eggs
displaySavedEggs();
// Game event handlers
game.down = function (x, y) {
if (y < 2732 - 350) {
isPainting = true;
lastX = x;
lastY = y;
if (currentTool === 'brush') {
var brushStroke = new BrushStroke(currentColor, currentBrushSize);
easterEgg.addDesign(x, y, brushStroke);
LK.getSound('brushSound').play();
} else if (currentTool === 'star' || currentTool === 'heart') {
var size = currentStickerSize;
var sticker = new Sticker(currentTool, size);
easterEgg.addDesign(x, y, sticker);
LK.getSound('stickerSound').play();
} else if (currentTool === 'eraser') {
// Create a visual eraser element but don't actually add it to the design
var eraser = new Eraser(eraserSizeSlider.value);
// Store reference to enable updating size from slider
game.eraser = eraser;
// Convert to egg's local coordinates for hit testing
var eggLocalPosition = easterEgg.toLocal({
x: x,
y: y
}, game);
// Check if point is inside egg boundary
var eggBase = easterEgg.children[0]; // The eggBase is the first child
var eggWidth = eggBase.width / 2;
var eggHeight = eggBase.height / 2;
var dx = eggLocalPosition.x;
var dy = eggLocalPosition.y;
var isInEgg = dx * dx / (eggWidth * eggWidth) + dy * dy / (eggHeight * eggHeight) <= 1;
if (isInEgg && easterEgg.designContainer && easterEgg.designContainer.children.length > 0) {
// Find and remove elements near the eraser position
for (var i = easterEgg.designContainer.children.length - 1; i >= 0; i--) {
var element = easterEgg.designContainer.children[i];
var distance = Math.sqrt(Math.pow(element.x - eggLocalPosition.x, 2) + Math.pow(element.y - eggLocalPosition.y, 2));
// If element is within eraser size, remove it
if (distance < eraserSizeSlider.value / 2) {
// Save the removed element to history for potential undo
designHistory.push({
element: element,
index: i,
erased: true // Mark as erased rather than added
});
easterEgg.designContainer.removeChild(element);
LK.getSound('brushSound').play();
break; // Remove one element at a time for better control
}
}
}
}
}
};
game.move = function (x, y) {
if (isPainting && (currentTool === 'brush' || currentTool === 'eraser')) {
// Calculate distance between last point and current point
var dx = x - lastX;
var dy = y - lastY;
var distance = Math.sqrt(dx * dx + dy * dy);
// Get current size based on tool
var currentSize = currentTool === 'brush' ? currentBrushSize : currentEraserSize;
// Get current color based on tool
var strokeColor = currentTool === 'brush' ? currentColor : 0xFFFFFF;
// Play brush sound occasionally while using eraser
if (currentTool === 'eraser' && Math.random() < 0.05) {
LK.getSound('brushSound').play();
}
// If distance is greater than half the size, add intermediate points
if (distance > currentSize / 2) {
var steps = Math.ceil(distance / (currentSize / 2));
for (var i = 1; i <= steps; i++) {
var pointX = lastX + dx * i / steps;
var pointY = lastY + dy * i / steps;
if (currentTool === 'eraser') {
// Calculate egg local position for eraser
var eggLocalPosition = easterEgg.toLocal({
x: pointX,
y: pointY
}, game);
// Check if point is inside egg boundary
var eggBase = easterEgg.children[0];
var eggWidth = eggBase.width / 2;
var eggHeight = eggBase.height / 2;
var localDx = eggLocalPosition.x;
var localDy = eggLocalPosition.y;
var isInEgg = localDx * localDx / (eggWidth * eggWidth) + localDy * localDy / (eggHeight * eggHeight) <= 1;
if (isInEgg && easterEgg.designContainer && easterEgg.designContainer.children.length > 0) {
// Find and remove elements near the eraser position
for (var j = easterEgg.designContainer.children.length - 1; j >= 0; j--) {
var element = easterEgg.designContainer.children[j];
var eraseDist = Math.sqrt(Math.pow(element.x - eggLocalPosition.x, 2) + Math.pow(element.y - eggLocalPosition.y, 2));
// If element is within eraser size, remove it
if (eraseDist < eraserSizeSlider.value / 2) {
// Save the removed element to history for potential undo
designHistory.push({
element: element,
index: j,
erased: true // Mark as erased rather than added
});
easterEgg.designContainer.removeChild(element);
break; // Remove one element at a time for better control
}
}
}
} else {
var stroke = new BrushStroke(strokeColor, currentSize);
easterEgg.addDesign(pointX, pointY, stroke);
}
}
} else {
if (currentTool === 'eraser') {
// Calculate egg local position for eraser
var eggLocalPosition = easterEgg.toLocal({
x: x,
y: y
}, game);
// Check if point is inside egg boundary
var eggBase = easterEgg.children[0];
var eggWidth = eggBase.width / 2;
var eggHeight = eggBase.height / 2;
var localDx = eggLocalPosition.x;
var localDy = eggLocalPosition.y;
var isInEgg = localDx * localDx / (eggWidth * eggWidth) + localDy * localDy / (eggHeight * eggHeight) <= 1;
if (isInEgg && easterEgg.designContainer && easterEgg.designContainer.children.length > 0) {
// Find and remove elements near the eraser position
for (var j = easterEgg.designContainer.children.length - 1; j >= 0; j--) {
var element = easterEgg.designContainer.children[j];
var eraseDist = Math.sqrt(Math.pow(element.x - eggLocalPosition.x, 2) + Math.pow(element.y - eggLocalPosition.y, 2));
// If element is within eraser size, remove it
if (eraseDist < eraserSizeSlider.value / 2) {
// Save the removed element to history for potential undo
designHistory.push({
element: element,
index: j,
erased: true // Mark as erased rather than added
});
easterEgg.designContainer.removeChild(element);
break; // Remove one element at a time for better control
}
}
}
} else {
var stroke = new BrushStroke(strokeColor, currentSize);
easterEgg.addDesign(x, y, stroke);
}
}
lastX = x;
lastY = y;
}
};
game.up = function () {
isPainting = false;
};
// Update function
game.update = function () {
// Update score display
scoreText.setText("Eggs: " + LK.getScore());
};
// Create and add the full color palette
var colorPalette = new ColorPalette();
colorPalette.x = 2048 / 2;
colorPalette.y = 2732 / 2 - 150; // Position at center, aligned with the egg, moved down by 50 units
game.addChild(colorPalette);
// Set up color selection callback
colorPalette.onColorSelected = function (color) {
currentColor = color;
// Stop any animations on previously selected button
if (selectedColorButton) {
tween.stop(selectedColorButton);
tween(selectedColorButton, {
scaleX: 2,
scaleY: 2
}, {
duration: 100
});
}
// Find button with matching color and set as selected
var _loop = function _loop() {
if (colorButtons[i].color === color) {
var _pulseSelectedButton2 = function pulseSelectedButton() {
tween(selectedColorButton, {
scaleX: 2.2,
scaleY: 2.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(selectedColorButton, {
scaleX: 1.8,
scaleY: 1.8
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: _pulseSelectedButton2
});
}
});
}; // Start the pulsing animation
selectedColorButton = colorButtons[i];
// Start pulsing animation
_pulseSelectedButton2();
return 1; // break
}
};
for (var i = 0; i < colorButtons.length; i++) {
if (_loop()) {
break;
}
}
};
// Create size slider for star stickers
var sizeSlider = new Slider(0.5, 3, 1.2, 1801, 0xFFD700); // Gold color, width matches colorPanel width minus 80 units (1801)
sizeSlider.x = 2048 / 2 - 900; // Position at center of map, moved left by 900 units
sizeSlider.y = 2732 / 2 + 800; // Moved down by 800 units
sizeSlider.visible = false; // Hidden by default
game.addChild(sizeSlider);
// Add label above slider
var sizeLabel = new Text2("Sticker Size", {
size: 80,
fill: 0x000000 // Black color
});
sizeLabel.anchor.set(0.5, 0.5);
sizeLabel.x = sizeSlider.x + 150;
sizeLabel.y = sizeSlider.y - 95; // Moved up by 25 units
sizeLabel.visible = false;
game.addChild(sizeLabel);
// Create eraser size slider
var eraserSizeSlider = new Slider(20, 100, 50, 1801, 0x444444); // Dark grey color to match clear button, width matches colorPanel width minus 80 units (1801)
eraserSizeSlider.x = 2048 / 2 - 900; // Position at center of map, moved left by 900 units
eraserSizeSlider.y = 2732 / 2 + 800; // Moved down to same position as star and heart slider
eraserSizeSlider.visible = false; // Hidden by default
game.addChild(eraserSizeSlider);
// Add label for eraser size slider
var eraserSizeLabel = new Text2("Eraser Size", {
size: 80,
fill: 0x000000 // Black color
});
eraserSizeLabel.anchor.set(0.5, 0.5);
eraserSizeLabel.x = eraserSizeSlider.x + 150;
eraserSizeLabel.y = eraserSizeSlider.y - 95; // Moved up by 25 units
eraserSizeLabel.visible = false;
game.addChild(eraserSizeLabel);
// Update brush size/sticker size when slider value changes
sizeSlider.onValueChanged = function (value) {
// Update brush size if brush tool is selected
if (currentTool === 'brush') {
currentBrushSize = value * 20; // Scale value to appropriate brush size
}
// Update sticker size for star/heart tools
else if (currentTool === 'star' || currentTool === 'heart') {
currentStickerSize = value;
}
};
// Update eraser size when eraser slider value changes
eraserSizeSlider.onValueChanged = function (value) {
// Update eraser size for eraser tool
currentEraserSize = value;
// Update any active eraser visual if it exists
if (currentTool === 'eraser' && game.eraser) {
var eraserVisual = game.eraser.children[0];
eraserVisual.scaleX = value / 30;
eraserVisual.scaleY = value / 30;
}
};
// Make label visible when slider is visible
game.update = function () {
// Update score display
scoreText.setText("Eggs: " + LK.getScore());
// Update size label visibility to match slider
sizeLabel.visible = sizeSlider.visible;
// Update eraser size label visibility to match slider
eraserSizeLabel.visible = eraserSizeSlider.visible;
};
// Start background music
LK.playMusic('easterMusic', {
fade: {
start: 0,
end: 0.2,
duration: 1000
}
});
// Initialize first color button as selected with animation
if (colorButtons.length > 0) {
var _pulseSelectedButton = function pulseSelectedButton() {
tween(selectedColorButton, {
scaleX: 2.2,
scaleY: 2.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(selectedColorButton, {
scaleX: 1.8,
scaleY: 1.8
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: _pulseSelectedButton
});
}
});
}; // Start the initial pulsing animation
selectedColorButton = colorButtons[0];
// Start pulsing animation for first color button
_pulseSelectedButton();
}
// Add watermark to the game with forced persistence
var watermark = new Watermark("@jzubora", 0.35);
game.addChild(watermark);
// This interval ensures the watermark always exists, regenerating it if removed
LK.setInterval(function () {
// Check if watermark still exists in the game
var watermarkExists = false;
for (var i = 0; i < game.children.length; i++) {
if (game.children[i] === watermark) {
watermarkExists = true;
break;
}
}
// If watermark doesn't exist, recreate it
if (!watermarkExists) {
watermark = new Watermark("@jzubora", 0.35);
game.addChild(watermark);
// Restart the flashing animation
flashWatermark();
}
}, 1000); // Check every second
// Add flashing animation to watermark
function flashWatermark() {
// Flash watermark by alternating opacity
tween(watermark, {
alpha: 0.1
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(watermark, {
alpha: 0.8
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: flashWatermark
});
}
});
}
// Start watermark flashing animation
flashWatermark(); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var BrushStroke = Container.expand(function (color, size) {
var self = Container.call(this);
var stroke = self.attachAsset('brushStroke', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: size / 30,
scaleY: size / 30
});
stroke.tint = color;
return self;
});
var Button = Container.expand(function (label, color) {
var self = Container.call(this);
var background = self.attachAsset('buttonBg', {
anchorX: 0.5,
anchorY: 0.5
});
var text = new Text2(label, {
size: 30,
fill: 0xFFFFFF
});
text.anchor.set(0.5, 0.5);
self.addChild(text);
if (color !== undefined) {
background.tint = color;
}
self.down = function () {
tween(background, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100
});
};
self.up = function () {
tween(background, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
};
return self;
});
var ColorButton = Container.expand(function (color) {
var self = Container.call(this);
var button = self.attachAsset('colorButton', {
anchorX: 0.5,
anchorY: 0.5
});
button.tint = color;
self.color = color;
self.down = function () {
tween(button, {
scaleX: 0.9,
scaleY: 0.9
}, {
duration: 100
});
};
self.up = function () {
tween(button, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
};
return self;
});
var ColorPalette = Container.expand(function () {
var self = Container.call(this);
var background = LK.getAsset('colorPanel', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1881 / 1880,
// Set to exact size 1881
scaleY: 1899 / 277 // Set to exact size 1899
});
self.addChild(background);
var colorButtons = [];
// Generate 256 color gradient palette
var paletteColors = [];
var buttonSize = 90; // Increased from 30 to 90 (3x larger)
var spacing = 12; // Increased from 4 to 12 (3x larger)
var columns = 16;
var rows = 16;
// Generate rainbow gradient colors for the full 256 color palette
for (var i = 0; i < 256; i++) {
var hue = i / 256;
var r, g, b;
// Convert HSV to RGB (simplified rainbow gradient)
if (hue < 1 / 6) {
r = 1;
g = hue * 6;
b = 0;
} else if (hue < 2 / 6) {
r = (2 / 6 - hue) * 6;
g = 1;
b = 0;
} else if (hue < 3 / 6) {
r = 0;
g = 1;
b = (hue - 2 / 6) * 6;
} else if (hue < 4 / 6) {
r = 0;
g = (4 / 6 - hue) * 6;
b = 1;
} else if (hue < 5 / 6) {
r = (hue - 4 / 6) * 6;
b = 1;
g = 0;
} else {
r = 1;
g = 0;
b = (1 - hue) * 6;
}
// Convert to 0-255 range
var red = Math.floor(r * 255);
var green = Math.floor(g * 255);
var blue = Math.floor(b * 255);
var color = red << 16 | green << 8 | blue;
paletteColors.push(color);
}
for (var i = 0; i < paletteColors.length; i++) {
var row = Math.floor(i / columns);
var col = i % columns;
var colorBtn = new ColorButton(paletteColors[i]);
colorBtn.x = col * (buttonSize + spacing) - (columns - 1) * (buttonSize + spacing) / 2;
colorBtn.y = row * (buttonSize + spacing) - (rows - 1) * (buttonSize + spacing) / 2;
colorBtn.scaleX = 4.5; // Increased from 1.5 to 4.5 (3x larger)
colorBtn.scaleY = 4.5; // Increased from 1.5 to 4.5 (3x larger)
self.addChild(colorBtn);
// Create a closure to capture the current color
(function (color, btn) {
btn.down = function () {
currentColor = color;
self.visible = false;
// Notify the game that a color was selected
if (self.onColorSelected) {
self.onColorSelected(color);
}
};
})(paletteColors[i], colorBtn);
colorButtons.push(colorBtn);
}
// Add selector ring
var selector = LK.getAsset('brushStroke', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 7.5,
// Increased from 2.5 to 7.5 (3x larger)
scaleY: 7.5 // Increased from 2.5 to 7.5 (3x larger)
});
selector.tint = 0xFFFFFF;
selector.alpha = 0.7;
self.addChild(selector);
// Set selector initial position
selector.x = colorButtons[0].x;
selector.y = colorButtons[0].y;
// Hide palette initially
self.visible = false;
// Method to update selector position
self.updateSelector = function (color) {
for (var i = 0; i < paletteColors.length; i++) {
if (paletteColors[i] === color) {
selector.x = colorButtons[i].x;
selector.y = colorButtons[i].y;
break;
}
}
};
return self;
});
var CompletedEgg = Container.expand(function (baseColor) {
var self = Container.call(this);
var eggGraphic = self.attachAsset('completedEgg', {
anchorX: 0.5,
anchorY: 0.5
});
eggGraphic.tint = baseColor || 0xFFFFFF;
// Add some random decoration to make each egg look unique
for (var i = 0; i < 5; i++) {
var glitter = self.attachAsset('glitter', {
anchorX: 0.5,
anchorY: 0.5,
x: (Math.random() - 0.5) * 80,
y: (Math.random() - 0.5) * 120
});
glitter.tint = 0xFFD700 + Math.floor(Math.random() * 0x555555);
}
return self;
});
var EasterEgg = Container.expand(function () {
var self = Container.call(this);
var eggBase = self.attachAsset('eggBase', {
anchorX: 0.5,
anchorY: 0.5
});
var designContainer = new Container();
self.designContainer = designContainer; // Make accessible outside
self.addChild(designContainer);
self.addDesign = function (x, y, designElement) {
var localPosition = designContainer.toLocal({
x: x,
y: y
}, game);
// Check if the point is within the bounds of the eggBase
// Convert to egg's local coordinates for hit testing
var eggLocalPosition = self.toLocal({
x: x,
y: y
}, game);
// Calculate distance from center of egg
var dx = eggLocalPosition.x;
var dy = eggLocalPosition.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Check if point is inside the egg (ellipse)
// Using the egg's dimensions to determine the ellipse bounds
var eggWidth = eggBase.width / 2;
var eggHeight = eggBase.height / 2;
// Formula for point in ellipse: (x/a)² + (y/b)² <= 1
// where a is half-width and b is half-height
var isInEgg = dx * dx / (eggWidth * eggWidth) + dy * dy / (eggHeight * eggHeight) <= 1;
// Only add design if point is inside the egg
if (isInEgg) {
designElement.x = localPosition.x;
designElement.y = localPosition.y;
designContainer.addChild(designElement);
// Add to design history for undo functionality
designHistory.push({
element: designElement,
index: designContainer.children.length - 1
});
}
};
self.clearDesigns = function () {
while (designContainer.children.length > 0) {
designContainer.removeChild(designContainer.children[0]);
}
};
self.rotate = function (angle) {
eggBase.rotation += angle;
designContainer.rotation += angle;
};
self.captureDesign = function () {
// In a real implementation, this would create a snapshot of the egg
// For this simplified version, we just create a new completed egg with the same tint
var completedEgg = new CompletedEgg(eggBase.tint);
return completedEgg;
};
return self;
});
var Eraser = Container.expand(function (size) {
var self = Container.call(this);
// Create a visual representation of the eraser
var eraserVisual = self.attachAsset('brushStroke', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: size / 30,
scaleY: size / 30
});
// Make it white with a border
eraserVisual.tint = 0xFFFFFF;
eraserVisual.alpha = 0.7;
return self;
});
var Slider = Container.expand(function (minVal, maxVal, defaultVal, width, color) {
var self = Container.call(this);
// Track properties
self.minValue = minVal || 0;
self.maxValue = maxVal || 100;
self.value = defaultVal || 50;
self.trackWidth = width || 300;
self.trackColor = color || 0xCCCCCC;
// Create track
var track = LK.getAsset('buttonBg', {
anchorX: 0,
anchorY: 0.5,
scaleX: self.trackWidth / 120,
scaleY: 0.3
});
track.tint = self.trackColor;
self.addChild(track);
self.track = track; // Store track reference for external access
// Create handle
var handle = LK.getAsset('colorButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.5,
scaleY: 1.5
});
handle.tint = 0xFFFFFF;
handle.x = (self.value - self.minValue) / (self.maxValue - self.minValue) * self.trackWidth;
self.addChild(handle);
self.handle = handle;
// No value label is needed
// Method definitions
// Convert value to x position
self.getXForValue = function (val) {
return (val - self.minValue) / (self.maxValue - self.minValue) * self.trackWidth;
};
// Convert x position to value
self.getValueForX = function (x) {
return self.minValue + x / self.trackWidth * (self.maxValue - self.minValue);
};
// Update handle position
self.updateHandlePosition = function () {
handle.x = self.getXForValue(self.value);
};
// Set value
self.setValue = function (val) {
self.value = Math.max(self.minValue, Math.min(self.maxValue, val));
self.updateHandlePosition();
if (self.onValueChanged) {
self.onValueChanged(self.value);
}
};
// Handle drag
self.down = function (x, y) {
self.isDragging = true;
self.setValue(self.getValueForX(x));
};
self.move = function (x, y) {
if (self.isDragging) {
self.setValue(self.getValueForX(Math.max(0, Math.min(self.trackWidth, x))));
}
};
self.up = function () {
self.isDragging = false;
};
return self;
});
var Sticker = Container.expand(function (type, scale) {
var self = Container.call(this);
var stickerAsset;
if (type === 'star') {
stickerAsset = self.attachAsset('stickerStar', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: scale * 5,
scaleY: scale * 5
});
} else if (type === 'heart') {
stickerAsset = self.attachAsset('stickerHeart', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: scale * 5,
scaleY: scale * 5
});
}
self.down = function () {
tween(stickerAsset, {
scaleX: scale * 5 * 0.9,
scaleY: scale * 5 * 0.9
}, {
duration: 100
});
};
self.up = function () {
tween(stickerAsset, {
scaleX: scale * 5,
scaleY: scale * 5
}, {
duration: 100
});
};
return self;
});
var Watermark = Container.expand(function (text, opacity) {
var self = Container.call(this);
// Set default values if not provided
self.text = text || "FRVR Easter";
self.opacity = opacity || 0.35;
// Create corner text elements
function createCornerText(x, y, rotation) {
var cornerText = new Text2(self.text, {
size: 28,
fill: 0x333333
});
cornerText.anchor.set(0.5, 0.5);
cornerText.x = x;
cornerText.y = y;
cornerText.rotation = rotation || 0;
cornerText.alpha = self.opacity;
self.addChild(cornerText);
return cornerText;
}
// Create text for each corner, avoiding top-left 100x100 area
self.topRight = createCornerText(2048 - 120, 120, Math.PI / 4);
self.bottomRight = createCornerText(2048 - 120, 2732 - 120, -Math.PI / 4);
self.bottomLeft = createCornerText(120, 2732 - 120, Math.PI / 4);
// Top left is placed with extra margin to avoid the platform menu icon
self.topLeft = createCornerText(180, 180, -Math.PI / 4);
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xAFEEEE // Light turquoise background color
});
/****
* Game Code
****/
// Define color palette - arranged in rainbow gradient
var colors = [
// Black (left)
0x000000,
// Violet group
0x9400D3,
// Violet
0x4B0082,
// Indigo
0x8A2BE2,
// Blue Violet
// Blue group
0x0000FF,
// Blue
0x000080,
// Navy Blue
0x00FFFF,
// Cyan
0x008080,
// Teal
// Green group
0x00FF00,
// Green
0x32CD32,
// Lime Green
0x808000,
// Olive
// Red group
0x800000,
// Maroon
0xA52A2A,
// Brown
0xFF0000,
// Red
0xFF7F00,
// Orange
// Yellow group
0xFFD700,
// Gold
0xFFFF00,
// Yellow
// Pink group
0xFF69B4,
// Hot Pink
// Gray
0x808080,
// White (right)
0xFFFFFF];
// Define brush sizes
var brushSizes = [10, 20, 30];
// Initialize game variables
var currentColor = colors[0];
var currentBrushSize = brushSizes[1];
var currentEraserSize = 50;
var currentStickerSize = 1.2;
var currentTool = 'brush';
var previousTool = null;
var isPainting = false;
var lastX, lastY;
var selectedColorButton = null;
// Keep track of actions for undo functionality
var designHistory = [];
// Initialize empty savedEggs array
var savedEggs = [];
// Basket already created earlier
// Create main egg
var easterEgg = new EasterEgg();
easterEgg.x = 2048 / 2;
easterEgg.y = 2732 / 2 - 200;
game.addChild(easterEgg);
// Create UI components
// Tool panel
var toolPanel = LK.getAsset('toolPanel', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2 - 5,
y: 2732 - 100 // Moved up by 20 units
});
game.addChild(toolPanel);
// Color panel
var colorPanel = LK.getAsset('colorPanel', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 - 345 // Moved down by 5 units
});
game.addChild(colorPanel);
// Add color buttons
var colorButtons = [];
for (var i = 0; i < colors.length; i++) {
var colorButton = new ColorButton(colors[i]);
// Position in two rows (10 in first row, 10 in second row)
if (i < 10) {
// First row
colorButton.x = i * 130 + 160; // Changed spacing from 145 to 130, moved left by 10 units
colorButton.y = 2732 - 410; // First row - moved up by 10 units
} else {
// Second row
colorButton.x = (i - 10) * 130 + 160; // Changed spacing from 145 to 130, moved left by 10 units
colorButton.y = 2732 - 280; // Second row
}
game.addChild(colorButton);
colorButtons.push(colorButton);
// Scale up by 2x
tween(colorButton, {
scaleX: 2,
scaleY: 2
}, {
duration: 300
});
// Add click handler
(function (color, button) {
colorButton.down = function () {
tween(colorButton, {
scaleX: 1.8,
scaleY: 1.8
}, {
duration: 100
});
currentColor = color;
};
colorButton.up = function () {
tween(colorButton, {
scaleX: 2,
scaleY: 2
}, {
duration: 100
});
// Stop any animations on previously selected button
if (selectedColorButton) {
tween.stop(selectedColorButton);
tween(selectedColorButton, {
scaleX: 2,
scaleY: 2
}, {
duration: 100
});
}
// Set new selected button
selectedColorButton = button;
// Start pulsing animation
function pulseButton() {
tween(selectedColorButton, {
scaleX: 2.2,
scaleY: 2.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(selectedColorButton, {
scaleX: 1.8,
scaleY: 1.8
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: pulseButton
});
}
});
}
// Start the pulsing animation
pulseButton();
};
})(colors[i], colorButton);
}
// Create tool buttons
// Calculate button width including scale factor
var buttonWidth = 120 * 2; // 120px width * 2 scale
var buttonSpacing = 25; // 25 units apart
var startX = 300; // Starting X position
// Create tool buttons
var brushButton = new Button("Brush", 0x6495ED);
brushButton.x = startX - 75; // Moved left by 25 more units
brushButton.y = 2732 - 100; // Moved up by 20 units
game.addChild(brushButton);
tween(brushButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 300
});
brushButton.down = function () {
tween(brushButton, {
scaleX: 1.98,
scaleY: 1.8
}, {
duration: 100
});
};
brushButton.up = function () {
tween(brushButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// Hide any previous tool's sliders first
eraserSizeSlider.visible = false;
eraserSizeLabel.visible = false;
// Show size slider when brush tool is selected
sizeSlider.visible = true;
sizeLabel.visible = true;
// Change label text to "Brush Size" when brush tool is selected
sizeLabel.setText("Brush Size");
// Update slider track color to match button
sizeSlider.trackColor = 0x6495ED; // Match brush button color
sizeSlider.track.tint = 0x6495ED;
// Store previous tool and set current tool to brush
previousTool = currentTool;
currentTool = 'brush';
// Stop any animations on buttons
tween.stop(brushButton);
tween.stop(stickerStarButton);
tween.stop(stickerHeartButton);
tween.stop(eraserButton);
tween.stop(rotateLeftButton);
tween.stop(rotateRightButton);
tween.stop(saveButton);
tween.stop(clearButton);
// Reset all buttons to normal size
tween(stickerStarButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(stickerHeartButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(eraserButton, {
scaleX: 2.2,
scaleY: 3.1
}, {
duration: 100
});
tween(rotateLeftButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(rotateRightButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(saveButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(clearButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// Start pulsing animation for brush button
function pulseBrushButton() {
tween(brushButton, {
scaleX: 2.4,
scaleY: 2.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(brushButton, {
scaleX: 2.0,
scaleY: 1.8
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: pulseBrushButton
});
}
});
}
// Start the pulsing animation
pulseBrushButton();
};
var stickerStarButton = new Button("Star", 0xFFD700);
stickerStarButton.x = startX + (buttonWidth + buttonSpacing) * 1 - 75; // Moved left by 25 more units
stickerStarButton.y = 2732 - 100; // Moved up by 20 units
game.addChild(stickerStarButton);
// Set background to gold color
stickerStarButton.children[0].tint = 0xFFD700; // Gold color
tween(stickerStarButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 300
});
stickerStarButton.down = function () {
tween(stickerStarButton, {
scaleX: 1.98,
scaleY: 1.8
}, {
duration: 100
});
};
stickerStarButton.up = function () {
tween(stickerStarButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// Store previous tool and set current tool to star
previousTool = currentTool;
currentTool = 'star';
// First hide any previously visible sliders
eraserSizeSlider.visible = false;
eraserSizeLabel.visible = false;
// Show size slider for star (not toggle)
sizeSlider.visible = true;
sizeLabel.visible = true;
// Change label text to "Sticker Size" when star tool is selected
sizeLabel.setText("Sticker Size");
// Update slider track color to match button
sizeSlider.trackColor = 0xFFD700; // Gold color to match button
sizeSlider.track.tint = 0xFFD700;
// Stop any animations on buttons
tween.stop(brushButton);
tween.stop(stickerStarButton);
tween.stop(stickerHeartButton);
tween.stop(eraserButton);
tween.stop(rotateLeftButton);
tween.stop(rotateRightButton);
tween.stop(saveButton);
tween.stop(clearButton);
// Reset all buttons to normal size
tween(brushButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(stickerHeartButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(eraserButton, {
scaleX: 2.2,
scaleY: 3.1
}, {
duration: 100
});
tween(rotateLeftButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(rotateRightButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(saveButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(clearButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// Start pulsing animation for star button
function pulseStarButton() {
tween(stickerStarButton, {
scaleX: 2.4,
scaleY: 2.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(stickerStarButton, {
scaleX: 2.0,
scaleY: 1.8
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: pulseStarButton
});
}
});
}
// Start the pulsing animation
pulseStarButton();
};
var stickerHeartButton = new Button("Heart", 0xFF0000);
stickerHeartButton.x = startX + (buttonWidth + buttonSpacing) * 2 - 75; // Moved left by 25 more units
stickerHeartButton.y = 2732 - 100; // Moved up by 20 units
game.addChild(stickerHeartButton);
tween(stickerHeartButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 300
});
stickerHeartButton.down = function () {
tween(stickerHeartButton, {
scaleX: 1.98,
scaleY: 1.8
}, {
duration: 100
});
};
stickerHeartButton.up = function () {
tween(stickerHeartButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// Store previous tool and set current tool to heart
previousTool = currentTool;
currentTool = 'heart';
// First hide any previously visible sliders
eraserSizeSlider.visible = false;
eraserSizeLabel.visible = false;
// Show size slider for heart (not toggle)
sizeSlider.visible = true;
// Update slider track color to match button
sizeSlider.trackColor = 0xFF0000; // Red color to match button
sizeSlider.track.tint = 0xFF0000;
// Keep handle white for better visibility
// Stop any animations on buttons
tween.stop(brushButton);
tween.stop(stickerStarButton);
tween.stop(stickerHeartButton);
tween.stop(eraserButton);
tween.stop(rotateLeftButton);
tween.stop(rotateRightButton);
tween.stop(saveButton);
tween.stop(clearButton);
// Reset all buttons to normal size
tween(brushButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(stickerStarButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(eraserButton, {
scaleX: 2.2,
scaleY: 3.1
}, {
duration: 100
});
tween(rotateLeftButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(rotateRightButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(saveButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(clearButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// Start pulsing animation for heart button
function pulseHeartButton() {
tween(stickerHeartButton, {
scaleX: 2.4,
scaleY: 2.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(stickerHeartButton, {
scaleX: 2.0,
scaleY: 1.8
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: pulseHeartButton
});
}
});
}
// Start the pulsing animation
pulseHeartButton();
};
var rotateLeftButton = new Button("< Rotate", 0x9370DB);
rotateLeftButton.x = startX + (buttonWidth + buttonSpacing) * 3 - 75; // Moved left by 25 more units
rotateLeftButton.y = 2732 - 100; // Moved up by 20 units
game.addChild(rotateLeftButton);
tween(rotateLeftButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 300
});
rotateLeftButton.down = function () {
tween(rotateLeftButton, {
scaleX: 1.98,
scaleY: 1.8
}, {
duration: 100
});
};
rotateLeftButton.up = function () {
tween(rotateLeftButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// Hide any open sliders
sizeSlider.visible = false;
eraserSizeSlider.visible = false;
eraserSizeLabel.visible = false;
// Store previous tool before rotation
previousTool = currentTool;
easterEgg.rotate(-Math.PI / 8);
};
// Add a thin grey vertical divider between rotate buttons
var divider = LK.getAsset('buttonBg', {
anchorX: 0.5,
anchorY: 0.5,
x: startX + (buttonWidth + buttonSpacing) * 3.5 - 75,
// Position between the two rotate buttons
y: 2732 - 100,
// Same Y as buttons
scaleX: 0.05,
// Make it thin
scaleY: 2 // Same height as buttons
});
divider.tint = 0xe6e6fa; // Light lavender color
game.addChild(divider);
var rotateRightButton = new Button("Rotate >", 0x9370DB);
rotateRightButton.x = startX + (buttonWidth + buttonSpacing) * 4 - 75; // Moved left by 25 more units
rotateRightButton.y = 2732 - 100; // Moved up by 20 units
game.addChild(rotateRightButton);
tween(rotateRightButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 300
});
rotateRightButton.down = function () {
tween(rotateRightButton, {
scaleX: 1.98,
scaleY: 1.8
}, {
duration: 100
});
};
rotateRightButton.up = function () {
tween(rotateRightButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// Hide any open sliders
sizeSlider.visible = false;
eraserSizeSlider.visible = false;
eraserSizeLabel.visible = false;
// Store previous tool before rotation
previousTool = currentTool;
easterEgg.rotate(Math.PI / 8);
};
var saveButton = new Button("Undo", 0x8B4513);
saveButton.x = startX + (buttonWidth + buttonSpacing) * 5 - 75; // Moved left by 25 more units
saveButton.y = 2732 - 100; // Moved up by 20 units
game.addChild(saveButton);
tween(saveButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 300
});
saveButton.down = function () {
tween(saveButton, {
scaleX: 1.98,
scaleY: 1.8
}, {
duration: 100
});
// Start continuous undo functionality
var performUndo = function performUndo() {
if (designHistory.length > 0) {
var lastDesign = designHistory.pop();
// Handle clear operation undo (restore all elements that were cleared)
if (lastDesign.clearOperation) {
// First clear any current elements to avoid duplicates
easterEgg.clearDesigns();
// Add back all elements that were cleared
for (var i = 0; i < lastDesign.elements.length; i++) {
easterEgg.designContainer.addChild(lastDesign.elements[i]);
}
LK.getSound('saveSound').play();
}
// Handle erased element undo (add back erased element)
else if (lastDesign.erased) {
easterEgg.designContainer.addChildAt(lastDesign.element, lastDesign.index);
LK.getSound('saveSound').play();
}
// Handle regular element undo (remove added element)
else if (easterEgg.designContainer && easterEgg.designContainer.children.length > 0) {
// Check if the element is still at the expected index
if (easterEgg.designContainer.children[lastDesign.index] === lastDesign.element) {
easterEgg.designContainer.removeChild(lastDesign.element);
} else {
// If not at expected index, find and remove it by reference
for (var i = 0; i < easterEgg.designContainer.children.length; i++) {
if (easterEgg.designContainer.children[i] === lastDesign.element) {
easterEgg.designContainer.removeChild(lastDesign.element);
break;
}
}
}
LK.getSound('saveSound').play();
}
}
};
// Perform first undo immediately
performUndo();
// Setup interval for continuous undo while button is pressed
saveButton.undoInterval = LK.setInterval(function () {
performUndo();
}, 150); // Undo every 150ms while pressed (2x faster)
};
saveButton.up = function () {
tween(saveButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// Hide any previous tool's sliders first
sizeSlider.visible = false;
eraserSizeSlider.visible = false;
eraserSizeLabel.visible = false;
// Stop continuous undo when releasing the button
if (saveButton.undoInterval) {
LK.clearInterval(saveButton.undoInterval);
saveButton.undoInterval = null;
}
// Deactivate previous tool and activate save tool
if (currentTool !== 'save') {
var _pulseSaveButton = function pulseSaveButton() {
tween(saveButton, {
scaleX: 2.4,
scaleY: 2.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(saveButton, {
scaleX: 2.0,
scaleY: 1.8
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: _pulseSaveButton
});
}
});
}; // Start the pulsing animation
// Stop any animations on buttons
tween.stop(brushButton);
tween.stop(stickerStarButton);
tween.stop(stickerHeartButton);
tween.stop(eraserButton);
tween.stop(rotateLeftButton);
tween.stop(rotateRightButton);
tween.stop(saveButton);
tween.stop(clearButton);
// Reset all buttons to normal size
tween(brushButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(stickerStarButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(stickerHeartButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(eraserButton, {
scaleX: 2.2,
scaleY: 3.1
}, {
duration: 100
});
tween(rotateLeftButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(rotateRightButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(clearButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// Store previous tool and set current tool to save
previousTool = currentTool;
currentTool = 'save';
// Start pulsing animation for save button
_pulseSaveButton();
}
};
var eraserButton = new Button("Eraser", 0x808080);
eraserButton.x = colorPanel.x + colorPanel.width / 2 - 145; // Moved right by 100 units
eraserButton.y = colorPanel.y - colorPanel.height / 2 + 139; // Moved down to match all colors button
game.addChild(eraserButton);
tween(eraserButton, {
scaleX: 2.2,
scaleY: 3.1
}, {
duration: 300
});
eraserButton.down = function () {
tween(eraserButton, {
scaleX: 1.98,
scaleY: 1.8
}, {
duration: 100
});
};
eraserButton.up = function () {
tween(eraserButton, {
scaleX: 2.2,
scaleY: 3.1
}, {
duration: 100
});
// Toggle eraser mode
if (currentTool === 'eraser') {
var _pulseBrushButton = function pulseBrushButton() {
tween(brushButton, {
scaleX: 2.4,
scaleY: 2.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(brushButton, {
scaleX: 2.0,
scaleY: 1.8
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: _pulseBrushButton
});
}
});
};
// Store previous tool and switch back to brush
previousTool = currentTool;
currentTool = 'brush';
// Stop animation on eraser button
tween.stop(eraserButton);
tween(eraserButton, {
scaleX: 2.2,
scaleY: 3.1
}, {
duration: 100
});
// Hide eraser size slider
eraserSizeSlider.visible = false;
eraserSizeLabel.visible = false;
// Start pulsing animation for brush button
_pulseBrushButton();
} else {
var _pulseEraserButton = function pulseEraserButton() {
tween(eraserButton, {
scaleX: 2.4,
scaleY: 3.3
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(eraserButton, {
scaleX: 2.0,
scaleY: 2.9
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: _pulseEraserButton
});
}
});
};
// Store previous tool and switch to eraser mode
previousTool = currentTool;
currentTool = 'eraser';
// Stop animations on all other buttons
tween.stop(brushButton);
tween.stop(stickerStarButton);
tween.stop(stickerHeartButton);
tween.stop(rotateLeftButton);
tween.stop(rotateRightButton);
tween.stop(clearButton);
// Reset all buttons to normal size
tween(brushButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(stickerStarButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(stickerHeartButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(rotateLeftButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(rotateRightButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
tween(clearButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// First hide any previously visible sliders
sizeSlider.visible = false;
// Show eraser size slider
eraserSizeSlider.visible = true;
eraserSizeLabel.visible = true;
// Start pulsing animation for eraser button
_pulseEraserButton();
}
};
// Add color palette button
var allColorButton = new Button("All Colors", 0x9370DB);
allColorButton.x = colorPanel.x + colorPanel.width / 2 - 415; // Position it - moved left by 100 units (from -315 to -415)
allColorButton.y = colorPanel.y - colorPanel.height / 2 + 139; // Moved down by 4 units (from 135 to 139)
game.addChild(allColorButton);
tween(allColorButton, {
scaleX: 2.2,
scaleY: 3.1
}, {
duration: 300
});
// Apply rainbow gradient to all colors button
var btnBackground = allColorButton.children[0];
var rainbowColors = [0xFF0000, 0xFF7F00, 0xFFFF00, 0x00FF00, 0x0000FF, 0x4B0082, 0x9400D3];
var colorIndex = 0;
var duration = 3000; // 3 seconds for full rainbow cycle
// Function to cycle through rainbow colors
function cycleRainbowColors() {
tween(btnBackground, {
tint: rainbowColors[colorIndex]
}, {
duration: duration / rainbowColors.length,
onFinish: function onFinish() {
colorIndex = (colorIndex + 1) % rainbowColors.length;
cycleRainbowColors();
}
});
}
// Start the rainbow cycle
cycleRainbowColors();
allColorButton.down = function () {
tween(allColorButton, {
scaleX: 1.98,
scaleY: 1.8
}, {
duration: 100
});
};
allColorButton.up = function () {
// Reset to normal size first
tween(allColorButton, {
scaleX: 2.2,
scaleY: 3.1
}, {
duration: 100
});
// Toggle the full color palette
colorPalette.visible = !colorPalette.visible;
// Update selector position to match current selected color
if (colorPalette.visible) {
colorPalette.updateSelector(currentColor);
}
};
var clearButton = new Button("Clear", 0x444444);
clearButton.x = startX + (buttonWidth + buttonSpacing) * 6 - 75; // Moved next to save button
clearButton.y = 2732 - 100; // Moved up by 20 units
game.addChild(clearButton);
tween(clearButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 300
});
clearButton.down = function () {
tween(clearButton, {
scaleX: 1.98,
scaleY: 1.8
}, {
duration: 100
});
};
clearButton.up = function () {
tween(clearButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// Hide any open sliders
sizeSlider.visible = false;
eraserSizeSlider.visible = false;
eraserSizeLabel.visible = false;
// Store previous tool before clearing
previousTool = currentTool;
// Save the current design state for potential undo
if (easterEgg.designContainer && easterEgg.designContainer.children.length > 0) {
// Create a special history entry for the clear operation
designHistory.push({
clearOperation: true,
elements: easterEgg.designContainer.children.slice() // Make a copy of all elements
});
}
easterEgg.clearDesigns();
LK.getSound('clearSound').play();
};
// Function to toggle eraser tool
function toggleEraserThicknessSlider(visible) {
// Set eraser as current tool when enabled
if (visible) {
currentTool = 'eraser';
}
}
// Create basket display
var basket = LK.getAsset('basket', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 - 525 // Moved up by 25 units (from 500 to 525)
});
game.addChildAt(basket, 0); // Add at index 0 to ensure it's behind the egg
// Bring the easterEgg to the front to ensure proper display order
game.removeChild(easterEgg);
game.addChild(easterEgg);
// Title text
var titleText = new Text2("Easter Egg Artist", {
size: 100,
fill: 0x8B4513 // Dark brown
});
titleText.anchor.set(0.5, 0);
titleText.x = 2048 / 2;
titleText.y = 50;
game.addChild(titleText);
// Score display - hidden but kept in code for reference
var scoreText = new Text2("Eggs: 0", {
size: 60,
fill: 0x4B0082 // Indigo
});
scoreText.anchor.set(0, 0);
scoreText.x = 120;
scoreText.y = 120;
scoreText.visible = false; // Hide the score text
// Function to display saved eggs (placeholder for new implementation)
function displaySavedEggs() {
// Remove any existing displayed eggs
for (var i = game.children.length - 1; i >= 0; i--) {
if (game.children[i].isCompletedEgg) {
game.removeChild(game.children[i]);
}
}
// Display saved eggs (will be reimplemented)
for (var i = 0; i < savedEggs.length; i++) {
var eggData = savedEggs[i];
var displayedEgg = new CompletedEgg(eggData.color);
displayedEgg.x = eggData.x;
displayedEgg.y = eggData.y;
displayedEgg.isCompletedEgg = true;
game.addChild(displayedEgg);
}
}
// Display any saved eggs
displaySavedEggs();
// Game event handlers
game.down = function (x, y) {
if (y < 2732 - 350) {
isPainting = true;
lastX = x;
lastY = y;
if (currentTool === 'brush') {
var brushStroke = new BrushStroke(currentColor, currentBrushSize);
easterEgg.addDesign(x, y, brushStroke);
LK.getSound('brushSound').play();
} else if (currentTool === 'star' || currentTool === 'heart') {
var size = currentStickerSize;
var sticker = new Sticker(currentTool, size);
easterEgg.addDesign(x, y, sticker);
LK.getSound('stickerSound').play();
} else if (currentTool === 'eraser') {
// Create a visual eraser element but don't actually add it to the design
var eraser = new Eraser(eraserSizeSlider.value);
// Store reference to enable updating size from slider
game.eraser = eraser;
// Convert to egg's local coordinates for hit testing
var eggLocalPosition = easterEgg.toLocal({
x: x,
y: y
}, game);
// Check if point is inside egg boundary
var eggBase = easterEgg.children[0]; // The eggBase is the first child
var eggWidth = eggBase.width / 2;
var eggHeight = eggBase.height / 2;
var dx = eggLocalPosition.x;
var dy = eggLocalPosition.y;
var isInEgg = dx * dx / (eggWidth * eggWidth) + dy * dy / (eggHeight * eggHeight) <= 1;
if (isInEgg && easterEgg.designContainer && easterEgg.designContainer.children.length > 0) {
// Find and remove elements near the eraser position
for (var i = easterEgg.designContainer.children.length - 1; i >= 0; i--) {
var element = easterEgg.designContainer.children[i];
var distance = Math.sqrt(Math.pow(element.x - eggLocalPosition.x, 2) + Math.pow(element.y - eggLocalPosition.y, 2));
// If element is within eraser size, remove it
if (distance < eraserSizeSlider.value / 2) {
// Save the removed element to history for potential undo
designHistory.push({
element: element,
index: i,
erased: true // Mark as erased rather than added
});
easterEgg.designContainer.removeChild(element);
LK.getSound('brushSound').play();
break; // Remove one element at a time for better control
}
}
}
}
}
};
game.move = function (x, y) {
if (isPainting && (currentTool === 'brush' || currentTool === 'eraser')) {
// Calculate distance between last point and current point
var dx = x - lastX;
var dy = y - lastY;
var distance = Math.sqrt(dx * dx + dy * dy);
// Get current size based on tool
var currentSize = currentTool === 'brush' ? currentBrushSize : currentEraserSize;
// Get current color based on tool
var strokeColor = currentTool === 'brush' ? currentColor : 0xFFFFFF;
// Play brush sound occasionally while using eraser
if (currentTool === 'eraser' && Math.random() < 0.05) {
LK.getSound('brushSound').play();
}
// If distance is greater than half the size, add intermediate points
if (distance > currentSize / 2) {
var steps = Math.ceil(distance / (currentSize / 2));
for (var i = 1; i <= steps; i++) {
var pointX = lastX + dx * i / steps;
var pointY = lastY + dy * i / steps;
if (currentTool === 'eraser') {
// Calculate egg local position for eraser
var eggLocalPosition = easterEgg.toLocal({
x: pointX,
y: pointY
}, game);
// Check if point is inside egg boundary
var eggBase = easterEgg.children[0];
var eggWidth = eggBase.width / 2;
var eggHeight = eggBase.height / 2;
var localDx = eggLocalPosition.x;
var localDy = eggLocalPosition.y;
var isInEgg = localDx * localDx / (eggWidth * eggWidth) + localDy * localDy / (eggHeight * eggHeight) <= 1;
if (isInEgg && easterEgg.designContainer && easterEgg.designContainer.children.length > 0) {
// Find and remove elements near the eraser position
for (var j = easterEgg.designContainer.children.length - 1; j >= 0; j--) {
var element = easterEgg.designContainer.children[j];
var eraseDist = Math.sqrt(Math.pow(element.x - eggLocalPosition.x, 2) + Math.pow(element.y - eggLocalPosition.y, 2));
// If element is within eraser size, remove it
if (eraseDist < eraserSizeSlider.value / 2) {
// Save the removed element to history for potential undo
designHistory.push({
element: element,
index: j,
erased: true // Mark as erased rather than added
});
easterEgg.designContainer.removeChild(element);
break; // Remove one element at a time for better control
}
}
}
} else {
var stroke = new BrushStroke(strokeColor, currentSize);
easterEgg.addDesign(pointX, pointY, stroke);
}
}
} else {
if (currentTool === 'eraser') {
// Calculate egg local position for eraser
var eggLocalPosition = easterEgg.toLocal({
x: x,
y: y
}, game);
// Check if point is inside egg boundary
var eggBase = easterEgg.children[0];
var eggWidth = eggBase.width / 2;
var eggHeight = eggBase.height / 2;
var localDx = eggLocalPosition.x;
var localDy = eggLocalPosition.y;
var isInEgg = localDx * localDx / (eggWidth * eggWidth) + localDy * localDy / (eggHeight * eggHeight) <= 1;
if (isInEgg && easterEgg.designContainer && easterEgg.designContainer.children.length > 0) {
// Find and remove elements near the eraser position
for (var j = easterEgg.designContainer.children.length - 1; j >= 0; j--) {
var element = easterEgg.designContainer.children[j];
var eraseDist = Math.sqrt(Math.pow(element.x - eggLocalPosition.x, 2) + Math.pow(element.y - eggLocalPosition.y, 2));
// If element is within eraser size, remove it
if (eraseDist < eraserSizeSlider.value / 2) {
// Save the removed element to history for potential undo
designHistory.push({
element: element,
index: j,
erased: true // Mark as erased rather than added
});
easterEgg.designContainer.removeChild(element);
break; // Remove one element at a time for better control
}
}
}
} else {
var stroke = new BrushStroke(strokeColor, currentSize);
easterEgg.addDesign(x, y, stroke);
}
}
lastX = x;
lastY = y;
}
};
game.up = function () {
isPainting = false;
};
// Update function
game.update = function () {
// Update score display
scoreText.setText("Eggs: " + LK.getScore());
};
// Create and add the full color palette
var colorPalette = new ColorPalette();
colorPalette.x = 2048 / 2;
colorPalette.y = 2732 / 2 - 150; // Position at center, aligned with the egg, moved down by 50 units
game.addChild(colorPalette);
// Set up color selection callback
colorPalette.onColorSelected = function (color) {
currentColor = color;
// Stop any animations on previously selected button
if (selectedColorButton) {
tween.stop(selectedColorButton);
tween(selectedColorButton, {
scaleX: 2,
scaleY: 2
}, {
duration: 100
});
}
// Find button with matching color and set as selected
var _loop = function _loop() {
if (colorButtons[i].color === color) {
var _pulseSelectedButton2 = function pulseSelectedButton() {
tween(selectedColorButton, {
scaleX: 2.2,
scaleY: 2.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(selectedColorButton, {
scaleX: 1.8,
scaleY: 1.8
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: _pulseSelectedButton2
});
}
});
}; // Start the pulsing animation
selectedColorButton = colorButtons[i];
// Start pulsing animation
_pulseSelectedButton2();
return 1; // break
}
};
for (var i = 0; i < colorButtons.length; i++) {
if (_loop()) {
break;
}
}
};
// Create size slider for star stickers
var sizeSlider = new Slider(0.5, 3, 1.2, 1801, 0xFFD700); // Gold color, width matches colorPanel width minus 80 units (1801)
sizeSlider.x = 2048 / 2 - 900; // Position at center of map, moved left by 900 units
sizeSlider.y = 2732 / 2 + 800; // Moved down by 800 units
sizeSlider.visible = false; // Hidden by default
game.addChild(sizeSlider);
// Add label above slider
var sizeLabel = new Text2("Sticker Size", {
size: 80,
fill: 0x000000 // Black color
});
sizeLabel.anchor.set(0.5, 0.5);
sizeLabel.x = sizeSlider.x + 150;
sizeLabel.y = sizeSlider.y - 95; // Moved up by 25 units
sizeLabel.visible = false;
game.addChild(sizeLabel);
// Create eraser size slider
var eraserSizeSlider = new Slider(20, 100, 50, 1801, 0x444444); // Dark grey color to match clear button, width matches colorPanel width minus 80 units (1801)
eraserSizeSlider.x = 2048 / 2 - 900; // Position at center of map, moved left by 900 units
eraserSizeSlider.y = 2732 / 2 + 800; // Moved down to same position as star and heart slider
eraserSizeSlider.visible = false; // Hidden by default
game.addChild(eraserSizeSlider);
// Add label for eraser size slider
var eraserSizeLabel = new Text2("Eraser Size", {
size: 80,
fill: 0x000000 // Black color
});
eraserSizeLabel.anchor.set(0.5, 0.5);
eraserSizeLabel.x = eraserSizeSlider.x + 150;
eraserSizeLabel.y = eraserSizeSlider.y - 95; // Moved up by 25 units
eraserSizeLabel.visible = false;
game.addChild(eraserSizeLabel);
// Update brush size/sticker size when slider value changes
sizeSlider.onValueChanged = function (value) {
// Update brush size if brush tool is selected
if (currentTool === 'brush') {
currentBrushSize = value * 20; // Scale value to appropriate brush size
}
// Update sticker size for star/heart tools
else if (currentTool === 'star' || currentTool === 'heart') {
currentStickerSize = value;
}
};
// Update eraser size when eraser slider value changes
eraserSizeSlider.onValueChanged = function (value) {
// Update eraser size for eraser tool
currentEraserSize = value;
// Update any active eraser visual if it exists
if (currentTool === 'eraser' && game.eraser) {
var eraserVisual = game.eraser.children[0];
eraserVisual.scaleX = value / 30;
eraserVisual.scaleY = value / 30;
}
};
// Make label visible when slider is visible
game.update = function () {
// Update score display
scoreText.setText("Eggs: " + LK.getScore());
// Update size label visibility to match slider
sizeLabel.visible = sizeSlider.visible;
// Update eraser size label visibility to match slider
eraserSizeLabel.visible = eraserSizeSlider.visible;
};
// Start background music
LK.playMusic('easterMusic', {
fade: {
start: 0,
end: 0.2,
duration: 1000
}
});
// Initialize first color button as selected with animation
if (colorButtons.length > 0) {
var _pulseSelectedButton = function pulseSelectedButton() {
tween(selectedColorButton, {
scaleX: 2.2,
scaleY: 2.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(selectedColorButton, {
scaleX: 1.8,
scaleY: 1.8
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: _pulseSelectedButton
});
}
});
}; // Start the initial pulsing animation
selectedColorButton = colorButtons[0];
// Start pulsing animation for first color button
_pulseSelectedButton();
}
// Add watermark to the game with forced persistence
var watermark = new Watermark("@jzubora", 0.35);
game.addChild(watermark);
// This interval ensures the watermark always exists, regenerating it if removed
LK.setInterval(function () {
// Check if watermark still exists in the game
var watermarkExists = false;
for (var i = 0; i < game.children.length; i++) {
if (game.children[i] === watermark) {
watermarkExists = true;
break;
}
}
// If watermark doesn't exist, recreate it
if (!watermarkExists) {
watermark = new Watermark("@jzubora", 0.35);
game.addChild(watermark);
// Restart the flashing animation
flashWatermark();
}
}, 1000); // Check every second
// Add flashing animation to watermark
function flashWatermark() {
// Flash watermark by alternating opacity
tween(watermark, {
alpha: 0.1
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(watermark, {
alpha: 0.8
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: flashWatermark
});
}
});
}
// Start watermark flashing animation
flashWatermark();