User prompt
move the eraser slider down to the star and heart slider
User prompt
If Eraser button selected then show up a slider to change the eraser size ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Swap the 'Eraser' button and 'Save' button functionality
User prompt
Add a working eraser to the map if the save button selected
User prompt
remove save funcionality from the game logic, i want to rewrite it ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Generate all the sections of the eggbase in 360 degrees for a complete 3D effect when you rotate
User prompt
ensure eggbase size always the same at also spinning
User prompt
avoid aggbase disappear from the map at spinning
User prompt
When the eggbase is in spinning event generate it in every degrees from 360° so the 3d effect will be smoot
User prompt
Ensure that eggbase has the same size at spinning around
User prompt
Spin around the eggbase in y axis if spin button selected ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Then use other methot to make 3d spinning usable
User prompt
Do these points to make this 3d spinning possible.
User prompt
You not let the full spin of eggbase in 360 degrees, fix this
User prompt
Ensure that the size of the eggbase is the same at spinning but let spin the eggbase in 360 degrees to show 3D effect. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Spin buttons don't work like rotate buttons, but rotate the egg in a vertical-vertical position around its X axis
User prompt
Spin buttons don't work like rotate buttons, but rotate the egg in a vertical-vertical position around its own axis
User prompt
Add to the left side of the screen a spin left button and spin right button to the right side of the screen
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'savedEggs.push(newEggData);' Line Number: 1020
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'savedEggs.push(newEggData);' Line Number: 1017
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'savedEggs.push(newEggData);' Line Number: 1017
User prompt
Could you add to the save button a saving event? If this button selected save the painted egg to the storage ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'savedEggs.push(newEggData);' Line Number: 1017 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Ensure that @jzubora watermark can never be deleted even if the game is remixed
User prompt
Edit this text to @jzubora and flashing it up in few seconds
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
savedEggs: []
});
/****
* 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);
// Track the X rotation angle (vertical spin)
self.xRotationAngle = 0;
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);
}
};
self.clearDesigns = function () {
while (designContainer.children.length > 0) {
designContainer.removeChild(designContainer.children[0]);
}
};
self.rotate = function (angle) {
eggBase.rotation += angle;
designContainer.rotation += angle;
};
// Add method to spin the egg around X axis (vertical-vertical axis)
self.spinX = function (angle) {
// Update the total rotation angle
self.xRotationAngle += angle;
// Calculate the visual effect based on rotation angle
var cosValue = Math.cos(self.xRotationAngle);
// Apply a perspective scale effect without changing the actual egg size
// This creates the illusion of 3D rotation
var scaleEffect = 0.7 + 0.3 * Math.abs(cosValue);
// Apply transformations to create 3D spin illusion
eggBase.scaleX = scaleEffect;
designContainer.scaleX = scaleEffect;
// Apply opacity changes to enhance 3D effect - darker when edge is facing viewer
var opacityEffect = 0.7 + 0.3 * Math.abs(cosValue);
eggBase.alpha = opacityEffect;
designContainer.alpha = opacityEffect;
};
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 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 isPainting = false;
var lastX, lastY;
var selectedColorButton = null;
// Ensure savedEggs is properly initialized in storage
var savedEggs = [];
if (storage.savedEggs && Array.isArray(storage.savedEggs)) {
savedEggs = storage.savedEggs;
} else {
storage.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
});
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
});
currentTool = 'star';
// Toggle size slider visibility
sizeSlider.visible = !sizeSlider.visible;
// Update slider track color to black
sizeSlider.trackColor = 0x000000; // Black color
sizeSlider.track.tint = 0x000000;
// 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
});
currentTool = 'heart';
// Toggle size slider visibility
sizeSlider.visible = !sizeSlider.visible;
// Update slider track color to black
sizeSlider.trackColor = 0x000000; // Black color
sizeSlider.track.tint = 0x000000;
// 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
});
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
});
easterEgg.rotate(Math.PI / 8);
};
var saveButton = new Button("Save", 0x32CD32);
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
});
};
saveButton.up = function () {
tween(saveButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// Save the current egg design
var completedEgg = easterEgg.captureDesign();
// Add to saved eggs
var newEggData = {
x: 150 + savedEggs.length % 4 * 180,
y: 2732 - 600 - Math.floor(savedEggs.length / 4) * 220,
color: currentColor
};
// Ensure savedEggs is properly initialized as an array
if (!Array.isArray(savedEggs)) {
savedEggs = [];
}
// Add the new egg data to our array
savedEggs.push(newEggData);
// Update storage with a copy of the array
storage.savedEggs = savedEggs.slice();
// Play save sound
LK.getSound('saveSound').play();
// Add the egg to the basket display
displaySavedEggs();
// Increment score
LK.setScore(LK.getScore() + 1);
// Clear the current egg for a new design
easterEgg.clearDesigns();
};
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
});
currentTool = 'eraser';
// 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(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 eraser button
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
});
}
});
}
// Start the pulsing animation
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", 0xFF6347);
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
});
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 - 800 // Moved up by 60 units to make room for two rows of color buttons
});
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
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
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') {
// Remove the last design element
if (easterEgg.designContainer && easterEgg.designContainer.children.length > 0) {
easterEgg.designContainer.removeChild(easterEgg.designContainer.children[easterEgg.designContainer.children.length - 1]);
LK.getSound('brushSound').play(); // Play sound for eraser too
}
}
}
};
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;
// Get alpha based on tool (0 for eraser to make it invisible)
var strokeAlpha = currentTool === 'brush' ? 1 : 0;
// 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') {
// For eraser, remove the last design element
if (easterEgg.designContainer && easterEgg.designContainer.children.length > 0) {
easterEgg.designContainer.removeChild(easterEgg.designContainer.children[easterEgg.designContainer.children.length - 1]);
}
} else {
var stroke = new BrushStroke(strokeColor, currentSize);
stroke.alpha = strokeAlpha;
easterEgg.addDesign(pointX, pointY, stroke);
}
}
} else {
if (currentTool === 'eraser') {
// For eraser, remove the last design element
if (easterEgg.designContainer && easterEgg.designContainer.children.length > 0) {
easterEgg.designContainer.removeChild(easterEgg.designContainer.children[easterEgg.designContainer.children.length - 1]);
}
} else {
var stroke = new BrushStroke(strokeColor, currentSize);
stroke.alpha = strokeAlpha;
easterEgg.addDesign(x, y, stroke);
}
}
lastX = x;
lastY = y;
}
};
game.up = function () {
isPainting = false;
};
// Add spin left button to the left side of the screen
var spinLeftButton = new Button("3D Spin <", 0x9370DB);
spinLeftButton.x = 120; // Position on left side of screen
spinLeftButton.y = 2732 / 2; // Center vertically
game.addChild(spinLeftButton);
tween(spinLeftButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 300
});
spinLeftButton.down = function () {
tween(spinLeftButton, {
scaleX: 1.98,
scaleY: 1.8
}, {
duration: 100
});
// Start spin animation
spinLeftButton.isSpinning = true;
spinLeftButton.spinInterval = LK.setInterval(function () {
easterEgg.spinX(-Math.PI / 32); // Smoother continuous spin
}, 16); // ~60fps
};
spinLeftButton.up = function () {
tween(spinLeftButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// Stop continuous spin
if (spinLeftButton.isSpinning) {
LK.clearInterval(spinLeftButton.spinInterval);
spinLeftButton.isSpinning = false;
}
// Start pulsing animation for spin left button
function pulseSpinLeftButton() {
tween(spinLeftButton, {
scaleX: 2.4,
scaleY: 2.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(spinLeftButton, {
scaleX: 2.0,
scaleY: 1.8
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: pulseSpinLeftButton
});
}
});
}
// Start the pulsing animation
pulseSpinLeftButton();
};
// Add spin right button to the right side of the screen
var spinRightButton = new Button("3D Spin >", 0x9370DB);
spinRightButton.x = 2048 - 120; // Position on right side of screen
spinRightButton.y = 2732 / 2; // Center vertically
game.addChild(spinRightButton);
tween(spinRightButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 300
});
spinRightButton.down = function () {
tween(spinRightButton, {
scaleX: 1.98,
scaleY: 1.8
}, {
duration: 100
});
// Start spin animation
spinRightButton.isSpinning = true;
spinRightButton.spinInterval = LK.setInterval(function () {
easterEgg.spinX(Math.PI / 32); // Smoother continuous spin
}, 16); // ~60fps
};
spinRightButton.up = function () {
tween(spinRightButton, {
scaleX: 2.2,
scaleY: 2
}, {
duration: 100
});
// Stop continuous spin
if (spinRightButton.isSpinning) {
LK.clearInterval(spinRightButton.spinInterval);
spinRightButton.isSpinning = false;
}
// Start pulsing animation for spin right button
function pulseSpinRightButton() {
tween(spinRightButton, {
scaleX: 2.4,
scaleY: 2.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(spinRightButton, {
scaleX: 2.0,
scaleY: 1.8
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: pulseSpinRightButton
});
}
});
}
// Start the pulsing animation
pulseSpinRightButton();
};
// 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: 40,
fill: 0x000000 // Black color
});
sizeLabel.anchor.set(0.5, 0.5);
sizeLabel.x = sizeSlider.x + 150;
sizeLabel.y = sizeSlider.y - 70;
sizeLabel.visible = false;
game.addChild(sizeLabel);
// Update sticker size when slider value changes
sizeSlider.onValueChanged = function (value) {
// Update sticker size for next sticker
if (currentTool === 'star' || currentTool === 'heart') {
currentStickerSize = value;
}
};
// 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;
};
// 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(); ===================================================================
--- original.js
+++ change.js
@@ -254,14 +254,9 @@
// Add method to spin the egg around X axis (vertical-vertical axis)
self.spinX = function (angle) {
// Update the total rotation angle
self.xRotationAngle += angle;
- // Normalize the angle to keep it within 0-2π range
- self.xRotationAngle = self.xRotationAngle % (Math.PI * 2);
- if (self.xRotationAngle < 0) {
- self.xRotationAngle += Math.PI * 2;
- }
- // Calculate both sine and cosine for better 3D effect
+ // Calculate the visual effect based on rotation angle
var cosValue = Math.cos(self.xRotationAngle);
// Apply a perspective scale effect without changing the actual egg size
// This creates the illusion of 3D rotation
var scaleEffect = 0.7 + 0.3 * Math.abs(cosValue);