/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ // Obstacle class: static obstacle (box or ellipse) var Obstacle = Container.expand(function () { var self = Container.call(this); // Attach obstacle asset (ellipse shape) var obstacleGraphics = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5 }); return self; }); // Platform class: static or moving platform var Platform = Container.expand(function () { var self = Container.call(this); // Attach platform asset (box shape) var platformGraphics = self.attachAsset('platform', { anchorX: 0.5, anchorY: 0.5 }); // Platform movement properties self.isMoving = false; self.moveDir = 1; // 1: right, -1: left self.moveRange = 0; // in px self.moveSpeed = 0; // px per frame self.startX = 0; // Called every tick self.update = function () { if (self.isMoving) { self.x += self.moveDir * self.moveSpeed; if (Math.abs(self.x - self.startX) > self.moveRange) { self.moveDir *= -1; } } }; return self; }); // Player class var Player = Container.expand(function () { var self = Container.call(this); // Attach player asset (box shape) var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); // Physics properties self.vx = 0; self.vy = 0; self.isOnGround = false; self.width = playerGraphics.width; self.height = playerGraphics.height; // Jump method self.jump = function () { if (self.isOnGround) { self.vy = -jumpStrength; self.isOnGround = false; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222244 }); /**** * Game Code ****/ // --- Asset Initialization --- // --- Game Constants --- var GRAVITY = 2.2; var MOVE_SPEED = 22; var jumpStrength = 48; var PLATFORM_MIN_WIDTH = 220; var PLATFORM_MAX_WIDTH = 420; var PLATFORM_HEIGHT = 40; var PLATFORM_GAP_MIN = 220; var PLATFORM_GAP_MAX = 420; var PLATFORM_MOVE_CHANCE = 0.25; var PLATFORM_MOVE_RANGE = 320; var PLATFORM_MOVE_SPEED = 4; var OBSTACLE_CHANCE = 0.25; var OBSTACLE_SIZE = 80; var PLAYER_START_X = 2048 / 2; var PLAYER_START_Y = 2732 - 400; var CAMERA_OFFSET = 900; // How far from bottom the player is kept // --- Game State --- var player; var platforms = []; var obstacles = []; var maxHeight = 0; // Highest Y the player has reached (lower y = higher) var dragStartX = null; var dragStartY = null; var dragLastX = null; var dragLastY = null; var isDragging = false; var scoreTxt; var lastPlatformY = 0; var cameraY = 0; var gameOver = false; // --- Decorative White Dots --- var whiteDots = []; var WHITE_DOT_COUNT = 40; // Number of dots // --- GUI --- scoreTxt = new Text2('0', { size: 120, fill: "#fff" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // --- Helper Functions --- // Generate a new platform at (x, y), optionally moving function createPlatform(x, y, width, isMoving) { var plat = new Platform(); plat.x = x; plat.y = y; plat.width = width; plat.height = PLATFORM_HEIGHT; plat.getChildAt(0).width = width; plat.getChildAt(0).height = PLATFORM_HEIGHT; plat.isMoving = isMoving; plat.moveRange = isMoving ? PLATFORM_MOVE_RANGE : 0; plat.moveSpeed = isMoving ? PLATFORM_MOVE_SPEED : 0; plat.startX = x; game.addChild(plat); platforms.push(plat); return plat; } // Generate a new obstacle on a platform function createObstacle(x, y) { var obs = new Obstacle(); obs.x = x; obs.y = y - OBSTACLE_SIZE / 2 - 10; obs.width = OBSTACLE_SIZE; obs.height = OBSTACLE_SIZE; obs.getChildAt(0).width = OBSTACLE_SIZE; obs.getChildAt(0).height = OBSTACLE_SIZE; game.addChild(obs); obstacles.push(obs); return obs; } // Remove platforms/obstacles below camera function cleanupPlatformsObstacles() { for (var i = platforms.length - 1; i >= 0; i--) { if (platforms[i].y - cameraY > 2732 + 200) { platforms[i].destroy(); platforms.splice(i, 1); } } for (var j = obstacles.length - 1; j >= 0; j--) { if (obstacles[j].y - cameraY > 2732 + 200) { obstacles[j].destroy(); obstacles.splice(j, 1); } } } // Generate platforms up to a certain Y function generatePlatformsUpTo(minY) { while (lastPlatformY > minY) { var gap = PLATFORM_GAP_MIN + Math.random() * (PLATFORM_GAP_MAX - PLATFORM_GAP_MIN); var platY = lastPlatformY - gap; var platWidth = PLATFORM_MIN_WIDTH + Math.random() * (PLATFORM_MAX_WIDTH - PLATFORM_MIN_WIDTH); var platX = platWidth / 2 + Math.random() * (2048 - platWidth); var isMoving = Math.random() < PLATFORM_MOVE_CHANCE; var plat = createPlatform(platX, platY, platWidth, isMoving); // Maybe add obstacle if (Math.random() < OBSTACLE_CHANCE && platWidth > 200 + OBSTACLE_SIZE) { var obsX = plat.x + (Math.random() - 0.5) * (platWidth - OBSTACLE_SIZE - 40); createObstacle(obsX, platY); } lastPlatformY = platY; } } // Reset game state function resetGame() { // Remove old objects for (var i = 0; i < platforms.length; i++) platforms[i].destroy(); for (var j = 0; j < obstacles.length; j++) obstacles[j].destroy(); for (var d = 0; d < whiteDots.length; d++) whiteDots[d].destroy && whiteDots[d].destroy(); platforms = []; obstacles = []; whiteDots = []; cameraY = 0; lastPlatformY = PLAYER_START_Y + 120; maxHeight = PLAYER_START_Y; LK.setScore(0); scoreTxt.setText('0'); gameOver = false; // Reset background color to original game.setBackgroundColor(0x222244); // Create random white dots (decorative, do not affect gameplay) for (var i = 0; i < WHITE_DOT_COUNT; i++) { var dotSize = 8 + Math.random() * 22; // 8-30 px var dotX = 40 + Math.random() * (2048 - 80); var dotY = Math.random() * (2732 - 80); var dot = LK.getAsset('whiteDot', { width: dotSize, height: dotSize, color: 0xffffff, shape: 'ellipse', anchorX: 0.5, anchorY: 0.5, x: dotX, y: dotY }); game.addChild(dot); whiteDots.push(dot); } // Create player if (player) player.destroy(); player = new Player(); player.x = PLAYER_START_X; player.y = PLAYER_START_Y; player.vx = 0; player.vy = 0; player.isOnGround = false; game.addChild(player); // Create starting platform createPlatform(PLAYER_START_X, PLAYER_START_Y + 80, 420, false); // Generate initial platforms generatePlatformsUpTo(PLAYER_START_Y - 2000); } // --- Input Handling --- // Touch/drag to move player left/right, tap to jump game.down = function (x, y, obj) { if (gameOver) return; dragStartX = x; dragStartY = y; dragLastX = x; dragLastY = y; isDragging = true; }; game.move = function (x, y, obj) { if (gameOver) return; if (!isDragging) return; var dx = x - dragLastX; dragLastX = x; dragLastY = y; // Move player horizontally player.x += dx * 1.2; if (player.x < player.width / 2) player.x = player.width / 2; if (player.x > 2048 - player.width / 2) player.x = 2048 - player.width / 2; }; game.up = function (x, y, obj) { if (gameOver) return; isDragging = false; // If tap (not drag), jump if (Math.abs(x - dragStartX) < 30 && Math.abs(y - dragStartY) < 30) { player.jump(); } }; // --- Main Game Loop --- game.update = function () { if (gameOver) return; // --- Player Physics --- player.vy += GRAVITY; player.y += player.vy; player.x += player.vx; // Clamp player to screen if (player.x < player.width / 2) player.x = player.width / 2; if (player.x > 2048 - player.width / 2) player.x = 2048 - player.width / 2; // --- Platform Collision --- player.isOnGround = false; for (var i = 0; i < platforms.length; i++) { var plat = platforms[i]; // Only check collision if falling if (player.vy >= 0) { var px = player.x; var py = player.y + player.height / 2; var platLeft = plat.x - plat.width / 2; var platRight = plat.x + plat.width / 2; var platTop = plat.y - plat.height / 2; var platBottom = plat.y + plat.height / 2; if (px > platLeft + 10 && px < platRight - 10 && py > platTop && py < platTop + 40 && player.y < plat.y) { // Landed on platform player.y = platTop - player.height / 2 + 1; player.vy = 0; player.isOnGround = true; } } } // --- Obstacle Collision --- for (var j = 0; j < obstacles.length; j++) { var obs = obstacles[j]; // Simple circle-rect collision var dx = Math.abs(player.x - obs.x); var dy = Math.abs(player.y - obs.y); if (dx < player.width / 2 + OBSTACLE_SIZE / 2 - 10 && dy < player.height / 2 + OBSTACLE_SIZE / 2 - 10) { // Hit obstacle LK.effects.flashScreen(0xff0000, 800); gameOver = true; LK.showGameOver(); return; } } // --- Fall Off Screen --- if (player.y - cameraY > 2732 + 100) { LK.effects.flashScreen(0xff0000, 800); gameOver = true; LK.showGameOver(); return; } // --- Camera Follow --- if (player.y < maxHeight) { maxHeight = player.y; LK.setScore(Math.max(0, Math.floor((PLAYER_START_Y - maxHeight) / 10))); scoreTxt.setText(LK.getScore()); } // --- Scene transitions and visuals --- // (No scene transitions in original endless climb version) var targetCameraY = player.y - (2732 - CAMERA_OFFSET); if (targetCameraY < cameraY) { cameraY = targetCameraY; } // Move all objects up by cameraY // Move all objects up by cameraY (endless climb illusion) for (var k = 0; k < platforms.length; k++) { // Move platform up by camera scroll delta platforms[k].y -= cameraY - (platforms[k].baseCameraY || 0); platforms[k].baseCameraY = cameraY; platforms[k].update(); } for (var l = 0; l < obstacles.length; l++) { obstacles[l].y -= cameraY - (obstacles[l].baseCameraY || 0); obstacles[l].baseCameraY = cameraY; } player.y -= cameraY - (player.baseCameraY || 0); player.baseCameraY = cameraY; // Move white dots with camera (decorative, do not affect gameplay) for (var d = 0; d < whiteDots.length; d++) { var dot = whiteDots[d]; dot.y -= cameraY - (dot.baseCameraY || 0); dot.baseCameraY = cameraY; } // --- Generate More Platforms --- generatePlatformsUpTo(cameraY - 1200); // --- Cleanup --- cleanupPlatformsObstacles(); }; // --- Game Over Handler (reset on restart) --- LK.on('gameover', function () { resetGame(); }); // --- Start Game --- resetGame();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Obstacle class: static obstacle (box or ellipse)
var Obstacle = Container.expand(function () {
var self = Container.call(this);
// Attach obstacle asset (ellipse shape)
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
// Platform class: static or moving platform
var Platform = Container.expand(function () {
var self = Container.call(this);
// Attach platform asset (box shape)
var platformGraphics = self.attachAsset('platform', {
anchorX: 0.5,
anchorY: 0.5
});
// Platform movement properties
self.isMoving = false;
self.moveDir = 1; // 1: right, -1: left
self.moveRange = 0; // in px
self.moveSpeed = 0; // px per frame
self.startX = 0;
// Called every tick
self.update = function () {
if (self.isMoving) {
self.x += self.moveDir * self.moveSpeed;
if (Math.abs(self.x - self.startX) > self.moveRange) {
self.moveDir *= -1;
}
}
};
return self;
});
// Player class
var Player = Container.expand(function () {
var self = Container.call(this);
// Attach player asset (box shape)
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
// Physics properties
self.vx = 0;
self.vy = 0;
self.isOnGround = false;
self.width = playerGraphics.width;
self.height = playerGraphics.height;
// Jump method
self.jump = function () {
if (self.isOnGround) {
self.vy = -jumpStrength;
self.isOnGround = false;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222244
});
/****
* Game Code
****/
// --- Asset Initialization ---
// --- Game Constants ---
var GRAVITY = 2.2;
var MOVE_SPEED = 22;
var jumpStrength = 48;
var PLATFORM_MIN_WIDTH = 220;
var PLATFORM_MAX_WIDTH = 420;
var PLATFORM_HEIGHT = 40;
var PLATFORM_GAP_MIN = 220;
var PLATFORM_GAP_MAX = 420;
var PLATFORM_MOVE_CHANCE = 0.25;
var PLATFORM_MOVE_RANGE = 320;
var PLATFORM_MOVE_SPEED = 4;
var OBSTACLE_CHANCE = 0.25;
var OBSTACLE_SIZE = 80;
var PLAYER_START_X = 2048 / 2;
var PLAYER_START_Y = 2732 - 400;
var CAMERA_OFFSET = 900; // How far from bottom the player is kept
// --- Game State ---
var player;
var platforms = [];
var obstacles = [];
var maxHeight = 0; // Highest Y the player has reached (lower y = higher)
var dragStartX = null;
var dragStartY = null;
var dragLastX = null;
var dragLastY = null;
var isDragging = false;
var scoreTxt;
var lastPlatformY = 0;
var cameraY = 0;
var gameOver = false;
// --- Decorative White Dots ---
var whiteDots = [];
var WHITE_DOT_COUNT = 40; // Number of dots
// --- GUI ---
scoreTxt = new Text2('0', {
size: 120,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// --- Helper Functions ---
// Generate a new platform at (x, y), optionally moving
function createPlatform(x, y, width, isMoving) {
var plat = new Platform();
plat.x = x;
plat.y = y;
plat.width = width;
plat.height = PLATFORM_HEIGHT;
plat.getChildAt(0).width = width;
plat.getChildAt(0).height = PLATFORM_HEIGHT;
plat.isMoving = isMoving;
plat.moveRange = isMoving ? PLATFORM_MOVE_RANGE : 0;
plat.moveSpeed = isMoving ? PLATFORM_MOVE_SPEED : 0;
plat.startX = x;
game.addChild(plat);
platforms.push(plat);
return plat;
}
// Generate a new obstacle on a platform
function createObstacle(x, y) {
var obs = new Obstacle();
obs.x = x;
obs.y = y - OBSTACLE_SIZE / 2 - 10;
obs.width = OBSTACLE_SIZE;
obs.height = OBSTACLE_SIZE;
obs.getChildAt(0).width = OBSTACLE_SIZE;
obs.getChildAt(0).height = OBSTACLE_SIZE;
game.addChild(obs);
obstacles.push(obs);
return obs;
}
// Remove platforms/obstacles below camera
function cleanupPlatformsObstacles() {
for (var i = platforms.length - 1; i >= 0; i--) {
if (platforms[i].y - cameraY > 2732 + 200) {
platforms[i].destroy();
platforms.splice(i, 1);
}
}
for (var j = obstacles.length - 1; j >= 0; j--) {
if (obstacles[j].y - cameraY > 2732 + 200) {
obstacles[j].destroy();
obstacles.splice(j, 1);
}
}
}
// Generate platforms up to a certain Y
function generatePlatformsUpTo(minY) {
while (lastPlatformY > minY) {
var gap = PLATFORM_GAP_MIN + Math.random() * (PLATFORM_GAP_MAX - PLATFORM_GAP_MIN);
var platY = lastPlatformY - gap;
var platWidth = PLATFORM_MIN_WIDTH + Math.random() * (PLATFORM_MAX_WIDTH - PLATFORM_MIN_WIDTH);
var platX = platWidth / 2 + Math.random() * (2048 - platWidth);
var isMoving = Math.random() < PLATFORM_MOVE_CHANCE;
var plat = createPlatform(platX, platY, platWidth, isMoving);
// Maybe add obstacle
if (Math.random() < OBSTACLE_CHANCE && platWidth > 200 + OBSTACLE_SIZE) {
var obsX = plat.x + (Math.random() - 0.5) * (platWidth - OBSTACLE_SIZE - 40);
createObstacle(obsX, platY);
}
lastPlatformY = platY;
}
}
// Reset game state
function resetGame() {
// Remove old objects
for (var i = 0; i < platforms.length; i++) platforms[i].destroy();
for (var j = 0; j < obstacles.length; j++) obstacles[j].destroy();
for (var d = 0; d < whiteDots.length; d++) whiteDots[d].destroy && whiteDots[d].destroy();
platforms = [];
obstacles = [];
whiteDots = [];
cameraY = 0;
lastPlatformY = PLAYER_START_Y + 120;
maxHeight = PLAYER_START_Y;
LK.setScore(0);
scoreTxt.setText('0');
gameOver = false;
// Reset background color to original
game.setBackgroundColor(0x222244);
// Create random white dots (decorative, do not affect gameplay)
for (var i = 0; i < WHITE_DOT_COUNT; i++) {
var dotSize = 8 + Math.random() * 22; // 8-30 px
var dotX = 40 + Math.random() * (2048 - 80);
var dotY = Math.random() * (2732 - 80);
var dot = LK.getAsset('whiteDot', {
width: dotSize,
height: dotSize,
color: 0xffffff,
shape: 'ellipse',
anchorX: 0.5,
anchorY: 0.5,
x: dotX,
y: dotY
});
game.addChild(dot);
whiteDots.push(dot);
}
// Create player
if (player) player.destroy();
player = new Player();
player.x = PLAYER_START_X;
player.y = PLAYER_START_Y;
player.vx = 0;
player.vy = 0;
player.isOnGround = false;
game.addChild(player);
// Create starting platform
createPlatform(PLAYER_START_X, PLAYER_START_Y + 80, 420, false);
// Generate initial platforms
generatePlatformsUpTo(PLAYER_START_Y - 2000);
}
// --- Input Handling ---
// Touch/drag to move player left/right, tap to jump
game.down = function (x, y, obj) {
if (gameOver) return;
dragStartX = x;
dragStartY = y;
dragLastX = x;
dragLastY = y;
isDragging = true;
};
game.move = function (x, y, obj) {
if (gameOver) return;
if (!isDragging) return;
var dx = x - dragLastX;
dragLastX = x;
dragLastY = y;
// Move player horizontally
player.x += dx * 1.2;
if (player.x < player.width / 2) player.x = player.width / 2;
if (player.x > 2048 - player.width / 2) player.x = 2048 - player.width / 2;
};
game.up = function (x, y, obj) {
if (gameOver) return;
isDragging = false;
// If tap (not drag), jump
if (Math.abs(x - dragStartX) < 30 && Math.abs(y - dragStartY) < 30) {
player.jump();
}
};
// --- Main Game Loop ---
game.update = function () {
if (gameOver) return;
// --- Player Physics ---
player.vy += GRAVITY;
player.y += player.vy;
player.x += player.vx;
// Clamp player to screen
if (player.x < player.width / 2) player.x = player.width / 2;
if (player.x > 2048 - player.width / 2) player.x = 2048 - player.width / 2;
// --- Platform Collision ---
player.isOnGround = false;
for (var i = 0; i < platforms.length; i++) {
var plat = platforms[i];
// Only check collision if falling
if (player.vy >= 0) {
var px = player.x;
var py = player.y + player.height / 2;
var platLeft = plat.x - plat.width / 2;
var platRight = plat.x + plat.width / 2;
var platTop = plat.y - plat.height / 2;
var platBottom = plat.y + plat.height / 2;
if (px > platLeft + 10 && px < platRight - 10 && py > platTop && py < platTop + 40 && player.y < plat.y) {
// Landed on platform
player.y = platTop - player.height / 2 + 1;
player.vy = 0;
player.isOnGround = true;
}
}
}
// --- Obstacle Collision ---
for (var j = 0; j < obstacles.length; j++) {
var obs = obstacles[j];
// Simple circle-rect collision
var dx = Math.abs(player.x - obs.x);
var dy = Math.abs(player.y - obs.y);
if (dx < player.width / 2 + OBSTACLE_SIZE / 2 - 10 && dy < player.height / 2 + OBSTACLE_SIZE / 2 - 10) {
// Hit obstacle
LK.effects.flashScreen(0xff0000, 800);
gameOver = true;
LK.showGameOver();
return;
}
}
// --- Fall Off Screen ---
if (player.y - cameraY > 2732 + 100) {
LK.effects.flashScreen(0xff0000, 800);
gameOver = true;
LK.showGameOver();
return;
}
// --- Camera Follow ---
if (player.y < maxHeight) {
maxHeight = player.y;
LK.setScore(Math.max(0, Math.floor((PLAYER_START_Y - maxHeight) / 10)));
scoreTxt.setText(LK.getScore());
}
// --- Scene transitions and visuals ---
// (No scene transitions in original endless climb version)
var targetCameraY = player.y - (2732 - CAMERA_OFFSET);
if (targetCameraY < cameraY) {
cameraY = targetCameraY;
}
// Move all objects up by cameraY
// Move all objects up by cameraY (endless climb illusion)
for (var k = 0; k < platforms.length; k++) {
// Move platform up by camera scroll delta
platforms[k].y -= cameraY - (platforms[k].baseCameraY || 0);
platforms[k].baseCameraY = cameraY;
platforms[k].update();
}
for (var l = 0; l < obstacles.length; l++) {
obstacles[l].y -= cameraY - (obstacles[l].baseCameraY || 0);
obstacles[l].baseCameraY = cameraY;
}
player.y -= cameraY - (player.baseCameraY || 0);
player.baseCameraY = cameraY;
// Move white dots with camera (decorative, do not affect gameplay)
for (var d = 0; d < whiteDots.length; d++) {
var dot = whiteDots[d];
dot.y -= cameraY - (dot.baseCameraY || 0);
dot.baseCameraY = cameraY;
}
// --- Generate More Platforms ---
generatePlatformsUpTo(cameraY - 1200);
// --- Cleanup ---
cleanupPlatformsObstacles();
};
// --- Game Over Handler (reset on restart) ---
LK.on('gameover', function () {
resetGame();
});
// --- Start Game ---
resetGame();