/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var CoasterCar = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('coasterCar', {
anchorX: 0.5,
anchorY: 0.5
});
self.moving = false;
self.speed = 3;
self.direction = 1;
self.trackPosition = 0;
self.update = function () {
if (self.moving) {
self.trackPosition += self.speed * self.direction;
// Simple track movement (left-right)
if (self.trackPosition > 400) {
self.trackPosition = 400;
self.direction = -1;
} else if (self.trackPosition < 0) {
self.trackPosition = 0;
self.direction = 1;
}
self.x = 824 + self.trackPosition; // Center track at 1024
}
};
return self;
});
var Sled = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('sled', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.speed = 0;
self.maxSpeed = 8;
self.friction = 0.98;
self.update = function () {
// Apply movement
self.x += self.velocityX;
self.y += self.velocityY;
// Apply friction
self.velocityX *= self.friction;
self.velocityY *= self.friction;
// Keep in bounds
self.x = Math.max(70, Math.min(1978, self.x));
self.y = Math.max(70, Math.min(2662, self.y));
};
return self;
});
var Snowball = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('snowball', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.active = true;
self.update = function () {
if (!self.active) return;
self.x += self.velocityX;
self.y += self.velocityY;
// Remove if off screen
if (self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782) {
self.active = false;
}
};
return self;
});
var Snowflake = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('snowflake', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityY = Math.random() * 2 + 1;
self.velocityX = (Math.random() - 0.5) * 0.5;
self.active = true;
self.update = function () {
if (!self.active) return;
self.x += self.velocityX;
self.y += self.velocityY;
if (self.y > 2732) {
self.active = false;
}
};
return self;
});
var Target = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('target', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = (Math.random() - 0.5) * 4;
self.velocityY = (Math.random() - 0.5) * 2;
self.active = true;
self.lastX = self.x;
self.lastY = self.y;
self.update = function () {
if (!self.active) return;
self.lastX = self.x;
self.lastY = self.y;
self.x += self.velocityX;
self.y += self.velocityY;
// Bounce off walls
if (self.x < 50 || self.x > 1998) {
self.velocityX *= -1;
}
if (self.y < 200 || self.y > 1500) {
self.velocityY *= -1;
}
// Keep in bounds
self.x = Math.max(50, Math.min(1998, self.x));
self.y = Math.max(200, Math.min(1500, self.y));
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Sounds
// UI elements
// Characters and objects
// Level backgrounds
// Game state variables
var currentLevel = 1;
var gameState = 'playing'; // 'playing', 'levelComplete', 'gameComplete'
var levelScore = 0;
var totalScore = 0;
// Level 1 variables
var snowballs = [];
var targets = [];
var targetSpawnTimer = 0;
// Level 2 variables
var player = null;
var hills = [];
var sledPower = 0;
var sledding = false;
// Level 3 variables
var coasterCar = null;
var snowflakes = [];
var snowflakeTimer = 0;
var coasterScore = 0;
var coasterTimer = 0;
// UI Elements
var levelText = new Text2('Level 1: Snowball Fight', {
size: 80,
fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(1, 0);
LK.gui.topRight.addChild(scoreText);
var instructionText = new Text2('Tap targets to throw snowballs!', {
size: 50,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 0);
instructionText.y = 120;
LK.gui.top.addChild(instructionText);
// Initialize Level 1
function initLevel1() {
currentLevel = 1;
levelScore = 0;
gameState = 'playing';
// Clear arrays
snowballs = [];
targets = [];
// Update UI
levelText.setText('Level 1: Snowball Fight');
instructionText.setText('Tap targets to throw snowballs!');
// Create background
var bg = game.addChild(LK.getAsset('level1Background', {
x: 0,
y: 0
}));
// Create initial targets
for (var i = 0; i < 3; i++) {
createTarget();
}
}
// Initialize Level 2
function initLevel2() {
currentLevel = 2;
levelScore = 0;
gameState = 'playing';
// Clear previous level
clearLevel();
// Update UI
levelText.setText('Level 2: Sledding');
instructionText.setText('Tap to control your sled!');
// Create background
var bg = game.addChild(LK.getAsset('level2Background', {
x: 0,
y: 0
}));
// Create hills
for (var i = 0; i < 5; i++) {
var hill = game.addChild(LK.getAsset('hill', {
x: Math.random() * 1748 + 150,
y: Math.random() * 1000 + 800,
anchorX: 0.5,
anchorY: 0.5
}));
hills.push(hill);
}
// Create sled
player = game.addChild(new Sled());
player.x = 1024;
player.y = 500;
}
// Initialize Level 3
function initLevel3() {
currentLevel = 3;
levelScore = 0;
gameState = 'playing';
coasterScore = 0;
coasterTimer = 0;
// Clear previous level
clearLevel();
// Update UI
levelText.setText('Level 3: Snow Roller Coaster');
instructionText.setText('Tap to start/stop the coaster!');
// Create background
var bg = game.addChild(LK.getAsset('level3Background', {
x: 0,
y: 0
}));
// Create track
var track = game.addChild(LK.getAsset('track', {
x: 1024,
y: 1366,
anchorX: 0.5,
anchorY: 0.5
}));
// Create coaster car
coasterCar = game.addChild(new CoasterCar());
coasterCar.x = 1024;
coasterCar.y = 1366;
snowflakes = [];
}
function clearLevel() {
// Remove all children except UI
while (game.children.length > 0) {
var child = game.children[0];
child.destroy();
}
// Clear arrays
snowballs = [];
targets = [];
hills = [];
snowflakes = [];
player = null;
coasterCar = null;
}
function createTarget() {
var target = game.addChild(new Target());
target.x = Math.random() * 1600 + 224;
target.y = Math.random() * 1000 + 400;
targets.push(target);
}
function createSnowball(targetX, targetY) {
var snowball = game.addChild(new Snowball());
snowball.x = 1024; // Center of screen
snowball.y = 2200; // Bottom of screen
// Calculate velocity towards target
var dx = targetX - snowball.x;
var dy = targetY - snowball.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var speed = 12;
snowball.velocityX = dx / distance * speed;
snowball.velocityY = dy / distance * speed;
snowballs.push(snowball);
LK.getSound('throw').play();
}
function createSnowflake() {
var snowflake = game.addChild(new Snowflake());
snowflake.x = Math.random() * 2048;
snowflake.y = -20;
snowflakes.push(snowflake);
}
// Game input handlers
game.down = function (x, y, obj) {
if (gameState !== 'playing') return;
if (currentLevel === 1) {
// Level 1: Tap to throw snowball
createSnowball(x, y);
} else if (currentLevel === 2) {
// Level 2: Tap to boost sled
if (player) {
var dx = x - player.x;
var dy = y - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
var force = 3;
player.velocityX += dx / distance * force;
player.velocityY += dy / distance * force;
// Limit max speed
var currentSpeed = Math.sqrt(player.velocityX * player.velocityX + player.velocityY * player.velocityY);
if (currentSpeed > player.maxSpeed) {
player.velocityX = player.velocityX / currentSpeed * player.maxSpeed;
player.velocityY = player.velocityY / currentSpeed * player.maxSpeed;
}
}
LK.getSound('whoosh').play();
}
} else if (currentLevel === 3) {
// Level 3: Tap to start/stop coaster
if (coasterCar) {
coasterCar.moving = !coasterCar.moving;
LK.getSound('bell').play();
}
}
};
// Main game update loop
game.update = function () {
if (gameState !== 'playing') return;
if (currentLevel === 1) {
updateLevel1();
} else if (currentLevel === 2) {
updateLevel2();
} else if (currentLevel === 3) {
updateLevel3();
}
// Update score display
scoreText.setText('Score: ' + (totalScore + levelScore));
};
function updateLevel1() {
// Spawn targets
targetSpawnTimer++;
if (targetSpawnTimer > 180 && targets.length < 5) {
// Every 3 seconds
createTarget();
targetSpawnTimer = 0;
}
// Update snowballs
for (var i = snowballs.length - 1; i >= 0; i--) {
var snowball = snowballs[i];
if (!snowball.active) {
snowball.destroy();
snowballs.splice(i, 1);
continue;
}
// Check collision with targets
for (var j = targets.length - 1; j >= 0; j--) {
var target = targets[j];
if (target.active && snowball.intersects(target)) {
// Hit!
levelScore += 10;
LK.getSound('hit').play();
// Remove both objects
snowball.active = false;
target.active = false;
target.destroy();
targets.splice(j, 1);
// Flash effect
LK.effects.flashObject(snowball, 0xFFFF00, 200);
break;
}
}
}
// Update targets
for (var i = targets.length - 1; i >= 0; i--) {
var target = targets[i];
if (!target.active) {
target.destroy();
targets.splice(i, 1);
}
}
// Level completion check
if (levelScore >= 100) {
completeLevel();
}
}
function updateLevel2() {
if (!player) return;
// Check collision with hills (score points)
for (var i = 0; i < hills.length; i++) {
var hill = hills[i];
if (player.intersects(hill)) {
levelScore += 5;
LK.effects.flashObject(hill, 0x00FF00, 300);
// Move hill to new position
hill.x = Math.random() * 1748 + 150;
hill.y = Math.random() * 1000 + 800;
}
}
// Level completion check
if (levelScore >= 150) {
completeLevel();
}
}
function updateLevel3() {
if (!coasterCar) return;
coasterTimer++;
// Spawn snowflakes
snowflakeTimer++;
if (snowflakeTimer > 30) {
// Every 0.5 seconds
createSnowflake();
snowflakeTimer = 0;
}
// Update snowflakes
for (var i = snowflakes.length - 1; i >= 0; i--) {
var snowflake = snowflakes[i];
if (!snowflake.active) {
snowflake.destroy();
snowflakes.splice(i, 1);
continue;
}
// Check collision with coaster (only when moving)
if (coasterCar.moving && snowflake.intersects(coasterCar)) {
levelScore += 2;
snowflake.active = false;
LK.effects.flashObject(snowflake, 0x00FFFF, 200);
}
}
// Score points for moving
if (coasterCar.moving) {
coasterScore++;
if (coasterScore % 60 === 0) {
// Every second
levelScore += 1;
}
}
// Level completion check
if (levelScore >= 200) {
completeLevel();
}
}
function completeLevel() {
gameState = 'levelComplete';
totalScore += levelScore;
// Flash screen
LK.effects.flashScreen(0x00FF00, 1000);
// Move to next level or complete game
LK.setTimeout(function () {
if (currentLevel < 3) {
if (currentLevel === 1) {
initLevel2();
} else if (currentLevel === 2) {
initLevel3();
}
} else {
// Game complete
gameState = 'gameComplete';
LK.setScore(totalScore);
LK.showYouWin();
}
}, 1500);
}
// Initialize the game
initLevel1(); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var CoasterCar = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('coasterCar', {
anchorX: 0.5,
anchorY: 0.5
});
self.moving = false;
self.speed = 3;
self.direction = 1;
self.trackPosition = 0;
self.update = function () {
if (self.moving) {
self.trackPosition += self.speed * self.direction;
// Simple track movement (left-right)
if (self.trackPosition > 400) {
self.trackPosition = 400;
self.direction = -1;
} else if (self.trackPosition < 0) {
self.trackPosition = 0;
self.direction = 1;
}
self.x = 824 + self.trackPosition; // Center track at 1024
}
};
return self;
});
var Sled = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('sled', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.speed = 0;
self.maxSpeed = 8;
self.friction = 0.98;
self.update = function () {
// Apply movement
self.x += self.velocityX;
self.y += self.velocityY;
// Apply friction
self.velocityX *= self.friction;
self.velocityY *= self.friction;
// Keep in bounds
self.x = Math.max(70, Math.min(1978, self.x));
self.y = Math.max(70, Math.min(2662, self.y));
};
return self;
});
var Snowball = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('snowball', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.active = true;
self.update = function () {
if (!self.active) return;
self.x += self.velocityX;
self.y += self.velocityY;
// Remove if off screen
if (self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782) {
self.active = false;
}
};
return self;
});
var Snowflake = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('snowflake', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityY = Math.random() * 2 + 1;
self.velocityX = (Math.random() - 0.5) * 0.5;
self.active = true;
self.update = function () {
if (!self.active) return;
self.x += self.velocityX;
self.y += self.velocityY;
if (self.y > 2732) {
self.active = false;
}
};
return self;
});
var Target = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('target', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = (Math.random() - 0.5) * 4;
self.velocityY = (Math.random() - 0.5) * 2;
self.active = true;
self.lastX = self.x;
self.lastY = self.y;
self.update = function () {
if (!self.active) return;
self.lastX = self.x;
self.lastY = self.y;
self.x += self.velocityX;
self.y += self.velocityY;
// Bounce off walls
if (self.x < 50 || self.x > 1998) {
self.velocityX *= -1;
}
if (self.y < 200 || self.y > 1500) {
self.velocityY *= -1;
}
// Keep in bounds
self.x = Math.max(50, Math.min(1998, self.x));
self.y = Math.max(200, Math.min(1500, self.y));
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
// Sounds
// UI elements
// Characters and objects
// Level backgrounds
// Game state variables
var currentLevel = 1;
var gameState = 'playing'; // 'playing', 'levelComplete', 'gameComplete'
var levelScore = 0;
var totalScore = 0;
// Level 1 variables
var snowballs = [];
var targets = [];
var targetSpawnTimer = 0;
// Level 2 variables
var player = null;
var hills = [];
var sledPower = 0;
var sledding = false;
// Level 3 variables
var coasterCar = null;
var snowflakes = [];
var snowflakeTimer = 0;
var coasterScore = 0;
var coasterTimer = 0;
// UI Elements
var levelText = new Text2('Level 1: Snowball Fight', {
size: 80,
fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(1, 0);
LK.gui.topRight.addChild(scoreText);
var instructionText = new Text2('Tap targets to throw snowballs!', {
size: 50,
fill: 0xFFFFFF
});
instructionText.anchor.set(0.5, 0);
instructionText.y = 120;
LK.gui.top.addChild(instructionText);
// Initialize Level 1
function initLevel1() {
currentLevel = 1;
levelScore = 0;
gameState = 'playing';
// Clear arrays
snowballs = [];
targets = [];
// Update UI
levelText.setText('Level 1: Snowball Fight');
instructionText.setText('Tap targets to throw snowballs!');
// Create background
var bg = game.addChild(LK.getAsset('level1Background', {
x: 0,
y: 0
}));
// Create initial targets
for (var i = 0; i < 3; i++) {
createTarget();
}
}
// Initialize Level 2
function initLevel2() {
currentLevel = 2;
levelScore = 0;
gameState = 'playing';
// Clear previous level
clearLevel();
// Update UI
levelText.setText('Level 2: Sledding');
instructionText.setText('Tap to control your sled!');
// Create background
var bg = game.addChild(LK.getAsset('level2Background', {
x: 0,
y: 0
}));
// Create hills
for (var i = 0; i < 5; i++) {
var hill = game.addChild(LK.getAsset('hill', {
x: Math.random() * 1748 + 150,
y: Math.random() * 1000 + 800,
anchorX: 0.5,
anchorY: 0.5
}));
hills.push(hill);
}
// Create sled
player = game.addChild(new Sled());
player.x = 1024;
player.y = 500;
}
// Initialize Level 3
function initLevel3() {
currentLevel = 3;
levelScore = 0;
gameState = 'playing';
coasterScore = 0;
coasterTimer = 0;
// Clear previous level
clearLevel();
// Update UI
levelText.setText('Level 3: Snow Roller Coaster');
instructionText.setText('Tap to start/stop the coaster!');
// Create background
var bg = game.addChild(LK.getAsset('level3Background', {
x: 0,
y: 0
}));
// Create track
var track = game.addChild(LK.getAsset('track', {
x: 1024,
y: 1366,
anchorX: 0.5,
anchorY: 0.5
}));
// Create coaster car
coasterCar = game.addChild(new CoasterCar());
coasterCar.x = 1024;
coasterCar.y = 1366;
snowflakes = [];
}
function clearLevel() {
// Remove all children except UI
while (game.children.length > 0) {
var child = game.children[0];
child.destroy();
}
// Clear arrays
snowballs = [];
targets = [];
hills = [];
snowflakes = [];
player = null;
coasterCar = null;
}
function createTarget() {
var target = game.addChild(new Target());
target.x = Math.random() * 1600 + 224;
target.y = Math.random() * 1000 + 400;
targets.push(target);
}
function createSnowball(targetX, targetY) {
var snowball = game.addChild(new Snowball());
snowball.x = 1024; // Center of screen
snowball.y = 2200; // Bottom of screen
// Calculate velocity towards target
var dx = targetX - snowball.x;
var dy = targetY - snowball.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var speed = 12;
snowball.velocityX = dx / distance * speed;
snowball.velocityY = dy / distance * speed;
snowballs.push(snowball);
LK.getSound('throw').play();
}
function createSnowflake() {
var snowflake = game.addChild(new Snowflake());
snowflake.x = Math.random() * 2048;
snowflake.y = -20;
snowflakes.push(snowflake);
}
// Game input handlers
game.down = function (x, y, obj) {
if (gameState !== 'playing') return;
if (currentLevel === 1) {
// Level 1: Tap to throw snowball
createSnowball(x, y);
} else if (currentLevel === 2) {
// Level 2: Tap to boost sled
if (player) {
var dx = x - player.x;
var dy = y - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
var force = 3;
player.velocityX += dx / distance * force;
player.velocityY += dy / distance * force;
// Limit max speed
var currentSpeed = Math.sqrt(player.velocityX * player.velocityX + player.velocityY * player.velocityY);
if (currentSpeed > player.maxSpeed) {
player.velocityX = player.velocityX / currentSpeed * player.maxSpeed;
player.velocityY = player.velocityY / currentSpeed * player.maxSpeed;
}
}
LK.getSound('whoosh').play();
}
} else if (currentLevel === 3) {
// Level 3: Tap to start/stop coaster
if (coasterCar) {
coasterCar.moving = !coasterCar.moving;
LK.getSound('bell').play();
}
}
};
// Main game update loop
game.update = function () {
if (gameState !== 'playing') return;
if (currentLevel === 1) {
updateLevel1();
} else if (currentLevel === 2) {
updateLevel2();
} else if (currentLevel === 3) {
updateLevel3();
}
// Update score display
scoreText.setText('Score: ' + (totalScore + levelScore));
};
function updateLevel1() {
// Spawn targets
targetSpawnTimer++;
if (targetSpawnTimer > 180 && targets.length < 5) {
// Every 3 seconds
createTarget();
targetSpawnTimer = 0;
}
// Update snowballs
for (var i = snowballs.length - 1; i >= 0; i--) {
var snowball = snowballs[i];
if (!snowball.active) {
snowball.destroy();
snowballs.splice(i, 1);
continue;
}
// Check collision with targets
for (var j = targets.length - 1; j >= 0; j--) {
var target = targets[j];
if (target.active && snowball.intersects(target)) {
// Hit!
levelScore += 10;
LK.getSound('hit').play();
// Remove both objects
snowball.active = false;
target.active = false;
target.destroy();
targets.splice(j, 1);
// Flash effect
LK.effects.flashObject(snowball, 0xFFFF00, 200);
break;
}
}
}
// Update targets
for (var i = targets.length - 1; i >= 0; i--) {
var target = targets[i];
if (!target.active) {
target.destroy();
targets.splice(i, 1);
}
}
// Level completion check
if (levelScore >= 100) {
completeLevel();
}
}
function updateLevel2() {
if (!player) return;
// Check collision with hills (score points)
for (var i = 0; i < hills.length; i++) {
var hill = hills[i];
if (player.intersects(hill)) {
levelScore += 5;
LK.effects.flashObject(hill, 0x00FF00, 300);
// Move hill to new position
hill.x = Math.random() * 1748 + 150;
hill.y = Math.random() * 1000 + 800;
}
}
// Level completion check
if (levelScore >= 150) {
completeLevel();
}
}
function updateLevel3() {
if (!coasterCar) return;
coasterTimer++;
// Spawn snowflakes
snowflakeTimer++;
if (snowflakeTimer > 30) {
// Every 0.5 seconds
createSnowflake();
snowflakeTimer = 0;
}
// Update snowflakes
for (var i = snowflakes.length - 1; i >= 0; i--) {
var snowflake = snowflakes[i];
if (!snowflake.active) {
snowflake.destroy();
snowflakes.splice(i, 1);
continue;
}
// Check collision with coaster (only when moving)
if (coasterCar.moving && snowflake.intersects(coasterCar)) {
levelScore += 2;
snowflake.active = false;
LK.effects.flashObject(snowflake, 0x00FFFF, 200);
}
}
// Score points for moving
if (coasterCar.moving) {
coasterScore++;
if (coasterScore % 60 === 0) {
// Every second
levelScore += 1;
}
}
// Level completion check
if (levelScore >= 200) {
completeLevel();
}
}
function completeLevel() {
gameState = 'levelComplete';
totalScore += levelScore;
// Flash screen
LK.effects.flashScreen(0x00FF00, 1000);
// Move to next level or complete game
LK.setTimeout(function () {
if (currentLevel < 3) {
if (currentLevel === 1) {
initLevel2();
} else if (currentLevel === 2) {
initLevel3();
}
} else {
// Game complete
gameState = 'gameComplete';
LK.setScore(totalScore);
LK.showYouWin();
}
}, 1500);
}
// Initialize the game
initLevel1();