/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Coin class var Coin = Container.expand(function () { var self = Container.call(this); var coinSprite = self.attachAsset('coin', { anchorX: 0.5, anchorY: 0.5 }); self.width = coinSprite.width; self.height = coinSprite.height; return self; }); // Enemy class var Enemy = Container.expand(function () { var self = Container.call(this); // Attach enemy asset (blue box) var enemySprite = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 0 }); self.width = enemySprite.width; self.height = enemySprite.height; // Enemy stays on the ground and moves only a little left-right self.vx = 0; self.moveRange = 40; // smaller movement range self.baseX = 0; self.update = function () { // Always keep enemy at ground level // Find the highest platform directly under the enemy's x position var bestPlatY = groundY; for (var i = 0; i < platforms.length; i++) { var plat = platforms[i]; // Check if enemy is horizontally over the platform if (self.x + self.width * 0.4 > plat.x && self.x - self.width * 0.4 < plat.x + plat.width) { if (plat.y < bestPlatY) { bestPlatY = plat.y; } } } self.y = bestPlatY - self.height; // Optionally, add some small movement if (self.baseX === 0) { self.baseX = self.x; } self.x = self.baseX + Math.sin(LK.ticks / 60) * self.moveRange; }; return self; }); // Flag class var Flag = Container.expand(function () { var self = Container.call(this); var flagSprite = self.attachAsset('flag', { anchorX: 0.5, anchorY: 1 }); self.width = flagSprite.width; self.height = flagSprite.height; return self; }); // Platform class var Platform = Container.expand(function () { var self = Container.call(this); // Attach platform asset (green box) var platformSprite = self.attachAsset('platform', { anchorX: 0, anchorY: 0 }); self.width = platformSprite.width; self.height = platformSprite.height; // Platforms are static, but can be moved for scrolling self.update = function () { // Platforms are stationary; do not move. }; return self; }); // Player class var Player = Container.expand(function () { var self = Container.call(this); // Attach player asset (red box) var playerSprite = self.attachAsset('player', { anchorX: 0.5, anchorY: 1 }); // Physics properties self.vx = 0; self.vy = 0; self.isOnGround = false; self.width = playerSprite.width; self.height = playerSprite.height; // Jumping state self.isJumping = false; // Update method called every tick self.update = function () { // Gravity self.vy += gravity; // Horizontal movement (auto-run) self.x += self.vx; // Vertical movement self.y += self.vy; // Prevent falling below ground if (self.y > groundY) { self.y = groundY; self.vy = 0; self.isOnGround = true; self.isJumping = false; } else { self.isOnGround = false; } }; // Jump method self.jump = function () { if (self.isOnGround && !self.isJumping) { self.vy = -jumpStrength; self.isJumping = true; self.isOnGround = false; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87ceeb // Sky blue }); /**** * Game Code ****/ // --- Game constants --- // Tween plugin for animations var gravity = 1.2; var jumpStrength = 32; var scrollSpeed = 7; var groundY = 2300; // Y position of the ground/platforms // --- Game state --- var player; var platforms = []; var enemies = []; var flag; var coin; var lives = 3; var level = 1; var isGameOver = false; var isYouWin = false; // --- GUI elements --- var livesTxt = new Text2('♥♥♥', { size: 100, fill: 0xFF4444 }); // Anchor left, top livesTxt.anchor.set(0, 0); // Place at x=110 to avoid top-left menu, y=0 livesTxt.x = 110; livesTxt.y = 0; LK.gui.top.addChild(livesTxt); // Score variable and score text var score = 0; var scoreTxt = new Text2('0', { size: 100, fill: 0xffffff }); scoreTxt.anchor.set(0.5, 0); // center, top scoreTxt.x = 2048 / 2; scoreTxt.y = 0; LK.gui.top.addChild(scoreTxt); // --- Asset initialization (shapes) --- // --- Helper functions --- // Create a platform at (x, y) with optional width function createPlatform(x, y, width) { var plat = new Platform(); plat.x = x; plat.y = y; if (width) { plat.width = width; } platforms.push(plat); game.addChild(plat); return plat; } // Create an enemy at (x, y) function createEnemy(x, y) { var enemy = new Enemy(); enemy.x = x; enemy.y = y; enemies.push(enemy); game.addChild(enemy); return enemy; } // Reset game state for new game or level function resetGame() { // Remove all platforms and enemies for (var i = 0; i < platforms.length; i++) { platforms[i].destroy(); } for (var i = 0; i < enemies.length; i++) { enemies[i].destroy(); } if (flag) { flag.destroy(); flag = null; } if (coin) { coin.destroy(); coin = null; } platforms = []; enemies = []; // Reset lives lives = 3; level = 1; isGameOver = false; isYouWin = false; livesTxt.setText('♥♥♥'); // Reset score score = 0; scoreTxt.setText(score); // Create player if (player) { player.destroy(); } player = new Player(); player.x = 300; player.y = groundY; player.vx = scrollSpeed; game.addChild(player); // Create level createLevel(level); } // Create a level layout function createLevel(levelNum) { // Simple level: ground platform, some floating platforms, coins, enemies // Ground (very extended) createPlatform(0, groundY, 20000); // No floating platforms // Enemies (on ground, spread out and more of them) createEnemy(1200, groundY - 160 + 240); createEnemy(2000, groundY - 160 + 240); createEnemy(3000, groundY - 160 + 240); createEnemy(4000, groundY - 160 + 240); createEnemy(5200, groundY - 160 + 240); createEnemy(6500, groundY - 160 + 240); createEnemy(7500, groundY - 160 + 240); // End flag (no floating platform needed) // Place flag much farther to the right and keep it stationary flag = new Flag(); flag.x = 8000; flag.y = groundY; game.addChild(flag); } // --- Collision detection --- function rectsIntersect(a, b) { return a.x - a.width * 0.5 < b.x + b.width * 0.5 && a.x + a.width * 0.5 > b.x - b.width * 0.5 && a.y - a.height < b.y && a.y > b.y - b.height; } // --- Touch controls --- // Touch anywhere to jump game.down = function (x, y, obj) { if (isGameOver || isYouWin) { return; } player.jump(); }; // --- Main game update loop --- game.update = function () { if (isGameOver || isYouWin) { return; } // Update player player.update(); // Camera: keep player at 1/3 of screen, scroll world var cameraX = player.x - 600; if (cameraX < 0) { cameraX = 0; } // Move the game container so the player is always followed by the camera game.x = -cameraX; // Update platforms for (var i = platforms.length - 1; i >= 0; i--) { var plat = platforms[i]; plat.update(); // Remove platforms that are off screen if (plat.x + plat.width < cameraX - 200) { plat.destroy(); platforms.splice(i, 1); } } // Update enemies for (var i = enemies.length - 1; i >= 0; i--) { var enemy = enemies[i]; enemy.update(); // Remove enemies that are off screen if (enemy.x < cameraX - 200) { enemy.destroy(); enemies.splice(i, 1); continue; } // Player hits enemy (from above) if (rectsIntersect(player, enemy) && player.vy > 0 && player.y - player.height < enemy.y - enemy.height + 30) { // Defeat enemy enemy.destroy(); enemies.splice(i, 1); player.vy = -jumpStrength * 0.7; // Bounce // Increase score score += 1; scoreTxt.setText(score); } // Player collides with enemy (side or bottom) else if (rectsIntersect(player, enemy)) { loseLife(); } } // Platform collision (only check platforms under player) var onPlatform = false; for (var i = 0; i < platforms.length; i++) { var plat = platforms[i]; // Check if player is falling and above platform if (player.vy >= 0 && player.x + player.width * 0.4 > plat.x && player.x - player.width * 0.4 < plat.x + plat.width && player.y > plat.y - 10 && player.y < plat.y + 40) { // Land on platform player.y = plat.y; player.vy = 0; player.isOnGround = true; player.isJumping = false; onPlatform = true; break; } } if (!onPlatform && player.y < groundY) { player.isOnGround = false; } // Check for falling off screen if (player.y > 2732 + 200) { loseLife(); } // Check for level end (reaching far right) if (flag && rectsIntersect(player, flag)) { isYouWin = true; LK.showYouWin(); } }; // Lose a life and handle game over function loseLife() { if (isGameOver) { return; } lives -= 1; if (lives < 0) { lives = 0; } var livesStr = ''; for (var i = 0; i < lives; i++) { livesStr += '♥'; } livesTxt.setText(livesStr); // Flash screen red LK.effects.flashScreen(0xff0000, 800); if (lives <= 0) { isGameOver = true; LK.showGameOver(); } else { // Reset player position player.x = 300; player.y = groundY; player.vx = scrollSpeed; player.vy = 0; } } // --- Start game --- resetGame();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Coin class
var Coin = Container.expand(function () {
var self = Container.call(this);
var coinSprite = self.attachAsset('coin', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = coinSprite.width;
self.height = coinSprite.height;
return self;
});
// Enemy class
var Enemy = Container.expand(function () {
var self = Container.call(this);
// Attach enemy asset (blue box)
var enemySprite = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0
});
self.width = enemySprite.width;
self.height = enemySprite.height;
// Enemy stays on the ground and moves only a little left-right
self.vx = 0;
self.moveRange = 40; // smaller movement range
self.baseX = 0;
self.update = function () {
// Always keep enemy at ground level
// Find the highest platform directly under the enemy's x position
var bestPlatY = groundY;
for (var i = 0; i < platforms.length; i++) {
var plat = platforms[i];
// Check if enemy is horizontally over the platform
if (self.x + self.width * 0.4 > plat.x && self.x - self.width * 0.4 < plat.x + plat.width) {
if (plat.y < bestPlatY) {
bestPlatY = plat.y;
}
}
}
self.y = bestPlatY - self.height;
// Optionally, add some small movement
if (self.baseX === 0) {
self.baseX = self.x;
}
self.x = self.baseX + Math.sin(LK.ticks / 60) * self.moveRange;
};
return self;
});
// Flag class
var Flag = Container.expand(function () {
var self = Container.call(this);
var flagSprite = self.attachAsset('flag', {
anchorX: 0.5,
anchorY: 1
});
self.width = flagSprite.width;
self.height = flagSprite.height;
return self;
});
// Platform class
var Platform = Container.expand(function () {
var self = Container.call(this);
// Attach platform asset (green box)
var platformSprite = self.attachAsset('platform', {
anchorX: 0,
anchorY: 0
});
self.width = platformSprite.width;
self.height = platformSprite.height;
// Platforms are static, but can be moved for scrolling
self.update = function () {
// Platforms are stationary; do not move.
};
return self;
});
// Player class
var Player = Container.expand(function () {
var self = Container.call(this);
// Attach player asset (red box)
var playerSprite = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 1
});
// Physics properties
self.vx = 0;
self.vy = 0;
self.isOnGround = false;
self.width = playerSprite.width;
self.height = playerSprite.height;
// Jumping state
self.isJumping = false;
// Update method called every tick
self.update = function () {
// Gravity
self.vy += gravity;
// Horizontal movement (auto-run)
self.x += self.vx;
// Vertical movement
self.y += self.vy;
// Prevent falling below ground
if (self.y > groundY) {
self.y = groundY;
self.vy = 0;
self.isOnGround = true;
self.isJumping = false;
} else {
self.isOnGround = false;
}
};
// Jump method
self.jump = function () {
if (self.isOnGround && !self.isJumping) {
self.vy = -jumpStrength;
self.isJumping = true;
self.isOnGround = false;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb // Sky blue
});
/****
* Game Code
****/
// --- Game constants ---
// Tween plugin for animations
var gravity = 1.2;
var jumpStrength = 32;
var scrollSpeed = 7;
var groundY = 2300; // Y position of the ground/platforms
// --- Game state ---
var player;
var platforms = [];
var enemies = [];
var flag;
var coin;
var lives = 3;
var level = 1;
var isGameOver = false;
var isYouWin = false;
// --- GUI elements ---
var livesTxt = new Text2('♥♥♥', {
size: 100,
fill: 0xFF4444
});
// Anchor left, top
livesTxt.anchor.set(0, 0);
// Place at x=110 to avoid top-left menu, y=0
livesTxt.x = 110;
livesTxt.y = 0;
LK.gui.top.addChild(livesTxt);
// Score variable and score text
var score = 0;
var scoreTxt = new Text2('0', {
size: 100,
fill: 0xffffff
});
scoreTxt.anchor.set(0.5, 0); // center, top
scoreTxt.x = 2048 / 2;
scoreTxt.y = 0;
LK.gui.top.addChild(scoreTxt);
// --- Asset initialization (shapes) ---
// --- Helper functions ---
// Create a platform at (x, y) with optional width
function createPlatform(x, y, width) {
var plat = new Platform();
plat.x = x;
plat.y = y;
if (width) {
plat.width = width;
}
platforms.push(plat);
game.addChild(plat);
return plat;
}
// Create an enemy at (x, y)
function createEnemy(x, y) {
var enemy = new Enemy();
enemy.x = x;
enemy.y = y;
enemies.push(enemy);
game.addChild(enemy);
return enemy;
}
// Reset game state for new game or level
function resetGame() {
// Remove all platforms and enemies
for (var i = 0; i < platforms.length; i++) {
platforms[i].destroy();
}
for (var i = 0; i < enemies.length; i++) {
enemies[i].destroy();
}
if (flag) {
flag.destroy();
flag = null;
}
if (coin) {
coin.destroy();
coin = null;
}
platforms = [];
enemies = [];
// Reset lives
lives = 3;
level = 1;
isGameOver = false;
isYouWin = false;
livesTxt.setText('♥♥♥');
// Reset score
score = 0;
scoreTxt.setText(score);
// Create player
if (player) {
player.destroy();
}
player = new Player();
player.x = 300;
player.y = groundY;
player.vx = scrollSpeed;
game.addChild(player);
// Create level
createLevel(level);
}
// Create a level layout
function createLevel(levelNum) {
// Simple level: ground platform, some floating platforms, coins, enemies
// Ground (very extended)
createPlatform(0, groundY, 20000);
// No floating platforms
// Enemies (on ground, spread out and more of them)
createEnemy(1200, groundY - 160 + 240);
createEnemy(2000, groundY - 160 + 240);
createEnemy(3000, groundY - 160 + 240);
createEnemy(4000, groundY - 160 + 240);
createEnemy(5200, groundY - 160 + 240);
createEnemy(6500, groundY - 160 + 240);
createEnemy(7500, groundY - 160 + 240);
// End flag (no floating platform needed)
// Place flag much farther to the right and keep it stationary
flag = new Flag();
flag.x = 8000;
flag.y = groundY;
game.addChild(flag);
}
// --- Collision detection ---
function rectsIntersect(a, b) {
return a.x - a.width * 0.5 < b.x + b.width * 0.5 && a.x + a.width * 0.5 > b.x - b.width * 0.5 && a.y - a.height < b.y && a.y > b.y - b.height;
}
// --- Touch controls ---
// Touch anywhere to jump
game.down = function (x, y, obj) {
if (isGameOver || isYouWin) {
return;
}
player.jump();
};
// --- Main game update loop ---
game.update = function () {
if (isGameOver || isYouWin) {
return;
}
// Update player
player.update();
// Camera: keep player at 1/3 of screen, scroll world
var cameraX = player.x - 600;
if (cameraX < 0) {
cameraX = 0;
}
// Move the game container so the player is always followed by the camera
game.x = -cameraX;
// Update platforms
for (var i = platforms.length - 1; i >= 0; i--) {
var plat = platforms[i];
plat.update();
// Remove platforms that are off screen
if (plat.x + plat.width < cameraX - 200) {
plat.destroy();
platforms.splice(i, 1);
}
}
// Update enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
enemy.update();
// Remove enemies that are off screen
if (enemy.x < cameraX - 200) {
enemy.destroy();
enemies.splice(i, 1);
continue;
}
// Player hits enemy (from above)
if (rectsIntersect(player, enemy) && player.vy > 0 && player.y - player.height < enemy.y - enemy.height + 30) {
// Defeat enemy
enemy.destroy();
enemies.splice(i, 1);
player.vy = -jumpStrength * 0.7; // Bounce
// Increase score
score += 1;
scoreTxt.setText(score);
}
// Player collides with enemy (side or bottom)
else if (rectsIntersect(player, enemy)) {
loseLife();
}
}
// Platform collision (only check platforms under player)
var onPlatform = false;
for (var i = 0; i < platforms.length; i++) {
var plat = platforms[i];
// Check if player is falling and above platform
if (player.vy >= 0 && player.x + player.width * 0.4 > plat.x && player.x - player.width * 0.4 < plat.x + plat.width && player.y > plat.y - 10 && player.y < plat.y + 40) {
// Land on platform
player.y = plat.y;
player.vy = 0;
player.isOnGround = true;
player.isJumping = false;
onPlatform = true;
break;
}
}
if (!onPlatform && player.y < groundY) {
player.isOnGround = false;
}
// Check for falling off screen
if (player.y > 2732 + 200) {
loseLife();
}
// Check for level end (reaching far right)
if (flag && rectsIntersect(player, flag)) {
isYouWin = true;
LK.showYouWin();
}
};
// Lose a life and handle game over
function loseLife() {
if (isGameOver) {
return;
}
lives -= 1;
if (lives < 0) {
lives = 0;
}
var livesStr = '';
for (var i = 0; i < lives; i++) {
livesStr += '♥';
}
livesTxt.setText(livesStr);
// Flash screen red
LK.effects.flashScreen(0xff0000, 800);
if (lives <= 0) {
isGameOver = true;
LK.showGameOver();
} else {
// Reset player position
player.x = 300;
player.y = groundY;
player.vx = scrollSpeed;
player.vy = 0;
}
}
// --- Start game ---
resetGame();