/****
* 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));
}
}
// 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
@@ -183,8 +183,16 @@
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 = [];
@@ -234,8 +242,20 @@
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;
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!