/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Checkpoint = Container.expand(function (x, y) {
var self = Container.call(this);
var checkpointGraphics = self.attachAsset('checkpoint', {
anchorX: 0.5,
anchorY: 1.0
});
self.x = x;
self.y = y;
self.activated = false;
self.activate = function () {
if (!self.activated) {
self.activated = true;
lastCheckpointX = self.x;
lastCheckpointY = self.y - 10;
LK.getSound('checkpoint').play();
LK.effects.flashObject(self, 0x00ff00, 300);
}
};
return self;
});
var Goal = Container.expand(function (x, y) {
var self = Container.call(this);
var goalGraphics = self.attachAsset('goal', {
anchorX: 0.5,
anchorY: 1.0
});
self.x = x;
self.y = y;
return self;
});
var MovingPlatform = Container.expand(function (x, y, moveDistance, moveSpeed) {
var self = Container.call(this);
var platformGraphics = self.attachAsset('movingPlatform', {
anchorX: 0,
anchorY: 0
});
self.x = x;
self.y = y;
self.startX = x;
self.moveDistance = moveDistance || 200;
self.moveSpeed = moveSpeed || 2;
self.direction = 1;
self.update = function () {
self.x += self.moveSpeed * self.direction;
if (self.x >= self.startX + self.moveDistance || self.x <= self.startX) {
self.direction *= -1;
}
};
return self;
});
var Platform = Container.expand(function (width, height, x, y) {
var self = Container.call(this);
var platformGraphics = self.attachAsset('ground', {
width: width,
height: height,
anchorX: 0,
anchorY: 0
});
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.isGrounded = false;
self.jumpPower = -25;
self.gravity = 1.2;
self.moveSpeed = 8;
self.isDead = false;
self.startX = 0;
self.startY = 0;
self.jump = function () {
if (self.isGrounded && !self.isDead) {
self.velocityY = self.jumpPower;
self.isGrounded = false;
LK.getSound('jump').play();
}
};
self.die = function () {
if (!self.isDead) {
self.isDead = true;
attempts++;
LK.getSound('death').play();
LK.effects.flashScreen(0xff0000, 500);
// Reset player position after brief delay
LK.setTimeout(function () {
self.reset();
}, 500);
}
};
self.reset = function () {
self.x = lastCheckpointX;
self.y = lastCheckpointY;
self.velocityX = 0;
self.velocityY = 0;
self.isGrounded = false;
self.isDead = false;
};
self.update = function () {
if (self.isDead) return;
// Apply gravity
self.velocityY += self.gravity;
// Horizontal movement (auto-run)
self.velocityX = self.moveSpeed;
// Update position
self.x += self.velocityX;
self.y += self.velocityY;
// Keep player in bounds
if (self.x < 0) {
self.x = 0;
self.velocityX = 0;
}
// Death if falling too far
if (self.y > 2732 + 200) {
self.die();
}
};
return self;
});
var Spike = Container.expand(function (x, y) {
var self = Container.call(this);
var spikeGraphics = self.attachAsset('spike', {
anchorX: 0.5,
anchorY: 1.0
});
self.x = x;
self.y = y;
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a2e
});
/****
* Game Code
****/
// Game variables
var currentLevel = storage.currentLevel || 1;
var attempts = 0;
var startTime = Date.now();
var lastCheckpointX = 200;
var lastCheckpointY = 2400;
// Game objects
var player;
var platforms = [];
var spikes = [];
var movingPlatforms = [];
var goal;
var checkpoints = [];
// Camera offset
var cameraOffsetX = 0;
// UI Elements
var levelTxt = new Text2('Level ' + currentLevel, {
size: 80,
fill: 0xFFFFFF
});
levelTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(levelTxt);
levelTxt.y = 50;
var attemptsTxt = new Text2('Attempts: 0', {
size: 60,
fill: 0xFFFFFF
});
attemptsTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(attemptsTxt);
attemptsTxt.x = -20;
attemptsTxt.y = 20;
var resetButton = new Text2('RESET', {
size: 50,
fill: 0xFF4444
});
resetButton.anchor.set(1, 0);
LK.gui.topRight.addChild(resetButton);
resetButton.x = -20;
resetButton.y = 90;
// Initialize level
function initLevel() {
// Clear existing objects
platforms = [];
spikes = [];
movingPlatforms = [];
checkpoints = [];
// Remove all children from game
while (game.children.length > 0) {
game.children[0].destroy();
}
// Create player
player = game.addChild(new Player());
player.x = lastCheckpointX;
player.y = lastCheckpointY;
// Level 1 - Basic jumping
if (currentLevel === 1) {
// Starting platform
platforms.push(game.addChild(new Platform(300, 40, 100, 2450)));
// Gap with platform
platforms.push(game.addChild(new Platform(200, 40, 500, 2400)));
// Spike obstacle
spikes.push(game.addChild(new Spike(750, 2400)));
// Higher platform
platforms.push(game.addChild(new Platform(250, 40, 850, 2300)));
// Checkpoint
checkpoints.push(game.addChild(new Checkpoint(1000, 2300)));
// Moving platform section
movingPlatforms.push(game.addChild(new MovingPlatform(1200, 2250, 150, 2)));
// Final platform with spikes
platforms.push(game.addChild(new Platform(300, 40, 1500, 2150)));
spikes.push(game.addChild(new Spike(1520, 2150)));
spikes.push(game.addChild(new Spike(1560, 2150)));
spikes.push(game.addChild(new Spike(1600, 2150)));
// Goal
goal = game.addChild(new Goal(1750, 2100));
}
// Level 2 - Moving platforms and timing challenges
else if (currentLevel === 2) {
// Starting platform
platforms.push(game.addChild(new Platform(250, 40, 100, 2450)));
// First moving platform
movingPlatforms.push(game.addChild(new MovingPlatform(400, 2350, 200, 3)));
// Spike trap after moving platform
spikes.push(game.addChild(new Spike(650, 2350)));
spikes.push(game.addChild(new Spike(690, 2350)));
// High jump section
platforms.push(game.addChild(new Platform(150, 40, 800, 2250)));
platforms.push(game.addChild(new Platform(120, 40, 1050, 2150)));
// Checkpoint at mid-level
checkpoints.push(game.addChild(new Checkpoint(1120, 2150)));
// Double moving platform challenge
movingPlatforms.push(game.addChild(new MovingPlatform(1300, 2100, 180, 2.5)));
movingPlatforms.push(game.addChild(new MovingPlatform(1600, 2050, 150, 2)));
// Spike gauntlet
platforms.push(game.addChild(new Platform(400, 40, 1850, 2000)));
spikes.push(game.addChild(new Spike(1900, 2000)));
spikes.push(game.addChild(new Spike(1940, 2000)));
spikes.push(game.addChild(new Spike(1980, 2000)));
spikes.push(game.addChild(new Spike(2020, 2000)));
spikes.push(game.addChild(new Spike(2060, 2000)));
// Final platform section
platforms.push(game.addChild(new Platform(200, 40, 2300, 1900)));
// Fast moving platform to goal
movingPlatforms.push(game.addChild(new MovingPlatform(2600, 1850, 200, 4)));
// Goal
goal = game.addChild(new Goal(2850, 1850));
}
// Level 3 - Devil's Challenge with precise timing
else if (currentLevel === 3) {
// Narrow starting platform
platforms.push(game.addChild(new Platform(200, 40, 100, 2450)));
// Immediate spike danger
spikes.push(game.addChild(new Spike(320, 2450)));
// First precise jump
platforms.push(game.addChild(new Platform(100, 40, 380, 2350)));
// Triple moving platforms in sequence
movingPlatforms.push(game.addChild(new MovingPlatform(550, 2300, 120, 3.5)));
movingPlatforms.push(game.addChild(new MovingPlatform(750, 2250, 100, 4)));
movingPlatforms.push(game.addChild(new MovingPlatform(950, 2200, 150, 2.8)));
// Spike corridor
platforms.push(game.addChild(new Platform(80, 40, 1200, 2200)));
spikes.push(game.addChild(new Spike(1220, 2200)));
platforms.push(game.addChild(new Platform(80, 40, 1320, 2200)));
spikes.push(game.addChild(new Spike(1340, 2200)));
platforms.push(game.addChild(new Platform(80, 40, 1440, 2200)));
// Checkpoint before final section
checkpoints.push(game.addChild(new Checkpoint(1480, 2200)));
// Fast alternating platforms
movingPlatforms.push(game.addChild(new MovingPlatform(1600, 2100, 200, 5)));
movingPlatforms.push(game.addChild(new MovingPlatform(1900, 2050, 180, 4.5)));
// Spike maze finale
platforms.push(game.addChild(new Platform(300, 40, 2200, 2000)));
spikes.push(game.addChild(new Spike(2250, 2000)));
spikes.push(game.addChild(new Spike(2290, 2000)));
platforms.push(game.addChild(new Platform(100, 40, 2350, 2000)));
spikes.push(game.addChild(new Spike(2370, 2000)));
platforms.push(game.addChild(new Platform(100, 40, 2500, 1950)));
// Final ultra-fast moving platform
movingPlatforms.push(game.addChild(new MovingPlatform(2650, 1900, 250, 6)));
// Goal at the end
goal = game.addChild(new Goal(2950, 1900));
}
}
// Input handling
var isJumpPressed = false;
var jumpHoldTime = 0;
var maxJumpHoldTime = 15;
game.down = function (x, y, obj) {
isJumpPressed = true;
jumpHoldTime = 0;
player.jump();
};
game.up = function (x, y, obj) {
isJumpPressed = false;
jumpHoldTime = 0;
};
// Reset button functionality
resetButton.down = function (x, y, obj) {
// Reset level variables
attempts = 0;
startTime = Date.now();
lastCheckpointX = 200;
lastCheckpointY = 2400;
// Flash effect to show reset activated
LK.effects.flashScreen(0x4444FF, 300);
// Reinitialize current level
initLevel();
};
// Collision detection
function checkCollisions() {
if (player.isDead) return;
player.isGrounded = false;
// Platform collisions
for (var i = 0; i < platforms.length; i++) {
var platform = platforms[i];
if (player.intersects(platform)) {
if (player.velocityY > 0 && player.y - 30 < platform.y) {
player.y = platform.y;
player.velocityY = 0;
player.isGrounded = true;
}
}
}
// Moving platform collisions
for (var i = 0; i < movingPlatforms.length; i++) {
var platform = movingPlatforms[i];
if (player.intersects(platform)) {
if (player.velocityY > 0 && player.y - 30 < platform.y) {
player.y = platform.y;
player.velocityY = 0;
player.isGrounded = true;
// Move player with platform
player.x += platform.moveSpeed * platform.direction;
}
}
}
// Spike collisions
for (var i = 0; i < spikes.length; i++) {
var spike = spikes[i];
if (player.intersects(spike)) {
player.die();
return;
}
}
// Checkpoint collisions
for (var i = 0; i < checkpoints.length; i++) {
var checkpoint = checkpoints[i];
if (player.intersects(checkpoint)) {
checkpoint.activate();
}
}
// Goal collision
if (goal && player.intersects(goal)) {
// Level complete
var completionTime = Math.floor((Date.now() - startTime) / 1000);
var score = Math.max(1000 - attempts * 50 - completionTime, 100);
LK.setScore(LK.getScore() + score);
LK.getSound('levelComplete').play();
LK.effects.flashScreen(0x00ff00, 1000);
// Next level
currentLevel++;
storage.currentLevel = currentLevel;
if (currentLevel > 3) {
LK.showYouWin();
} else {
// Reset for next level
attempts = 0;
startTime = Date.now();
lastCheckpointX = 200;
lastCheckpointY = 2400;
levelTxt.setText('Level ' + currentLevel);
LK.setTimeout(function () {
initLevel();
}, 1000);
}
}
}
// Camera follow
function updateCamera() {
if (player) {
// Follow player horizontally with some offset
var targetOffsetX = -(player.x - 1024);
cameraOffsetX += (targetOffsetX - cameraOffsetX) * 0.1;
// Clamp camera to reasonable bounds
cameraOffsetX = Math.max(cameraOffsetX, -2000);
cameraOffsetX = Math.min(cameraOffsetX, 200);
game.x = cameraOffsetX;
}
}
// Variable jump mechanics
function handleJumpInput() {
if (isJumpPressed && jumpHoldTime < maxJumpHoldTime && player.velocityY < 0) {
player.velocityY -= 0.8; // Additional upward force while holding
jumpHoldTime++;
}
}
// Main game loop
game.update = function () {
handleJumpInput();
// Update moving platforms
for (var i = 0; i < movingPlatforms.length; i++) {
movingPlatforms[i].update();
}
checkCollisions();
updateCamera();
// Update UI
attemptsTxt.setText('Attempts: ' + attempts);
};
// Initialize the game
initLevel(); ===================================================================
--- original.js
+++ change.js
@@ -228,8 +228,74 @@
spikes.push(game.addChild(new Spike(1600, 2150)));
// Goal
goal = game.addChild(new Goal(1750, 2100));
}
+ // Level 2 - Moving platforms and timing challenges
+ else if (currentLevel === 2) {
+ // Starting platform
+ platforms.push(game.addChild(new Platform(250, 40, 100, 2450)));
+ // First moving platform
+ movingPlatforms.push(game.addChild(new MovingPlatform(400, 2350, 200, 3)));
+ // Spike trap after moving platform
+ spikes.push(game.addChild(new Spike(650, 2350)));
+ spikes.push(game.addChild(new Spike(690, 2350)));
+ // High jump section
+ platforms.push(game.addChild(new Platform(150, 40, 800, 2250)));
+ platforms.push(game.addChild(new Platform(120, 40, 1050, 2150)));
+ // Checkpoint at mid-level
+ checkpoints.push(game.addChild(new Checkpoint(1120, 2150)));
+ // Double moving platform challenge
+ movingPlatforms.push(game.addChild(new MovingPlatform(1300, 2100, 180, 2.5)));
+ movingPlatforms.push(game.addChild(new MovingPlatform(1600, 2050, 150, 2)));
+ // Spike gauntlet
+ platforms.push(game.addChild(new Platform(400, 40, 1850, 2000)));
+ spikes.push(game.addChild(new Spike(1900, 2000)));
+ spikes.push(game.addChild(new Spike(1940, 2000)));
+ spikes.push(game.addChild(new Spike(1980, 2000)));
+ spikes.push(game.addChild(new Spike(2020, 2000)));
+ spikes.push(game.addChild(new Spike(2060, 2000)));
+ // Final platform section
+ platforms.push(game.addChild(new Platform(200, 40, 2300, 1900)));
+ // Fast moving platform to goal
+ movingPlatforms.push(game.addChild(new MovingPlatform(2600, 1850, 200, 4)));
+ // Goal
+ goal = game.addChild(new Goal(2850, 1850));
+ }
+ // Level 3 - Devil's Challenge with precise timing
+ else if (currentLevel === 3) {
+ // Narrow starting platform
+ platforms.push(game.addChild(new Platform(200, 40, 100, 2450)));
+ // Immediate spike danger
+ spikes.push(game.addChild(new Spike(320, 2450)));
+ // First precise jump
+ platforms.push(game.addChild(new Platform(100, 40, 380, 2350)));
+ // Triple moving platforms in sequence
+ movingPlatforms.push(game.addChild(new MovingPlatform(550, 2300, 120, 3.5)));
+ movingPlatforms.push(game.addChild(new MovingPlatform(750, 2250, 100, 4)));
+ movingPlatforms.push(game.addChild(new MovingPlatform(950, 2200, 150, 2.8)));
+ // Spike corridor
+ platforms.push(game.addChild(new Platform(80, 40, 1200, 2200)));
+ spikes.push(game.addChild(new Spike(1220, 2200)));
+ platforms.push(game.addChild(new Platform(80, 40, 1320, 2200)));
+ spikes.push(game.addChild(new Spike(1340, 2200)));
+ platforms.push(game.addChild(new Platform(80, 40, 1440, 2200)));
+ // Checkpoint before final section
+ checkpoints.push(game.addChild(new Checkpoint(1480, 2200)));
+ // Fast alternating platforms
+ movingPlatforms.push(game.addChild(new MovingPlatform(1600, 2100, 200, 5)));
+ movingPlatforms.push(game.addChild(new MovingPlatform(1900, 2050, 180, 4.5)));
+ // Spike maze finale
+ platforms.push(game.addChild(new Platform(300, 40, 2200, 2000)));
+ spikes.push(game.addChild(new Spike(2250, 2000)));
+ spikes.push(game.addChild(new Spike(2290, 2000)));
+ platforms.push(game.addChild(new Platform(100, 40, 2350, 2000)));
+ spikes.push(game.addChild(new Spike(2370, 2000)));
+ platforms.push(game.addChild(new Platform(100, 40, 2500, 1950)));
+ // Final ultra-fast moving platform
+ movingPlatforms.push(game.addChild(new MovingPlatform(2650, 1900, 250, 6)));
+ // Goal at the end
+ goal = game.addChild(new Goal(2950, 1900));
+ }
}
// Input handling
var isJumpPressed = false;
var jumpHoldTime = 0;
Modern App Store icon, high definition, square with rounded corners, for a game titled "Devil's Parkour Challenge" and with the description "Navigate treacherous obstacle courses filled with spikes and moving platforms in this challenging parkour platformer that tests your timing and precision.". No text on icon!