/****
* 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 ---