/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Pango = Container.expand(function () { var self = Container.call(this); var pangoGraphics = self.attachAsset('pango', { anchorX: 0.5, anchorY: 0.5 }); self.celebrate = function () { tween(self, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeIn }); } }); }; self.update = function () { // Gentle floating animation self.y += Math.sin(LK.ticks * 0.05) * 0.5; }; return self; }); var Snowflake = Container.expand(function (day) { var self = Container.call(this); self.day = day; self.isOpen = false; self.chocolateCollected = false; // Create snowflake visual var snowflakeGraphics = self.attachAsset('snowflake', { anchorX: 0.5, anchorY: 0.5 }); // Day number text var dayText = new Text2(day.toString(), { size: 36, fill: 0x003366 }); dayText.anchor.set(0.5, 0.5); self.addChild(dayText); // Chocolate ball (initially hidden) var chocolateBall = self.attachAsset('chocolateBall', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); chocolateBall.y = 40; self.open = function () { if (self.isOpen) return; self.isOpen = true; // Change appearance to opened state self.removeChild(snowflakeGraphics); var openedGraphics = self.attachAsset('snowflakeOpen', { anchorX: 0.5, anchorY: 0.5 }); // Show chocolate ball tween(chocolateBall, { alpha: 1 }, { duration: 500, easing: tween.easeOut }); // Play sound LK.getSound('snowflakeOpen').play(); // Add to opened snowflakes count openedSnowflakes++; updateProgress(); // Save progress saveProgress(); }; self.collectChocolate = function () { if (self.chocolateCollected || !self.isOpen) return; self.chocolateCollected = true; chocolateCount++; // Animate chocolate collection tween(chocolateBall, { scaleX: 0.1, scaleY: 0.1, alpha: 0 }, { duration: 300, easing: tween.easeIn }); LK.getSound('collectChocolate').play(); updateChocolateDisplay(); saveProgress(); }; self.canOpen = function () { // Sequential unlocking: can only open if previous day is opened or if it's day 1 if (self.day === 1) return true; var prevSnowflake = snowflakes[self.day - 2]; return prevSnowflake && prevSnowflake.isOpen; }; self.down = function (x, y, obj) { if (self.canOpen()) { if (!self.isOpen) { self.open(); } else if (!self.chocolateCollected) { self.collectChocolate(); } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x001a33 }); /**** * Game Code ****/ var snowflakes = []; var openedSnowflakes = 0; var chocolateCount = 0; var pango; // Load progress from storage var gameProgress = storage.gameProgress || { openedDays: [], collectedChocolates: [], totalChocolates: 0 }; // UI Elements var titleText = new Text2('Pango\'s Advent Calendar', { size: 72, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0); LK.gui.top.addChild(titleText); titleText.y = 50; var progressText = new Text2('Opened: 0/24', { size: 48, fill: 0xFFFFFF }); progressText.anchor.set(0, 0); LK.gui.topLeft.addChild(progressText); progressText.x = 120; progressText.y = 20; var chocolateText = new Text2('Chocolates: 0', { size: 48, fill: 0x8B4513 }); chocolateText.anchor.set(1, 0); LK.gui.topRight.addChild(chocolateText); chocolateText.x = -20; chocolateText.y = 20; // Create Pango character pango = game.addChild(new Pango()); pango.x = 1024; pango.y = 500; // Create snowflakes in advent calendar layout var startX = 200; var startY = 600; var cols = 6; var rows = 4; var spacingX = 280; var spacingY = 350; for (var i = 0; i < 24; i++) { var day = i + 1; var snowflake = new Snowflake(day); var col = i % cols; var row = Math.floor(i / cols); snowflake.x = startX + col * spacingX; snowflake.y = startY + row * spacingY; // Load saved progress if (gameProgress.openedDays.indexOf(day) !== -1) { snowflake.open(); } if (gameProgress.collectedChocolates.indexOf(day) !== -1) { snowflake.collectChocolate(); } snowflakes.push(snowflake); game.addChild(snowflake); } // Initialize counters from saved data openedSnowflakes = gameProgress.openedDays.length; chocolateCount = gameProgress.totalChocolates; function updateProgress() { progressText.setText('Opened: ' + openedSnowflakes + '/24'); if (openedSnowflakes === 24) { // All snowflakes opened! var completionText = new Text2('All Days Unlocked!', { size: 60, fill: 0x00FF00 }); completionText.anchor.set(0.5, 0.5); completionText.x = 1024; completionText.y = 400; game.addChild(completionText); pango.celebrate(); } } function updateChocolateDisplay() { chocolateText.setText('Chocolates: ' + chocolateCount); } function saveProgress() { var openedDays = []; var collectedChocolates = []; for (var i = 0; i < snowflakes.length; i++) { var snowflake = snowflakes[i]; if (snowflake.isOpen) { openedDays.push(snowflake.day); } if (snowflake.chocolateCollected) { collectedChocolates.push(snowflake.day); } } storage.gameProgress = { openedDays: openedDays, collectedChocolates: collectedChocolates, totalChocolates: chocolateCount }; } // Initialize display updateProgress(); updateChocolateDisplay(); // Start holiday music LK.playMusic('holidayMusic'); // Snow particle effect var snowParticles = []; var maxSnowParticles = 50; function createSnowParticle() { var particle = LK.getAsset('snowflake', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.2, scaleY: 0.2, alpha: 0.7 }); particle.x = Math.random() * 2048; particle.y = -50; particle.speed = Math.random() * 3 + 1; particle.drift = Math.random() * 2 - 1; return particle; } game.update = function () { // Create new snow particles if (snowParticles.length < maxSnowParticles && Math.random() < 0.3) { var particle = createSnowParticle(); snowParticles.push(particle); game.addChild(particle); } // Update snow particles for (var i = snowParticles.length - 1; i >= 0; i--) { var particle = snowParticles[i]; particle.y += particle.speed; particle.x += particle.drift; // Remove particles that are off screen if (particle.y > 2800) { particle.destroy(); snowParticles.splice(i, 1); } } // Visual feedback for locked snowflakes for (var j = 0; j < snowflakes.length; j++) { var snowflake = snowflakes[j]; if (!snowflake.isOpen && !snowflake.canOpen()) { snowflake.alpha = 0.5; } else if (!snowflake.isOpen) { snowflake.alpha = 1; // Gentle glow effect for available snowflakes snowflake.alpha = 0.8 + Math.sin(LK.ticks * 0.1) * 0.2; } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Pango = Container.expand(function () {
var self = Container.call(this);
var pangoGraphics = self.attachAsset('pango', {
anchorX: 0.5,
anchorY: 0.5
});
self.celebrate = function () {
tween(self, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeIn
});
}
});
};
self.update = function () {
// Gentle floating animation
self.y += Math.sin(LK.ticks * 0.05) * 0.5;
};
return self;
});
var Snowflake = Container.expand(function (day) {
var self = Container.call(this);
self.day = day;
self.isOpen = false;
self.chocolateCollected = false;
// Create snowflake visual
var snowflakeGraphics = self.attachAsset('snowflake', {
anchorX: 0.5,
anchorY: 0.5
});
// Day number text
var dayText = new Text2(day.toString(), {
size: 36,
fill: 0x003366
});
dayText.anchor.set(0.5, 0.5);
self.addChild(dayText);
// Chocolate ball (initially hidden)
var chocolateBall = self.attachAsset('chocolateBall', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0
});
chocolateBall.y = 40;
self.open = function () {
if (self.isOpen) return;
self.isOpen = true;
// Change appearance to opened state
self.removeChild(snowflakeGraphics);
var openedGraphics = self.attachAsset('snowflakeOpen', {
anchorX: 0.5,
anchorY: 0.5
});
// Show chocolate ball
tween(chocolateBall, {
alpha: 1
}, {
duration: 500,
easing: tween.easeOut
});
// Play sound
LK.getSound('snowflakeOpen').play();
// Add to opened snowflakes count
openedSnowflakes++;
updateProgress();
// Save progress
saveProgress();
};
self.collectChocolate = function () {
if (self.chocolateCollected || !self.isOpen) return;
self.chocolateCollected = true;
chocolateCount++;
// Animate chocolate collection
tween(chocolateBall, {
scaleX: 0.1,
scaleY: 0.1,
alpha: 0
}, {
duration: 300,
easing: tween.easeIn
});
LK.getSound('collectChocolate').play();
updateChocolateDisplay();
saveProgress();
};
self.canOpen = function () {
// Sequential unlocking: can only open if previous day is opened or if it's day 1
if (self.day === 1) return true;
var prevSnowflake = snowflakes[self.day - 2];
return prevSnowflake && prevSnowflake.isOpen;
};
self.down = function (x, y, obj) {
if (self.canOpen()) {
if (!self.isOpen) {
self.open();
} else if (!self.chocolateCollected) {
self.collectChocolate();
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x001a33
});
/****
* Game Code
****/
var snowflakes = [];
var openedSnowflakes = 0;
var chocolateCount = 0;
var pango;
// Load progress from storage
var gameProgress = storage.gameProgress || {
openedDays: [],
collectedChocolates: [],
totalChocolates: 0
};
// UI Elements
var titleText = new Text2('Pango\'s Advent Calendar', {
size: 72,
fill: 0xFFFFFF
});
titleText.anchor.set(0.5, 0);
LK.gui.top.addChild(titleText);
titleText.y = 50;
var progressText = new Text2('Opened: 0/24', {
size: 48,
fill: 0xFFFFFF
});
progressText.anchor.set(0, 0);
LK.gui.topLeft.addChild(progressText);
progressText.x = 120;
progressText.y = 20;
var chocolateText = new Text2('Chocolates: 0', {
size: 48,
fill: 0x8B4513
});
chocolateText.anchor.set(1, 0);
LK.gui.topRight.addChild(chocolateText);
chocolateText.x = -20;
chocolateText.y = 20;
// Create Pango character
pango = game.addChild(new Pango());
pango.x = 1024;
pango.y = 500;
// Create snowflakes in advent calendar layout
var startX = 200;
var startY = 600;
var cols = 6;
var rows = 4;
var spacingX = 280;
var spacingY = 350;
for (var i = 0; i < 24; i++) {
var day = i + 1;
var snowflake = new Snowflake(day);
var col = i % cols;
var row = Math.floor(i / cols);
snowflake.x = startX + col * spacingX;
snowflake.y = startY + row * spacingY;
// Load saved progress
if (gameProgress.openedDays.indexOf(day) !== -1) {
snowflake.open();
}
if (gameProgress.collectedChocolates.indexOf(day) !== -1) {
snowflake.collectChocolate();
}
snowflakes.push(snowflake);
game.addChild(snowflake);
}
// Initialize counters from saved data
openedSnowflakes = gameProgress.openedDays.length;
chocolateCount = gameProgress.totalChocolates;
function updateProgress() {
progressText.setText('Opened: ' + openedSnowflakes + '/24');
if (openedSnowflakes === 24) {
// All snowflakes opened!
var completionText = new Text2('All Days Unlocked!', {
size: 60,
fill: 0x00FF00
});
completionText.anchor.set(0.5, 0.5);
completionText.x = 1024;
completionText.y = 400;
game.addChild(completionText);
pango.celebrate();
}
}
function updateChocolateDisplay() {
chocolateText.setText('Chocolates: ' + chocolateCount);
}
function saveProgress() {
var openedDays = [];
var collectedChocolates = [];
for (var i = 0; i < snowflakes.length; i++) {
var snowflake = snowflakes[i];
if (snowflake.isOpen) {
openedDays.push(snowflake.day);
}
if (snowflake.chocolateCollected) {
collectedChocolates.push(snowflake.day);
}
}
storage.gameProgress = {
openedDays: openedDays,
collectedChocolates: collectedChocolates,
totalChocolates: chocolateCount
};
}
// Initialize display
updateProgress();
updateChocolateDisplay();
// Start holiday music
LK.playMusic('holidayMusic');
// Snow particle effect
var snowParticles = [];
var maxSnowParticles = 50;
function createSnowParticle() {
var particle = LK.getAsset('snowflake', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.2,
scaleY: 0.2,
alpha: 0.7
});
particle.x = Math.random() * 2048;
particle.y = -50;
particle.speed = Math.random() * 3 + 1;
particle.drift = Math.random() * 2 - 1;
return particle;
}
game.update = function () {
// Create new snow particles
if (snowParticles.length < maxSnowParticles && Math.random() < 0.3) {
var particle = createSnowParticle();
snowParticles.push(particle);
game.addChild(particle);
}
// Update snow particles
for (var i = snowParticles.length - 1; i >= 0; i--) {
var particle = snowParticles[i];
particle.y += particle.speed;
particle.x += particle.drift;
// Remove particles that are off screen
if (particle.y > 2800) {
particle.destroy();
snowParticles.splice(i, 1);
}
}
// Visual feedback for locked snowflakes
for (var j = 0; j < snowflakes.length; j++) {
var snowflake = snowflakes[j];
if (!snowflake.isOpen && !snowflake.canOpen()) {
snowflake.alpha = 0.5;
} else if (!snowflake.isOpen) {
snowflake.alpha = 1;
// Gentle glow effect for available snowflakes
snowflake.alpha = 0.8 + Math.sin(LK.ticks * 0.1) * 0.2;
}
}
};