/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Platform = Container.expand(function (x, y) { var self = Container.call(this); var platformGraphics = self.attachAsset('platform', { anchorX: 0.5, anchorY: 0.5 }); self.x = x; self.y = y; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 1.0 }); self.velocityY = 0; self.velocityX = 0; self.gravity = 0.8; self.jumpPower = 0; self.isOnGround = false; self.isCharging = false; self.maxJumpPower = 35; self.update = function () { // Apply gravity if (!self.isOnGround) { self.velocityY += self.gravity; } // Update position self.y += self.velocityY; self.x += self.velocityX; // Apply horizontal friction self.velocityX *= 0.96; // Keep player within screen bounds if (self.x < 40) { self.x = 40; self.velocityX = 0; } if (self.x > 2008) { self.x = 2008; self.velocityX = 0; } // Check platform collisions self.checkPlatformCollisions(); // Check spike collisions self.checkSpikeCollisions(); // Check if fallen off screen if (self.y > 2732 + 100) { LK.showGameOver(); } }; self.checkPlatformCollisions = function () { var wasOnGround = self.isOnGround; self.isOnGround = false; for (var i = 0; i < platforms.length; i++) { var platform = platforms[i]; if (self.intersects(platform) && self.velocityY >= 0) { var playerBottom = self.y; var platformTop = platform.y - platform.height / 2; if (playerBottom >= platformTop - 20 && playerBottom <= platformTop + 20) { self.y = platformTop; self.velocityY = 0; self.isOnGround = true; if (!wasOnGround) { LK.getSound('land').play(); // Score point for landing on platform if (platform.scored === undefined) { platform.scored = true; LK.setScore(LK.getScore() + 1); scoreTxt.setText(LK.getScore()); } } break; } } } }; self.startJump = function () { if (self.isOnGround) { self.isCharging = true; self.jumpPower = 0; } }; self.chargeJump = function () { if (self.isCharging && self.jumpPower < self.maxJumpPower) { self.jumpPower += 0.8; } }; self.executeJump = function () { if (self.isCharging && self.isOnGround) { self.velocityY = -self.jumpPower; self.isOnGround = false; self.isCharging = false; LK.getSound('jump').play(); } }; self.checkSpikeCollisions = function () { for (var i = 0; i < spikes.length; i++) { var spike = spikes[i]; if (self.intersects(spike)) { LK.getSound('death').play(); LK.showGameOver(); break; } } }; return self; }); var Spike = Container.expand(function (x, y) { var self = Container.call(this); var spikeGraphics = self.attachAsset('spike', { anchorX: 0.5, anchorY: 0.5 }); self.x = x; self.y = y; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ var player; var platforms = []; var spikes = []; var scoreTxt; // Create score display scoreTxt = new Text2('0', { size: 100, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); scoreTxt.y = 50; // Create player player = game.addChild(new Player()); player.x = 1024; player.y = 2500; // Create initial platforms function createPlatform(x, y) { var platform = new Platform(x, y); platforms.push(platform); game.addChild(platform); // 30% chance to add spikes to platform (but not the starting platform) if (Math.random() < 0.3 && platforms.length > 1) { // Create one large spike that covers the entire platform var spikeX = x; // Center spike on platform var spikeY = y; // Place spike at same level as platform var spike = new Spike(spikeX, spikeY); spikes.push(spike); game.addChild(spike); } return platform; } // Starting platform createPlatform(1024, 2600); // Generate platforms going upward for (var i = 0; i < 20; i++) { var x = Math.random() * 1600 + 224; // Random X between 224 and 1824 var y = 2400 - i * 200 + (Math.random() * 100 - 50); // Going upward with some variation createPlatform(x, y); } // Camera following var cameraY = 0; game.down = function (x, y, obj) { if (player.isOnGround) { // Convert tap position to game coordinates var gamePos = game.toLocal({ x: x, y: y }); // Find the closest platform to the tap position var closestPlatform = null; var closestDistance = Infinity; for (var i = 0; i < platforms.length; i++) { var platform = platforms[i]; // Only consider platforms that are above the player if (platform.y < player.y - 50) { var distance = Math.sqrt(Math.pow(platform.x - gamePos.x, 2) + Math.pow(platform.y - gamePos.y, 2)); if (distance < closestDistance) { closestDistance = distance; closestPlatform = platform; } } } if (closestPlatform) { // Calculate jump trajectory toward the platform var deltaX = closestPlatform.x - player.x; var deltaY = closestPlatform.y - player.y; var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY); // Normalize horizontal velocity based on distance to platform var horizontalSpeed = 18; if (distance > 0) { player.velocityX = deltaX / distance * horizontalSpeed; } } else { // Fallback to old system if no platform found var screenCenterX = 1024; if (x < screenCenterX) { player.velocityX = -15; } else { player.velocityX = 15; } } player.velocityY = -player.maxJumpPower; player.isOnGround = false; LK.getSound('jump').play(); } }; game.update = function () { // Update camera to follow player var targetCameraY = player.y - 1800; if (targetCameraY < cameraY) { cameraY += (targetCameraY - cameraY) * 0.1; game.y = -cameraY; } // Generate new platforms as player goes higher var highestPlatform = Math.min.apply(Math, platforms.map(function (p) { return p.y; })); if (player.y < highestPlatform + 1000) { for (var i = 0; i < 5; i++) { var x = Math.random() * 1600 + 224; var y = highestPlatform - 200 - i * 200 + (Math.random() * 100 - 50); createPlatform(x, y); } } // Clean up platforms that are too far below for (var i = platforms.length - 1; i >= 0; i--) { if (platforms[i].y > player.y + 1500) { platforms[i].destroy(); platforms.splice(i, 1); } } // Clean up spikes that are too far below for (var i = spikes.length - 1; i >= 0; i--) { if (spikes[i].y > player.y + 1500) { spikes[i].destroy(); spikes.splice(i, 1); } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Platform = Container.expand(function (x, y) {
var self = Container.call(this);
var platformGraphics = self.attachAsset('platform', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = x;
self.y = y;
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 1.0
});
self.velocityY = 0;
self.velocityX = 0;
self.gravity = 0.8;
self.jumpPower = 0;
self.isOnGround = false;
self.isCharging = false;
self.maxJumpPower = 35;
self.update = function () {
// Apply gravity
if (!self.isOnGround) {
self.velocityY += self.gravity;
}
// Update position
self.y += self.velocityY;
self.x += self.velocityX;
// Apply horizontal friction
self.velocityX *= 0.96;
// Keep player within screen bounds
if (self.x < 40) {
self.x = 40;
self.velocityX = 0;
}
if (self.x > 2008) {
self.x = 2008;
self.velocityX = 0;
}
// Check platform collisions
self.checkPlatformCollisions();
// Check spike collisions
self.checkSpikeCollisions();
// Check if fallen off screen
if (self.y > 2732 + 100) {
LK.showGameOver();
}
};
self.checkPlatformCollisions = function () {
var wasOnGround = self.isOnGround;
self.isOnGround = false;
for (var i = 0; i < platforms.length; i++) {
var platform = platforms[i];
if (self.intersects(platform) && self.velocityY >= 0) {
var playerBottom = self.y;
var platformTop = platform.y - platform.height / 2;
if (playerBottom >= platformTop - 20 && playerBottom <= platformTop + 20) {
self.y = platformTop;
self.velocityY = 0;
self.isOnGround = true;
if (!wasOnGround) {
LK.getSound('land').play();
// Score point for landing on platform
if (platform.scored === undefined) {
platform.scored = true;
LK.setScore(LK.getScore() + 1);
scoreTxt.setText(LK.getScore());
}
}
break;
}
}
}
};
self.startJump = function () {
if (self.isOnGround) {
self.isCharging = true;
self.jumpPower = 0;
}
};
self.chargeJump = function () {
if (self.isCharging && self.jumpPower < self.maxJumpPower) {
self.jumpPower += 0.8;
}
};
self.executeJump = function () {
if (self.isCharging && self.isOnGround) {
self.velocityY = -self.jumpPower;
self.isOnGround = false;
self.isCharging = false;
LK.getSound('jump').play();
}
};
self.checkSpikeCollisions = function () {
for (var i = 0; i < spikes.length; i++) {
var spike = spikes[i];
if (self.intersects(spike)) {
LK.getSound('death').play();
LK.showGameOver();
break;
}
}
};
return self;
});
var Spike = Container.expand(function (x, y) {
var self = Container.call(this);
var spikeGraphics = self.attachAsset('spike', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = x;
self.y = y;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
var player;
var platforms = [];
var spikes = [];
var scoreTxt;
// Create score display
scoreTxt = new Text2('0', {
size: 100,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
scoreTxt.y = 50;
// Create player
player = game.addChild(new Player());
player.x = 1024;
player.y = 2500;
// Create initial platforms
function createPlatform(x, y) {
var platform = new Platform(x, y);
platforms.push(platform);
game.addChild(platform);
// 30% chance to add spikes to platform (but not the starting platform)
if (Math.random() < 0.3 && platforms.length > 1) {
// Create one large spike that covers the entire platform
var spikeX = x; // Center spike on platform
var spikeY = y; // Place spike at same level as platform
var spike = new Spike(spikeX, spikeY);
spikes.push(spike);
game.addChild(spike);
}
return platform;
}
// Starting platform
createPlatform(1024, 2600);
// Generate platforms going upward
for (var i = 0; i < 20; i++) {
var x = Math.random() * 1600 + 224; // Random X between 224 and 1824
var y = 2400 - i * 200 + (Math.random() * 100 - 50); // Going upward with some variation
createPlatform(x, y);
}
// Camera following
var cameraY = 0;
game.down = function (x, y, obj) {
if (player.isOnGround) {
// Convert tap position to game coordinates
var gamePos = game.toLocal({
x: x,
y: y
});
// Find the closest platform to the tap position
var closestPlatform = null;
var closestDistance = Infinity;
for (var i = 0; i < platforms.length; i++) {
var platform = platforms[i];
// Only consider platforms that are above the player
if (platform.y < player.y - 50) {
var distance = Math.sqrt(Math.pow(platform.x - gamePos.x, 2) + Math.pow(platform.y - gamePos.y, 2));
if (distance < closestDistance) {
closestDistance = distance;
closestPlatform = platform;
}
}
}
if (closestPlatform) {
// Calculate jump trajectory toward the platform
var deltaX = closestPlatform.x - player.x;
var deltaY = closestPlatform.y - player.y;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
// Normalize horizontal velocity based on distance to platform
var horizontalSpeed = 18;
if (distance > 0) {
player.velocityX = deltaX / distance * horizontalSpeed;
}
} else {
// Fallback to old system if no platform found
var screenCenterX = 1024;
if (x < screenCenterX) {
player.velocityX = -15;
} else {
player.velocityX = 15;
}
}
player.velocityY = -player.maxJumpPower;
player.isOnGround = false;
LK.getSound('jump').play();
}
};
game.update = function () {
// Update camera to follow player
var targetCameraY = player.y - 1800;
if (targetCameraY < cameraY) {
cameraY += (targetCameraY - cameraY) * 0.1;
game.y = -cameraY;
}
// Generate new platforms as player goes higher
var highestPlatform = Math.min.apply(Math, platforms.map(function (p) {
return p.y;
}));
if (player.y < highestPlatform + 1000) {
for (var i = 0; i < 5; i++) {
var x = Math.random() * 1600 + 224;
var y = highestPlatform - 200 - i * 200 + (Math.random() * 100 - 50);
createPlatform(x, y);
}
}
// Clean up platforms that are too far below
for (var i = platforms.length - 1; i >= 0; i--) {
if (platforms[i].y > player.y + 1500) {
platforms[i].destroy();
platforms.splice(i, 1);
}
}
// Clean up spikes that are too far below
for (var i = spikes.length - 1; i >= 0; i--) {
if (spikes[i].y > player.y + 1500) {
spikes[i].destroy();
spikes.splice(i, 1);
}
}
};