/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Box = Container.expand(function (color) {
var self = Container.call(this);
self.color = color;
var assetName = color + 'Box';
var boxGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Clock = Container.expand(function () {
var self = Container.call(this);
var clockGraphics = self.attachAsset('clock', {
anchorX: 0.5,
anchorY: 0.5
});
self.isTapped = false;
self.down = function (x, y, obj) {
if (!self.isTapped) {
self.isTapped = true;
gameSpeed *= 1.5;
scoreMultiplier = 3;
// Update speed of all existing toys
for (var i = 0; i < toys.length; i++) {
toys[i].speed *= 1.5;
}
LK.getSound('clockRing').play();
// Shake animation
tween(self, {
rotation: 0.1
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
rotation: -0.1
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
rotation: 0
}, {
duration: 100,
easing: tween.easeInOut
});
}
});
}
});
LK.setTimeout(function () {
gameSpeed /= 1.5;
scoreMultiplier = 1;
// Update speed of all existing toys back to normal
for (var i = 0; i < toys.length; i++) {
toys[i].speed /= 1.5;
}
self.destroy();
clockSpawned = false;
}, 8750); // Delay disappearance by 8.75 seconds
}
};
return self;
});
var Toy = Container.expand(function (color) {
var self = Container.call(this);
self.color = color;
self.speed = 3;
self.isDragging = false;
self.startX = 0;
self.startY = 0;
// Randomly select a toy variant (1, 2, or 3)
var variant = Math.floor(Math.random() * 3) + 1;
var assetName = color + 'Toy' + (variant === 1 ? '' : variant);
var toyGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
if (!self.isDragging && !gameOver) {
self.y += self.speed;
if (self.color === 'red' && assetName === 'redToy3') {
self.rotation += 0.1; // Adjust the rotation speed as needed
}
}
};
self.down = function (x, y, obj) {
if (!draggedToy && !gameOver) {
self.isDragging = true;
self.startX = self.x;
self.startY = self.y;
draggedToy = self;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x006600
});
/****
* Game Code
****/
// Create background
var background = LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
scaleX: 20.48,
scaleY: 27.32
});
background.x = 0;
background.y = 0;
game.addChild(background);
// Game variables
var toys = [];
var boxes = [];
var draggedToy = null;
var wrong = 0;
var maxWrong = 3;
var spawnTimer = 0;
var spawnDelay = 90;
var baseSpawnDelay = 90;
var gameSpeed = 1;
var speedIncreaseTimer = 0;
var spawnRateIncreaseTimer = 0;
var gameTimer = 0;
var gameOver = false;
var scoreMilestonePlayed = false;
var fastMusicPlaying = false;
var warningPlayed = false;
// Create boxes at bottom of screen
var boxColors = ['red', 'yellow', 'blue'];
// Center the boxes when green box is not spawned with spacing between them
var boxSpacing = 450; // Distance between boxes
var startX = 2048 / 2 - boxSpacing; // Start position for first box
var boxPositions = [startX, startX + boxSpacing, startX + boxSpacing * 2];
var greenBoxSpawned = false;
for (var i = 0; i < boxColors.length; i++) {
var box = new Box(boxColors[i]);
box.x = boxPositions[i];
box.y = 2732 - 200;
boxes.push(box);
game.addChild(box);
}
// UI Elements
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var healthTxt = new Text2('Wrong: 0/' + maxWrong, {
size: 80,
fill: 0xFF0000
});
healthTxt.anchor.set(0, 0);
healthTxt.x = 150;
healthTxt.y = 20;
LK.gui.topLeft.addChild(healthTxt);
// Spawn toy function
function spawnToy() {
if (gameOver) return;
var availableColors = boxColors.slice();
// Add brown toys after 25 seconds (1500 ticks at 60fps) but less frequently
if (gameTimer >= 1500 && Math.random() < 0.3) {
availableColors.push('brown');
}
// Add green toys after 60 seconds (3600 ticks at 60fps)
if (gameTimer >= 3600) {
availableColors.push('green');
}
var randomColor = availableColors[Math.floor(Math.random() * availableColors.length)];
var toy = new Toy(randomColor);
toy.x = Math.random() * (2048 - 240) + 120;
toy.y = -60;
toy.speed = 3 * gameSpeed;
toys.push(toy);
game.addChild(toy);
}
// Check if toy intersects with any box
function checkToyBoxIntersection(toy) {
for (var i = 0; i < boxes.length; i++) {
if (toy.intersects(boxes[i])) {
return boxes[i];
}
}
return null;
}
// Remove toy from game
function removeToy(toy, index) {
toy.destroy();
toys.splice(index, 1);
}
// Game input handlers
game.move = function (x, y, obj) {
if (draggedToy && !gameOver) {
draggedToy.x = x;
draggedToy.y = y;
}
};
game.up = function (x, y, obj) {
if (draggedToy && !gameOver) {
var intersectingBox = checkToyBoxIntersection(draggedToy);
if (intersectingBox) {
if (draggedToy.color === intersectingBox.color) {
// Correct placement
LK.setScore(LK.getScore() + 5 * scoreMultiplier);
scoreTxt.setText('Score: ' + LK.getScore());
LK.getSound('correct').play();
// Remove toy
var toyIndex = toys.indexOf(draggedToy);
if (toyIndex !== -1) {
removeToy(draggedToy, toyIndex);
}
} else {
// Wrong placement (including brown toys in any box)
var newScore = Math.max(0, LK.getScore() - 15);
LK.setScore(newScore);
scoreTxt.setText('Score: ' + LK.getScore());
wrong++;
healthTxt.setText('Wrong: ' + wrong + '/' + maxWrong);
LK.getSound('wrong').play();
LK.effects.flashScreen(0xff0000, 500);
// Remove brown toys when placed in any box, return others to position
if (draggedToy.color === 'brown') {
var toyIndex = toys.indexOf(draggedToy);
if (toyIndex !== -1) {
removeToy(draggedToy, toyIndex);
}
} else {
// Return toy to original position
draggedToy.x = draggedToy.startX;
draggedToy.y = draggedToy.startY;
}
}
} else {
// Return toy to original position if not dropped on box
draggedToy.x = draggedToy.startX;
draggedToy.y = draggedToy.startY;
}
draggedToy.isDragging = false;
draggedToy = null;
}
};
// Main game update
game.update = function () {
if (gameOver) return;
// Update game timer
gameTimer++;
// Spawn toys
spawnTimer++;
if (spawnTimer >= spawnDelay) {
spawnToy();
spawnTimer = 0;
}
// Increase game speed over time
speedIncreaseTimer++;
if (speedIncreaseTimer >= 240) {
// Every 4 seconds at 60fps
gameSpeed *= 1.03; // Increase by 3%
if (gameSpeed > 3.0) {
gameSpeed = 3.0; // Cap at 300% (3x original speed)
}
speedIncreaseTimer = 0;
}
// Increase spawn rate over time (separate from speed increase)
spawnRateIncreaseTimer++;
if (spawnRateIncreaseTimer >= 1800) {
// Every 30 seconds at 60fps
if (spawnDelay > 30) {
spawnDelay = Math.max(30, spawnDelay - 2); // Reduce spawn delay by 2, minimum 30
}
spawnRateIncreaseTimer = 0;
}
// Start fast music when speed reaches maximum
if (gameSpeed >= 3.0 && !fastMusicPlaying) {
LK.playMusic('fastMusic');
fastMusicPlaying = true;
}
// Occasionally spawn clocks (only when brown toys can spawn and much less common)
if (gameTimer >= 1500 && Math.random() < 0.001 && !clockSpawned) {
var clock = new Clock();
clock.x = Math.random() * (2048 - 200) + 100;
clock.y = Math.random() * (2732 - 200) + 100;
game.addChild(clock);
clockSpawned = true;
}
// Update toys and check for collisions/missed toys
for (var i = toys.length - 1; i >= 0; i--) {
var toy = toys[i];
// Check if toy fell off screen
if (toy.y > 2732 + 60) {
// Brown toys don't give penalty when falling off screen - just remove them
if (toy.color !== 'brown') {
// Non-brown toys give penalty when falling off screen
var newScore = Math.max(0, LK.getScore() - 15);
LK.setScore(newScore);
scoreTxt.setText('Score: ' + LK.getScore());
wrong++;
healthTxt.setText('Wrong: ' + wrong + '/' + maxWrong);
LK.getSound('wrong').play();
LK.effects.flashScreen(0xff0000, 500);
}
removeToy(toy, i);
continue;
}
// Check if toy is intersecting with correct box while not being dragged
if (!toy.isDragging) {
var intersectingBox = checkToyBoxIntersection(toy);
if (intersectingBox) {
if (toy.color === intersectingBox.color) {
LK.setScore(LK.getScore() + 5 * scoreMultiplier);
scoreTxt.setText('Score: ' + LK.getScore());
LK.getSound('correct').play();
removeToy(toy, i);
continue;
}
}
}
}
// Check game over condition
if (wrong >= maxWrong && !gameOver) {
gameOver = true;
// Stop all music when santa appears
LK.stopMusic();
// Show santa for 1 second before game over
var santa = LK.getAsset('santa', {
anchorX: 0.5,
anchorY: 0.5
});
santa.x = 2048 / 2;
santa.y = 2732 / 2;
game.addChild(santa);
// Play santa sound
LK.getSound('santa').play();
// Calculate scale to make santa almost fill the screen
// Leave some padding around the edges (90% of screen size)
var targetScaleX = 2048 * 0.9 / santa.width;
var targetScaleY = 2732 * 0.9 / santa.height;
// Use the smaller scale to maintain aspect ratio and fit within screen
var targetScale = Math.min(targetScaleX, targetScaleY);
// Animate santa appearing with scale tween
santa.scaleX = 0;
santa.scaleY = 0;
tween(santa, {
scaleX: targetScale,
scaleY: targetScale
}, {
duration: 500,
easing: tween.bounceOut,
onFinish: function onFinish() {
// Wait 1500ms more then show game over (total 2 seconds)
LK.setTimeout(function () {
LK.showGameOver();
}, 1500);
}
});
}
// Play warning 5 seconds before brown toys spawn (at 20 seconds / 1200 ticks)
if (gameTimer >= 1200 && !warningPlayed) {
LK.getSound('warning').play();
warningPlayed = true;
// Create exclamation mark
var exclamation = LK.getAsset('exclamation', {
anchorX: 0.5,
anchorY: 0.5
});
exclamation.x = 2048 / 2;
exclamation.y = 2732 / 2;
exclamation.scaleX = 0;
exclamation.scaleY = 0;
game.addChild(exclamation);
// Animate exclamation mark appearing
tween(exclamation, {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.bounceOut,
onFinish: function onFinish() {
// Keep exclamation visible for 2 seconds then fade out
LK.setTimeout(function () {
tween(exclamation, {
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
exclamation.destroy();
}
});
}, 2000);
}
});
}
// Play warning at 60 seconds (3600 ticks) and spawn green box
if (gameTimer >= 3600 && !greenBoxSpawned) {
greenBoxSpawned = true;
// Move existing boxes to the left with tween animation
for (var b = 0; b < boxes.length; b++) {
var targetX = (b + 1) * 2048 / 5;
tween(boxes[b], {
x: targetX
}, {
duration: 1000,
easing: tween.easeInOut
});
}
// Create green box at the right
LK.getSound('greenBox').play();
var greenBox = new Box('green');
greenBox.x = 4 * 2048 / 5;
greenBox.y = 2732 - 200;
greenBox.alpha = 0; // Start invisible for fade-in animation
boxes.push(greenBox);
boxColors.push('green');
game.addChild(greenBox);
// Animate green box fade in
tween(greenBox, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeInOut
});
// Create exclamation mark
var exclamation = LK.getAsset('exclamation', {
anchorX: 0.5,
anchorY: 0.5
});
exclamation.x = 2048 / 2;
exclamation.y = 2732 / 2;
exclamation.scaleX = 0;
exclamation.scaleY = 0;
game.addChild(exclamation);
// Animate exclamation mark appearing
tween(exclamation, {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.bounceOut,
onFinish: function onFinish() {
// Keep exclamation visible for 2 seconds then fade out
LK.setTimeout(function () {
tween(exclamation, {
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
exclamation.destroy();
}
});
}, 2000);
}
});
}
// Play sound effect when reaching a score of 1000
if (LK.getScore() >= 1000 && !scoreMilestonePlayed) {
LK.getSound('scoreMilestone').play();
scoreMilestonePlayed = true;
}
// Game is now infinite - no win condition
};
// Start background music immediately at game start
LK.playMusic('christmas');
// Preload all sounds by playing them at volume 0
var correctSound = LK.getSound('correct');
correctSound.volume = 0;
correctSound.play();
correctSound.volume = 0.5;
var wrongSound = LK.getSound('wrong');
wrongSound.volume = 0;
wrongSound.play();
wrongSound.volume = 0.5;
var santaSound = LK.getSound('santa');
santaSound.volume = 0;
santaSound.play();
santaSound.volume = 1;
var clockRingSound = LK.getSound('clockRing');
clockRingSound.volume = 0;
clockRingSound.play();
clockRingSound.volume = 0.8;
var greenBoxSound = LK.getSound('greenBox');
greenBoxSound.volume = 0;
greenBoxSound.play();
greenBoxSound.volume = 1;
var scoreMilestoneSound = LK.getSound('scoreMilestone');
scoreMilestoneSound.volume = 0;
scoreMilestoneSound.play();
scoreMilestoneSound.volume = 1;
var warningSound = LK.getSound('warning');
warningSound.volume = 0;
warningSound.play();
warningSound.volume = 1;
var scoreMultiplier = 1;
var clockSpawned = false;
; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Box = Container.expand(function (color) {
var self = Container.call(this);
self.color = color;
var assetName = color + 'Box';
var boxGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var Clock = Container.expand(function () {
var self = Container.call(this);
var clockGraphics = self.attachAsset('clock', {
anchorX: 0.5,
anchorY: 0.5
});
self.isTapped = false;
self.down = function (x, y, obj) {
if (!self.isTapped) {
self.isTapped = true;
gameSpeed *= 1.5;
scoreMultiplier = 3;
// Update speed of all existing toys
for (var i = 0; i < toys.length; i++) {
toys[i].speed *= 1.5;
}
LK.getSound('clockRing').play();
// Shake animation
tween(self, {
rotation: 0.1
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
rotation: -0.1
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(self, {
rotation: 0
}, {
duration: 100,
easing: tween.easeInOut
});
}
});
}
});
LK.setTimeout(function () {
gameSpeed /= 1.5;
scoreMultiplier = 1;
// Update speed of all existing toys back to normal
for (var i = 0; i < toys.length; i++) {
toys[i].speed /= 1.5;
}
self.destroy();
clockSpawned = false;
}, 8750); // Delay disappearance by 8.75 seconds
}
};
return self;
});
var Toy = Container.expand(function (color) {
var self = Container.call(this);
self.color = color;
self.speed = 3;
self.isDragging = false;
self.startX = 0;
self.startY = 0;
// Randomly select a toy variant (1, 2, or 3)
var variant = Math.floor(Math.random() * 3) + 1;
var assetName = color + 'Toy' + (variant === 1 ? '' : variant);
var toyGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
if (!self.isDragging && !gameOver) {
self.y += self.speed;
if (self.color === 'red' && assetName === 'redToy3') {
self.rotation += 0.1; // Adjust the rotation speed as needed
}
}
};
self.down = function (x, y, obj) {
if (!draggedToy && !gameOver) {
self.isDragging = true;
self.startX = self.x;
self.startY = self.y;
draggedToy = self;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x006600
});
/****
* Game Code
****/
// Create background
var background = LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
scaleX: 20.48,
scaleY: 27.32
});
background.x = 0;
background.y = 0;
game.addChild(background);
// Game variables
var toys = [];
var boxes = [];
var draggedToy = null;
var wrong = 0;
var maxWrong = 3;
var spawnTimer = 0;
var spawnDelay = 90;
var baseSpawnDelay = 90;
var gameSpeed = 1;
var speedIncreaseTimer = 0;
var spawnRateIncreaseTimer = 0;
var gameTimer = 0;
var gameOver = false;
var scoreMilestonePlayed = false;
var fastMusicPlaying = false;
var warningPlayed = false;
// Create boxes at bottom of screen
var boxColors = ['red', 'yellow', 'blue'];
// Center the boxes when green box is not spawned with spacing between them
var boxSpacing = 450; // Distance between boxes
var startX = 2048 / 2 - boxSpacing; // Start position for first box
var boxPositions = [startX, startX + boxSpacing, startX + boxSpacing * 2];
var greenBoxSpawned = false;
for (var i = 0; i < boxColors.length; i++) {
var box = new Box(boxColors[i]);
box.x = boxPositions[i];
box.y = 2732 - 200;
boxes.push(box);
game.addChild(box);
}
// UI Elements
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var healthTxt = new Text2('Wrong: 0/' + maxWrong, {
size: 80,
fill: 0xFF0000
});
healthTxt.anchor.set(0, 0);
healthTxt.x = 150;
healthTxt.y = 20;
LK.gui.topLeft.addChild(healthTxt);
// Spawn toy function
function spawnToy() {
if (gameOver) return;
var availableColors = boxColors.slice();
// Add brown toys after 25 seconds (1500 ticks at 60fps) but less frequently
if (gameTimer >= 1500 && Math.random() < 0.3) {
availableColors.push('brown');
}
// Add green toys after 60 seconds (3600 ticks at 60fps)
if (gameTimer >= 3600) {
availableColors.push('green');
}
var randomColor = availableColors[Math.floor(Math.random() * availableColors.length)];
var toy = new Toy(randomColor);
toy.x = Math.random() * (2048 - 240) + 120;
toy.y = -60;
toy.speed = 3 * gameSpeed;
toys.push(toy);
game.addChild(toy);
}
// Check if toy intersects with any box
function checkToyBoxIntersection(toy) {
for (var i = 0; i < boxes.length; i++) {
if (toy.intersects(boxes[i])) {
return boxes[i];
}
}
return null;
}
// Remove toy from game
function removeToy(toy, index) {
toy.destroy();
toys.splice(index, 1);
}
// Game input handlers
game.move = function (x, y, obj) {
if (draggedToy && !gameOver) {
draggedToy.x = x;
draggedToy.y = y;
}
};
game.up = function (x, y, obj) {
if (draggedToy && !gameOver) {
var intersectingBox = checkToyBoxIntersection(draggedToy);
if (intersectingBox) {
if (draggedToy.color === intersectingBox.color) {
// Correct placement
LK.setScore(LK.getScore() + 5 * scoreMultiplier);
scoreTxt.setText('Score: ' + LK.getScore());
LK.getSound('correct').play();
// Remove toy
var toyIndex = toys.indexOf(draggedToy);
if (toyIndex !== -1) {
removeToy(draggedToy, toyIndex);
}
} else {
// Wrong placement (including brown toys in any box)
var newScore = Math.max(0, LK.getScore() - 15);
LK.setScore(newScore);
scoreTxt.setText('Score: ' + LK.getScore());
wrong++;
healthTxt.setText('Wrong: ' + wrong + '/' + maxWrong);
LK.getSound('wrong').play();
LK.effects.flashScreen(0xff0000, 500);
// Remove brown toys when placed in any box, return others to position
if (draggedToy.color === 'brown') {
var toyIndex = toys.indexOf(draggedToy);
if (toyIndex !== -1) {
removeToy(draggedToy, toyIndex);
}
} else {
// Return toy to original position
draggedToy.x = draggedToy.startX;
draggedToy.y = draggedToy.startY;
}
}
} else {
// Return toy to original position if not dropped on box
draggedToy.x = draggedToy.startX;
draggedToy.y = draggedToy.startY;
}
draggedToy.isDragging = false;
draggedToy = null;
}
};
// Main game update
game.update = function () {
if (gameOver) return;
// Update game timer
gameTimer++;
// Spawn toys
spawnTimer++;
if (spawnTimer >= spawnDelay) {
spawnToy();
spawnTimer = 0;
}
// Increase game speed over time
speedIncreaseTimer++;
if (speedIncreaseTimer >= 240) {
// Every 4 seconds at 60fps
gameSpeed *= 1.03; // Increase by 3%
if (gameSpeed > 3.0) {
gameSpeed = 3.0; // Cap at 300% (3x original speed)
}
speedIncreaseTimer = 0;
}
// Increase spawn rate over time (separate from speed increase)
spawnRateIncreaseTimer++;
if (spawnRateIncreaseTimer >= 1800) {
// Every 30 seconds at 60fps
if (spawnDelay > 30) {
spawnDelay = Math.max(30, spawnDelay - 2); // Reduce spawn delay by 2, minimum 30
}
spawnRateIncreaseTimer = 0;
}
// Start fast music when speed reaches maximum
if (gameSpeed >= 3.0 && !fastMusicPlaying) {
LK.playMusic('fastMusic');
fastMusicPlaying = true;
}
// Occasionally spawn clocks (only when brown toys can spawn and much less common)
if (gameTimer >= 1500 && Math.random() < 0.001 && !clockSpawned) {
var clock = new Clock();
clock.x = Math.random() * (2048 - 200) + 100;
clock.y = Math.random() * (2732 - 200) + 100;
game.addChild(clock);
clockSpawned = true;
}
// Update toys and check for collisions/missed toys
for (var i = toys.length - 1; i >= 0; i--) {
var toy = toys[i];
// Check if toy fell off screen
if (toy.y > 2732 + 60) {
// Brown toys don't give penalty when falling off screen - just remove them
if (toy.color !== 'brown') {
// Non-brown toys give penalty when falling off screen
var newScore = Math.max(0, LK.getScore() - 15);
LK.setScore(newScore);
scoreTxt.setText('Score: ' + LK.getScore());
wrong++;
healthTxt.setText('Wrong: ' + wrong + '/' + maxWrong);
LK.getSound('wrong').play();
LK.effects.flashScreen(0xff0000, 500);
}
removeToy(toy, i);
continue;
}
// Check if toy is intersecting with correct box while not being dragged
if (!toy.isDragging) {
var intersectingBox = checkToyBoxIntersection(toy);
if (intersectingBox) {
if (toy.color === intersectingBox.color) {
LK.setScore(LK.getScore() + 5 * scoreMultiplier);
scoreTxt.setText('Score: ' + LK.getScore());
LK.getSound('correct').play();
removeToy(toy, i);
continue;
}
}
}
}
// Check game over condition
if (wrong >= maxWrong && !gameOver) {
gameOver = true;
// Stop all music when santa appears
LK.stopMusic();
// Show santa for 1 second before game over
var santa = LK.getAsset('santa', {
anchorX: 0.5,
anchorY: 0.5
});
santa.x = 2048 / 2;
santa.y = 2732 / 2;
game.addChild(santa);
// Play santa sound
LK.getSound('santa').play();
// Calculate scale to make santa almost fill the screen
// Leave some padding around the edges (90% of screen size)
var targetScaleX = 2048 * 0.9 / santa.width;
var targetScaleY = 2732 * 0.9 / santa.height;
// Use the smaller scale to maintain aspect ratio and fit within screen
var targetScale = Math.min(targetScaleX, targetScaleY);
// Animate santa appearing with scale tween
santa.scaleX = 0;
santa.scaleY = 0;
tween(santa, {
scaleX: targetScale,
scaleY: targetScale
}, {
duration: 500,
easing: tween.bounceOut,
onFinish: function onFinish() {
// Wait 1500ms more then show game over (total 2 seconds)
LK.setTimeout(function () {
LK.showGameOver();
}, 1500);
}
});
}
// Play warning 5 seconds before brown toys spawn (at 20 seconds / 1200 ticks)
if (gameTimer >= 1200 && !warningPlayed) {
LK.getSound('warning').play();
warningPlayed = true;
// Create exclamation mark
var exclamation = LK.getAsset('exclamation', {
anchorX: 0.5,
anchorY: 0.5
});
exclamation.x = 2048 / 2;
exclamation.y = 2732 / 2;
exclamation.scaleX = 0;
exclamation.scaleY = 0;
game.addChild(exclamation);
// Animate exclamation mark appearing
tween(exclamation, {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.bounceOut,
onFinish: function onFinish() {
// Keep exclamation visible for 2 seconds then fade out
LK.setTimeout(function () {
tween(exclamation, {
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
exclamation.destroy();
}
});
}, 2000);
}
});
}
// Play warning at 60 seconds (3600 ticks) and spawn green box
if (gameTimer >= 3600 && !greenBoxSpawned) {
greenBoxSpawned = true;
// Move existing boxes to the left with tween animation
for (var b = 0; b < boxes.length; b++) {
var targetX = (b + 1) * 2048 / 5;
tween(boxes[b], {
x: targetX
}, {
duration: 1000,
easing: tween.easeInOut
});
}
// Create green box at the right
LK.getSound('greenBox').play();
var greenBox = new Box('green');
greenBox.x = 4 * 2048 / 5;
greenBox.y = 2732 - 200;
greenBox.alpha = 0; // Start invisible for fade-in animation
boxes.push(greenBox);
boxColors.push('green');
game.addChild(greenBox);
// Animate green box fade in
tween(greenBox, {
alpha: 1
}, {
duration: 1000,
easing: tween.easeInOut
});
// Create exclamation mark
var exclamation = LK.getAsset('exclamation', {
anchorX: 0.5,
anchorY: 0.5
});
exclamation.x = 2048 / 2;
exclamation.y = 2732 / 2;
exclamation.scaleX = 0;
exclamation.scaleY = 0;
game.addChild(exclamation);
// Animate exclamation mark appearing
tween(exclamation, {
scaleX: 1,
scaleY: 1
}, {
duration: 300,
easing: tween.bounceOut,
onFinish: function onFinish() {
// Keep exclamation visible for 2 seconds then fade out
LK.setTimeout(function () {
tween(exclamation, {
alpha: 0,
scaleX: 0,
scaleY: 0
}, {
duration: 300,
easing: tween.easeIn,
onFinish: function onFinish() {
exclamation.destroy();
}
});
}, 2000);
}
});
}
// Play sound effect when reaching a score of 1000
if (LK.getScore() >= 1000 && !scoreMilestonePlayed) {
LK.getSound('scoreMilestone').play();
scoreMilestonePlayed = true;
}
// Game is now infinite - no win condition
};
// Start background music immediately at game start
LK.playMusic('christmas');
// Preload all sounds by playing them at volume 0
var correctSound = LK.getSound('correct');
correctSound.volume = 0;
correctSound.play();
correctSound.volume = 0.5;
var wrongSound = LK.getSound('wrong');
wrongSound.volume = 0;
wrongSound.play();
wrongSound.volume = 0.5;
var santaSound = LK.getSound('santa');
santaSound.volume = 0;
santaSound.play();
santaSound.volume = 1;
var clockRingSound = LK.getSound('clockRing');
clockRingSound.volume = 0;
clockRingSound.play();
clockRingSound.volume = 0.8;
var greenBoxSound = LK.getSound('greenBox');
greenBoxSound.volume = 0;
greenBoxSound.play();
greenBoxSound.volume = 1;
var scoreMilestoneSound = LK.getSound('scoreMilestone');
scoreMilestoneSound.volume = 0;
scoreMilestoneSound.play();
scoreMilestoneSound.volume = 1;
var warningSound = LK.getSound('warning');
warningSound.volume = 0;
warningSound.play();
warningSound.volume = 1;
var scoreMultiplier = 1;
var clockSpawned = false;
;
Santa angry In-Game asset. 2d. High contrast. No shadows
Brown rocking horse. In-Game asset. 2d. High contrast. No shadows
Brown kids book. In-Game asset. 2d. High contrast. No shadows
A blue robot toy. In-Game asset. 2d. High contrast. No shadows
A yellow box. In-Game asset. 2d. High contrast. No shadows
Yellow star plushie with a smile on it. In-Game asset. 2d. High contrast. No shadows
A red toy car. In-Game asset. 2d. High contrast. No shadows
A yellow banana. In-Game asset. 2d. High contrast. No shadows
Red ball with two white eyes, inside the eyes are medium sized black dots, and a black smiley mouth. In-Game asset. 2d. High contrast. No shadows
Blue diamond toy. In-Game asset. 2d. High contrast
Red exclamation mark with a gradient and a stroke. In-Game asset. 2d. High contrast. No shadows
Green box. In-Game asset. 2d. High contrast. No shadows
Red clock. In-Game asset. 2d. High contrast. No shadows
A green puzzle piece. In-Game asset. 2d. High contrast. No shadows
Green dino plushie. In-Game asset. 2d. High contrast. No shadows
Green apple. In-Game asset. 2d. High contrast. No shadows