/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var BrokenPlatform = Container.expand(function () { var self = Container.call(this); var platformGraphics = self.attachAsset('brokenPlatform', { anchorX: 0.5, anchorY: 0.5 }); self.isBroken = false; self.breakTimer = 0; self.fallSpeed = 8; self["break"] = function () { if (!self.isBroken) { self.isBroken = true; // Flash red to indicate breaking LK.effects.flashObject(self, 0xff0000, 300); } }; self.update = function () { if (self.isBroken) { self.breakTimer++; // Start falling after a short delay if (self.breakTimer > 20) { self.y += self.fallSpeed; } } }; return self; }); //Library for using the camera (the background becomes the user's camera video feed) and the microphone. It can access face coordinates for interactive play, as well detect microphone volume / voice interactions // var facekit = LK.import('@upit/facekit.v1'); // Not needed for this game var Hero = Container.expand(function () { var self = Container.call(this); var heroGraphics = self.attachAsset('hero', { anchorX: 0.5, anchorY: 0.5 }); self.speedY = 0; self.gravity = 1; self.isJumping = false; // Track if the hero is currently jumping self.heroGraphics = heroGraphics; // Reference to the graphics for animation self.jump = function () { self.speedY = -30; // Jump strength LK.getSound('jump').play(); self.isJumping = true; // Set jumping state to true }; self.update = function () { self.speedY += self.gravity; self.y += self.speedY; // Check if the hero has landed on a platform (speedY becomes 0 after collision) if (self.speedY === 0 && self.isJumping) { self.isJumping = false; // Hero is no longer jumping } // If hero falls off the bottom, trigger game over. if (self.y > 2732) { LK.getSound('hit').play(); LK.showGameOver(); return; // Stop updating if game over } // Keep hero within horizontal bounds if (self.x < self.width / 2) { self.x = self.width / 2; } else if (self.x > 2048 - self.width / 2) { self.x = 2048 - self.width / 2; } // Change hero graphic based on jumping state if (self.isJumping) { self.heroGraphics.texture = LK.getAsset('hero2', {}).texture; // Use hero2 texture } else { self.heroGraphics.texture = LK.getAsset('hero', {}).texture; // Use hero texture } }; return self; }); var Obstacle = Container.expand(function () { var self = Container.call(this); var obstacleGraphics = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5 }); self.speedY = 5; // Obstacle falling speed self.update = function () { self.y += self.speedY; }; return self; }); var Platform = Container.expand(function () { var self = Container.call(this); var platformGraphics = self.attachAsset('platform', { anchorX: 0.5, anchorY: 0.5 }); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 // Init game with black background }); /**** * Game Code ****/ // Initialize assets used in this game. Scale them according to what is needed for the game. // Initialize music //We have access to the following plugins. (Note that the variable names used are mandetory for each plugin) //Only include the plugins you need to create the game. //Minimalistic tween library which should be used for animations over time, including tinting / colouring an object, scaling, rotating, or changing any game object property. //Storage library which should be used for persistent game data game.setBackgroundColor(0x87ceeb); // Change background color to sky blue var hero; var platforms = []; var obstacles = []; var scoreTxt; var score = 0; var platformSpawnTimer = 0; var obstacleSpawnTimer = 0; var heroLastY = 0; // To track vertical progress for scoring var highestY = 0; // Initialize the highest point reached globally var highestLevel = 0; // Track the highest level reached for scoring //Declare method for handling move events on game. //Favor using a single event handler in the game scope, rather than a per class event handler //Mouse or touch move on game object. LK returns complex event objects. Please be aware of this. game.move = function (x, y, obj) { if (hero) { // Move hero horizontally based on touch/mouse x position hero.x = x; } }; //Mouse or touch down on game object game.down = function (x, y, obj) { if (hero) { hero.jump(); } }; // Initialize game elements function startGame() { // Clear existing elements if (hero) hero.destroy(); for (var i = platforms.length - 1; i >= 0; i--) platforms[i].destroy(); for (var i = obstacles.length - 1; i >= 0; i--) obstacles[i].destroy(); platforms = []; obstacles = []; platformSpawnTimer = 0; obstacleSpawnTimer = 0; hero = game.addChild(new Hero()); // Add initial platform var initialPlatform = new Platform(); initialPlatform.x = 2048 / 2; // Keep centered horizontally for the first platform initialPlatform.y = 2732 - initialPlatform.height / 2 - hero.height / 2; // Position just above the bottom platforms.push(initialPlatform); game.addChild(initialPlatform); // Position hero at the top of the first platform hero.x = initialPlatform.x; hero.y = initialPlatform.y - initialPlatform.height / 2 - hero.height / 2; heroLastY = hero.y; highestY = hero.y; // Initialize the highest point reached highestLevel = 0; // Reset level tracking for new game score = 0; // Reset score for new game LK.setScore(0); // Ensure LK score is also reset for equal progression scoreTxt = new Text2('0', { size: 150, fill: 0xFFFFFF }); LK.gui.top.addChild(scoreTxt); // Create several starting platforms at different positions for (var i = 0; i < 5; i++) { // Create 5 additional platforms var platform = new Platform(); platform.x = Math.random() * (2048 - platform.width) + platform.width / 2; // Random X position // Position platforms stacked above the initial one platform.y = initialPlatform.y - (i + 1) * 300; // Adjust vertical spacing between platforms platforms.push(platform); game.addChild(platform); } LK.playMusic('gameMusic'); } startGame(); // Call startGame to initialize the game // Ask LK engine to update game every game tick game.update = function () { // Update hero if (hero) hero.update(); // Platforms and obstacles move at their own fixed speeds // Update platforms and check for collision for (var i = platforms.length - 1; i >= 0; i--) { var platform = platforms[i]; // Update platform (for broken platforms to handle falling) if (platform.update) { platform.update(); } // Platforms now move only downwards at their own speed, not affected by scrollSpeed platform.y += 3; // Fixed downward speed for platforms // Check for hero landing on platform if (hero && hero.speedY > 0 && hero.intersects(platform) && hero.y < platform.y - platform.height / 2 + hero.speedY) { hero.y = platform.y - platform.height / 2 - hero.height / 2; hero.speedY = 0; // Break the platform if it's a broken platform if (platform["break"]) { platform["break"](); } } // Remove platforms that are off-screen below if (platform.y > 2732 + platform.height) { platform.destroy(); platforms.splice(i, 1); } } // Update obstacles and check for collision for (var i = obstacles.length - 1; i >= 0; i--) { var obstacle = obstacles[i]; obstacle.y += obstacle.speedY; // Move obstacle down at its own speed // Check for collision with hero if (hero && hero.intersects(obstacle)) { // Hero hit by obstacle - Game Over LK.getSound('hit').play(); LK.effects.flashScreen(0xff0000, 500); LK.showGameOver(); // No need to destroy elements here, LK.showGameOver will reset the game return; // Stop updating if game over } // Update score based on highest level reached if (hero && hero.y < highestY) { highestY = hero.y; // Calculate current level based on height with better distribution // Use 250 pixels per level for more even scoring progression var currentLevel = Math.floor((2732 - highestY) / 250); // Award 10 points for each new level reached if (currentLevel > highestLevel) { highestLevel = currentLevel; score = highestLevel * 10; // Score equals 10 times the highest level reached LK.setScore(score); // Update LK score system scoreTxt.setText(score); } } // Remove obstacles that are off-screen below if (obstacle.y > 2732 + obstacle.height) { obstacle.destroy(); obstacles.splice(i, 1); } } // Spawn platforms platformSpawnTimer++; if (platformSpawnTimer >= 60) { // Spawn a platform roughly every second var newPlatform; // 30% chance to spawn a broken platform if (Math.random() < 0.3) { newPlatform = new BrokenPlatform(); } else { newPlatform = new Platform(); } // Position platform off-screen at the top newPlatform.x = Math.random() * (2048 - newPlatform.width) + newPlatform.width / 2; // Random X position within screen width // Find the highest existing platform var highestPlatformY = Infinity; for (var i = 0; i < platforms.length; i++) { if (platforms[i].y < highestPlatformY) { highestPlatformY = platforms[i].y; } } // Position the new platform just above the highest existing one newPlatform.y = highestPlatformY - 300; // Adjust vertical spacing as needed platforms.push(newPlatform); game.addChild(newPlatform); platformSpawnTimer = 0; } // Spawn obstacles obstacleSpawnTimer++; if (obstacleSpawnTimer >= 90) { // Spawn an obstacle roughly every 1.5 seconds var newObstacle = new Obstacle(); // Position obstacle off-screen at the top newObstacle.x = Math.random() * (2048 - newObstacle.width) + newObstacle.width / 2; newObstacle.y = -newObstacle.height / 2; obstacles.push(newObstacle); game.addChild(newObstacle); obstacleSpawnTimer = 0; } // Prevent hero from falling off the top (if somehow possible with gravity) if (hero && hero.y < -hero.height) { // This shouldn't happen with normal gameplay, but as a safeguard: // Treat as game over if the hero goes too far off the top LK.getSound('hit').play(); LK.showGameOver(); return; } // Check if hero has fallen off the bottom of the screen if (hero && hero.y > 2732) { LK.getSound('hit').play(); LK.showGameOver(); return; // Stop updating if game over } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var BrokenPlatform = Container.expand(function () {
var self = Container.call(this);
var platformGraphics = self.attachAsset('brokenPlatform', {
anchorX: 0.5,
anchorY: 0.5
});
self.isBroken = false;
self.breakTimer = 0;
self.fallSpeed = 8;
self["break"] = function () {
if (!self.isBroken) {
self.isBroken = true;
// Flash red to indicate breaking
LK.effects.flashObject(self, 0xff0000, 300);
}
};
self.update = function () {
if (self.isBroken) {
self.breakTimer++;
// Start falling after a short delay
if (self.breakTimer > 20) {
self.y += self.fallSpeed;
}
}
};
return self;
});
//Library for using the camera (the background becomes the user's camera video feed) and the microphone. It can access face coordinates for interactive play, as well detect microphone volume / voice interactions
// var facekit = LK.import('@upit/facekit.v1'); // Not needed for this game
var Hero = Container.expand(function () {
var self = Container.call(this);
var heroGraphics = self.attachAsset('hero', {
anchorX: 0.5,
anchorY: 0.5
});
self.speedY = 0;
self.gravity = 1;
self.isJumping = false; // Track if the hero is currently jumping
self.heroGraphics = heroGraphics; // Reference to the graphics for animation
self.jump = function () {
self.speedY = -30; // Jump strength
LK.getSound('jump').play();
self.isJumping = true; // Set jumping state to true
};
self.update = function () {
self.speedY += self.gravity;
self.y += self.speedY;
// Check if the hero has landed on a platform (speedY becomes 0 after collision)
if (self.speedY === 0 && self.isJumping) {
self.isJumping = false; // Hero is no longer jumping
}
// If hero falls off the bottom, trigger game over.
if (self.y > 2732) {
LK.getSound('hit').play();
LK.showGameOver();
return; // Stop updating if game over
}
// Keep hero within horizontal bounds
if (self.x < self.width / 2) {
self.x = self.width / 2;
} else if (self.x > 2048 - self.width / 2) {
self.x = 2048 - self.width / 2;
}
// Change hero graphic based on jumping state
if (self.isJumping) {
self.heroGraphics.texture = LK.getAsset('hero2', {}).texture; // Use hero2 texture
} else {
self.heroGraphics.texture = LK.getAsset('hero', {}).texture; // Use hero texture
}
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.speedY = 5; // Obstacle falling speed
self.update = function () {
self.y += self.speedY;
};
return self;
});
var Platform = Container.expand(function () {
var self = Container.call(this);
var platformGraphics = self.attachAsset('platform', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000 // Init game with black background
});
/****
* Game Code
****/
// Initialize assets used in this game. Scale them according to what is needed for the game.
// Initialize music
//We have access to the following plugins. (Note that the variable names used are mandetory for each plugin)
//Only include the plugins you need to create the game.
//Minimalistic tween library which should be used for animations over time, including tinting / colouring an object, scaling, rotating, or changing any game object property.
//Storage library which should be used for persistent game data
game.setBackgroundColor(0x87ceeb); // Change background color to sky blue
var hero;
var platforms = [];
var obstacles = [];
var scoreTxt;
var score = 0;
var platformSpawnTimer = 0;
var obstacleSpawnTimer = 0;
var heroLastY = 0; // To track vertical progress for scoring
var highestY = 0; // Initialize the highest point reached globally
var highestLevel = 0; // Track the highest level reached for scoring
//Declare method for handling move events on game.
//Favor using a single event handler in the game scope, rather than a per class event handler
//Mouse or touch move on game object. LK returns complex event objects. Please be aware of this.
game.move = function (x, y, obj) {
if (hero) {
// Move hero horizontally based on touch/mouse x position
hero.x = x;
}
};
//Mouse or touch down on game object
game.down = function (x, y, obj) {
if (hero) {
hero.jump();
}
};
// Initialize game elements
function startGame() {
// Clear existing elements
if (hero) hero.destroy();
for (var i = platforms.length - 1; i >= 0; i--) platforms[i].destroy();
for (var i = obstacles.length - 1; i >= 0; i--) obstacles[i].destroy();
platforms = [];
obstacles = [];
platformSpawnTimer = 0;
obstacleSpawnTimer = 0;
hero = game.addChild(new Hero());
// Add initial platform
var initialPlatform = new Platform();
initialPlatform.x = 2048 / 2; // Keep centered horizontally for the first platform
initialPlatform.y = 2732 - initialPlatform.height / 2 - hero.height / 2; // Position just above the bottom
platforms.push(initialPlatform);
game.addChild(initialPlatform);
// Position hero at the top of the first platform
hero.x = initialPlatform.x;
hero.y = initialPlatform.y - initialPlatform.height / 2 - hero.height / 2;
heroLastY = hero.y;
highestY = hero.y; // Initialize the highest point reached
highestLevel = 0; // Reset level tracking for new game
score = 0; // Reset score for new game
LK.setScore(0); // Ensure LK score is also reset for equal progression
scoreTxt = new Text2('0', {
size: 150,
fill: 0xFFFFFF
});
LK.gui.top.addChild(scoreTxt);
// Create several starting platforms at different positions
for (var i = 0; i < 5; i++) {
// Create 5 additional platforms
var platform = new Platform();
platform.x = Math.random() * (2048 - platform.width) + platform.width / 2; // Random X position
// Position platforms stacked above the initial one
platform.y = initialPlatform.y - (i + 1) * 300; // Adjust vertical spacing between platforms
platforms.push(platform);
game.addChild(platform);
}
LK.playMusic('gameMusic');
}
startGame(); // Call startGame to initialize the game
// Ask LK engine to update game every game tick
game.update = function () {
// Update hero
if (hero) hero.update();
// Platforms and obstacles move at their own fixed speeds
// Update platforms and check for collision
for (var i = platforms.length - 1; i >= 0; i--) {
var platform = platforms[i];
// Update platform (for broken platforms to handle falling)
if (platform.update) {
platform.update();
}
// Platforms now move only downwards at their own speed, not affected by scrollSpeed
platform.y += 3; // Fixed downward speed for platforms
// Check for hero landing on platform
if (hero && hero.speedY > 0 && hero.intersects(platform) && hero.y < platform.y - platform.height / 2 + hero.speedY) {
hero.y = platform.y - platform.height / 2 - hero.height / 2;
hero.speedY = 0;
// Break the platform if it's a broken platform
if (platform["break"]) {
platform["break"]();
}
}
// Remove platforms that are off-screen below
if (platform.y > 2732 + platform.height) {
platform.destroy();
platforms.splice(i, 1);
}
}
// Update obstacles and check for collision
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
obstacle.y += obstacle.speedY; // Move obstacle down at its own speed
// Check for collision with hero
if (hero && hero.intersects(obstacle)) {
// Hero hit by obstacle - Game Over
LK.getSound('hit').play();
LK.effects.flashScreen(0xff0000, 500);
LK.showGameOver();
// No need to destroy elements here, LK.showGameOver will reset the game
return; // Stop updating if game over
}
// Update score based on highest level reached
if (hero && hero.y < highestY) {
highestY = hero.y;
// Calculate current level based on height with better distribution
// Use 250 pixels per level for more even scoring progression
var currentLevel = Math.floor((2732 - highestY) / 250);
// Award 10 points for each new level reached
if (currentLevel > highestLevel) {
highestLevel = currentLevel;
score = highestLevel * 10; // Score equals 10 times the highest level reached
LK.setScore(score); // Update LK score system
scoreTxt.setText(score);
}
}
// Remove obstacles that are off-screen below
if (obstacle.y > 2732 + obstacle.height) {
obstacle.destroy();
obstacles.splice(i, 1);
}
}
// Spawn platforms
platformSpawnTimer++;
if (platformSpawnTimer >= 60) {
// Spawn a platform roughly every second
var newPlatform;
// 30% chance to spawn a broken platform
if (Math.random() < 0.3) {
newPlatform = new BrokenPlatform();
} else {
newPlatform = new Platform();
}
// Position platform off-screen at the top
newPlatform.x = Math.random() * (2048 - newPlatform.width) + newPlatform.width / 2; // Random X position within screen width
// Find the highest existing platform
var highestPlatformY = Infinity;
for (var i = 0; i < platforms.length; i++) {
if (platforms[i].y < highestPlatformY) {
highestPlatformY = platforms[i].y;
}
}
// Position the new platform just above the highest existing one
newPlatform.y = highestPlatformY - 300; // Adjust vertical spacing as needed
platforms.push(newPlatform);
game.addChild(newPlatform);
platformSpawnTimer = 0;
}
// Spawn obstacles
obstacleSpawnTimer++;
if (obstacleSpawnTimer >= 90) {
// Spawn an obstacle roughly every 1.5 seconds
var newObstacle = new Obstacle();
// Position obstacle off-screen at the top
newObstacle.x = Math.random() * (2048 - newObstacle.width) + newObstacle.width / 2;
newObstacle.y = -newObstacle.height / 2;
obstacles.push(newObstacle);
game.addChild(newObstacle);
obstacleSpawnTimer = 0;
}
// Prevent hero from falling off the top (if somehow possible with gravity)
if (hero && hero.y < -hero.height) {
// This shouldn't happen with normal gameplay, but as a safeguard:
// Treat as game over if the hero goes too far off the top
LK.getSound('hit').play();
LK.showGameOver();
return;
}
// Check if hero has fallen off the bottom of the screen
if (hero && hero.y > 2732) {
LK.getSound('hit').play();
LK.showGameOver();
return; // Stop updating if game over
}
};