/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Obstacle class: spikes or blocks var Obstacle = Container.expand(function () { var self = Container.call(this); // Randomly choose obstacle type: spike or block var type = Math.random() < 0.5 ? 'spike' : 'block'; if (type === 'spike') { // Spike: triangle (use box asset, scale to triangle shape) var spikeAsset = self.attachAsset('spike', { anchorX: 0.5, anchorY: 1 }); // width: 80, height: 120, color: 0xff4444, shape: 'box' // We'll visually "fake" a triangle by scaling Y and X spikeAsset.scaleX = 1; spikeAsset.scaleY = 1.2; } else { // Block: rectangle var blockAsset = self.attachAsset('obstacleBlock', { anchorX: 0.5, anchorY: 1 }); // width: 120, height: 120, color: 0x888888, shape: 'box' } self.type = type; // Update method: move left self.update = function () { self.x -= obstacleSpeed; }; return self; }); // Player class: geometric box that auto-runs and jumps var Player = Container.expand(function () { var self = Container.call(this); // Attach player asset (box) var playerAsset = self.attachAsset('playerBox', { anchorX: 0.5, anchorY: 1 }); // Physics properties self.vy = 0; // vertical velocity self.isJumping = false; self.grounded = true; // Constants self.jumpVelocity = -48; // negative is up self.gravity = 5; // gravity per frame // Set initial size and color // (Asset will be created automatically) // width: 120, height: 120, color: 0x2eccff // Update method called every tick self.update = function () { // Apply gravity if (!self.grounded) { self.vy += self.gravity; self.y += self.vy; // Check for landing on ground if (self.y >= groundY) { self.y = groundY; self.vy = 0; self.grounded = true; self.isJumping = false; } } }; // Jump method self.jump = function () { if (self.grounded && !self.isJumping) { self.vy = self.jumpVelocity; self.grounded = false; self.isJumping = true; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x181c2c }); /**** * Game Code ****/ // Tween plugin for jump and obstacle animations // --- Constants --- var groundY = 2200; // Y position of ground (player stands here) var playerStartX = 500; var playerStartY = groundY; var obstacleStartX = 2200; // Obstacles spawn off-screen right var obstacleSpeed = 28; // How fast obstacles move left var minObstacleGap = 500; // Minimum distance between obstacles var maxObstacleGap = 900; // Maximum distance between obstacles // --- Asset Initialization (auto by LK, but for clarity) --- // --- Game State --- var player; var obstacles = []; var score = 0; var scoreTxt; var lastObstacleX = 0; var gameStarted = false; // --- Ground --- var ground = LK.getAsset('ground', { anchorX: 0, anchorY: 0, x: 0, y: groundY + 1 }); game.addChild(ground); // --- Player --- player = new Player(); player.x = playerStartX; player.y = playerStartY; game.addChild(player); // --- Score Display --- scoreTxt = new Text2('0', { size: 120, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // --- Start State --- resetGame(); function resetGame() { // Remove all obstacles for (var i = 0; i < obstacles.length; i++) { obstacles[i].destroy(); } obstacles = []; // Reset player player.x = playerStartX; player.y = playerStartY; player.vy = 0; player.grounded = true; player.isJumping = false; // Reset score score = 0; LK.setScore(0); scoreTxt.setText('0'); // Reset obstacle spawn lastObstacleX = 1600; // Spawn initial obstacles for (var i = 0; i < 3; i++) { spawnObstacle(lastObstacleX + 800 * i); } gameStarted = true; } // --- Obstacle Spawning --- function spawnObstacle(x) { var obs = new Obstacle(); obs.x = x; obs.y = groundY; obstacles.push(obs); game.addChild(obs); lastObstacleX = x; } // --- Collision Detection --- function checkCollision(a, b) { // Simple AABB collision var ab = a.getBounds(); var bb = b.getBounds(); return ab.x < bb.x + bb.width && ab.x + ab.width > bb.x && ab.y < bb.y + bb.height && ab.y + ab.height > bb.y; } // --- Game Update Loop --- game.update = function () { if (!gameStarted) return; // Update player player.update(); // Update obstacles for (var i = obstacles.length - 1; i >= 0; i--) { var obs = obstacles[i]; obs.update(); // Remove obstacles that have gone off screen if (obs.x < -200) { obs.destroy(); obstacles.splice(i, 1); continue; } // Collision with player if (checkCollision(player, obs)) { // Flash screen and show game over LK.effects.flashScreen(0xff0000, 800); LK.showGameOver(); gameStarted = false; return; } } // Spawn new obstacles if needed if (obstacles.length === 0 || obstacles.length > 0 && obstacles[obstacles.length - 1].x < 2048 - minObstacleGap) { var gap = minObstacleGap + Math.floor(Math.random() * (maxObstacleGap - minObstacleGap)); spawnObstacle(2048 + gap); } // Score: increase as player passes obstacles for (var j = 0; j < obstacles.length; j++) { var obs2 = obstacles[j]; if (!obs2.passed && obs2.x + 60 < player.x) { obs2.passed = true; score += 1; LK.setScore(score); scoreTxt.setText(score + ''); } } }; // --- Input: Tap to Jump --- game.down = function (x, y, obj) { if (!gameStarted) return; player.jump(); }; // --- Reset on Game Over --- LK.on('gameover', function () { // Wait a short moment before reset to allow flash LK.setTimeout(function () { resetGame(); }, 400); }); // --- Prevent drag/scroll on mobile (handled by LK) --- // --- Center score text --- scoreTxt.setText('0'); scoreTxt.anchor.set(0.5, 0); // --- End of file ---
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Obstacle class: spikes or blocks
var Obstacle = Container.expand(function () {
var self = Container.call(this);
// Randomly choose obstacle type: spike or block
var type = Math.random() < 0.5 ? 'spike' : 'block';
if (type === 'spike') {
// Spike: triangle (use box asset, scale to triangle shape)
var spikeAsset = self.attachAsset('spike', {
anchorX: 0.5,
anchorY: 1
});
// width: 80, height: 120, color: 0xff4444, shape: 'box'
// We'll visually "fake" a triangle by scaling Y and X
spikeAsset.scaleX = 1;
spikeAsset.scaleY = 1.2;
} else {
// Block: rectangle
var blockAsset = self.attachAsset('obstacleBlock', {
anchorX: 0.5,
anchorY: 1
});
// width: 120, height: 120, color: 0x888888, shape: 'box'
}
self.type = type;
// Update method: move left
self.update = function () {
self.x -= obstacleSpeed;
};
return self;
});
// Player class: geometric box that auto-runs and jumps
var Player = Container.expand(function () {
var self = Container.call(this);
// Attach player asset (box)
var playerAsset = self.attachAsset('playerBox', {
anchorX: 0.5,
anchorY: 1
});
// Physics properties
self.vy = 0; // vertical velocity
self.isJumping = false;
self.grounded = true;
// Constants
self.jumpVelocity = -48; // negative is up
self.gravity = 5; // gravity per frame
// Set initial size and color
// (Asset will be created automatically)
// width: 120, height: 120, color: 0x2eccff
// Update method called every tick
self.update = function () {
// Apply gravity
if (!self.grounded) {
self.vy += self.gravity;
self.y += self.vy;
// Check for landing on ground
if (self.y >= groundY) {
self.y = groundY;
self.vy = 0;
self.grounded = true;
self.isJumping = false;
}
}
};
// Jump method
self.jump = function () {
if (self.grounded && !self.isJumping) {
self.vy = self.jumpVelocity;
self.grounded = false;
self.isJumping = true;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x181c2c
});
/****
* Game Code
****/
// Tween plugin for jump and obstacle animations
// --- Constants ---
var groundY = 2200; // Y position of ground (player stands here)
var playerStartX = 500;
var playerStartY = groundY;
var obstacleStartX = 2200; // Obstacles spawn off-screen right
var obstacleSpeed = 28; // How fast obstacles move left
var minObstacleGap = 500; // Minimum distance between obstacles
var maxObstacleGap = 900; // Maximum distance between obstacles
// --- Asset Initialization (auto by LK, but for clarity) ---
// --- Game State ---
var player;
var obstacles = [];
var score = 0;
var scoreTxt;
var lastObstacleX = 0;
var gameStarted = false;
// --- Ground ---
var ground = LK.getAsset('ground', {
anchorX: 0,
anchorY: 0,
x: 0,
y: groundY + 1
});
game.addChild(ground);
// --- Player ---
player = new Player();
player.x = playerStartX;
player.y = playerStartY;
game.addChild(player);
// --- Score Display ---
scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// --- Start State ---
resetGame();
function resetGame() {
// Remove all obstacles
for (var i = 0; i < obstacles.length; i++) {
obstacles[i].destroy();
}
obstacles = [];
// Reset player
player.x = playerStartX;
player.y = playerStartY;
player.vy = 0;
player.grounded = true;
player.isJumping = false;
// Reset score
score = 0;
LK.setScore(0);
scoreTxt.setText('0');
// Reset obstacle spawn
lastObstacleX = 1600;
// Spawn initial obstacles
for (var i = 0; i < 3; i++) {
spawnObstacle(lastObstacleX + 800 * i);
}
gameStarted = true;
}
// --- Obstacle Spawning ---
function spawnObstacle(x) {
var obs = new Obstacle();
obs.x = x;
obs.y = groundY;
obstacles.push(obs);
game.addChild(obs);
lastObstacleX = x;
}
// --- Collision Detection ---
function checkCollision(a, b) {
// Simple AABB collision
var ab = a.getBounds();
var bb = b.getBounds();
return ab.x < bb.x + bb.width && ab.x + ab.width > bb.x && ab.y < bb.y + bb.height && ab.y + ab.height > bb.y;
}
// --- Game Update Loop ---
game.update = function () {
if (!gameStarted) return;
// Update player
player.update();
// Update obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obs = obstacles[i];
obs.update();
// Remove obstacles that have gone off screen
if (obs.x < -200) {
obs.destroy();
obstacles.splice(i, 1);
continue;
}
// Collision with player
if (checkCollision(player, obs)) {
// Flash screen and show game over
LK.effects.flashScreen(0xff0000, 800);
LK.showGameOver();
gameStarted = false;
return;
}
}
// Spawn new obstacles if needed
if (obstacles.length === 0 || obstacles.length > 0 && obstacles[obstacles.length - 1].x < 2048 - minObstacleGap) {
var gap = minObstacleGap + Math.floor(Math.random() * (maxObstacleGap - minObstacleGap));
spawnObstacle(2048 + gap);
}
// Score: increase as player passes obstacles
for (var j = 0; j < obstacles.length; j++) {
var obs2 = obstacles[j];
if (!obs2.passed && obs2.x + 60 < player.x) {
obs2.passed = true;
score += 1;
LK.setScore(score);
scoreTxt.setText(score + '');
}
}
};
// --- Input: Tap to Jump ---
game.down = function (x, y, obj) {
if (!gameStarted) return;
player.jump();
};
// --- Reset on Game Over ---
LK.on('gameover', function () {
// Wait a short moment before reset to allow flash
LK.setTimeout(function () {
resetGame();
}, 400);
});
// --- Prevent drag/scroll on mobile (handled by LK) ---
// --- Center score text ---
scoreTxt.setText('0');
scoreTxt.anchor.set(0.5, 0);
// --- End of file ---