/**** * Classes ****/ var DashEffect = Container.expand(function () { var self = Container.call(this); var effectGraphics = self.attachAsset('dashEffect', { anchorX: 0.5, anchorY: 0.5 }); self.lifetime = 10; self.alpha = 0.8; self.update = function () { self.lifetime--; self.alpha = self.lifetime / 10; self.x -= 15 * 0.7; if (self.lifetime <= 0) { self.destroy(); return true; } return false; }; }); var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemyShape', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 10; self.verticalSpeed = Math.random() * 4 - 2; self.verticalDirection = 1; self.verticalDistance = 0; self.maxVerticalDistance = 100 + Math.random() * 200; self.update = function (gameSpeed) { self.x -= self.speed * gameSpeed * 0.7; // Vertical movement self.verticalDistance += Math.abs(self.verticalSpeed); if (self.verticalDistance > self.maxVerticalDistance) { self.verticalDirection *= -1; self.verticalDistance = 0; } self.y += self.verticalSpeed * self.verticalDirection; // Keep within bounds if (self.y < self.height / 2) { self.y = self.height / 2; self.verticalDirection *= -1; } else if (self.y > 2732 - 400) { self.y = 2732 - 400; self.verticalDirection *= -1; } return self.x < -100; }; }); var Obstacle = Container.expand(function () { var self = Container.call(this); var obstacleGraphics = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 15; self.update = function (gameSpeed) { self.x -= self.speed * gameSpeed * 0.7; return self.x < -100; }; }); var Particle = Container.expand(function () { var self = Container.call(this); var particleGraphics = self.attachAsset('particle', { anchorX: 0.5, anchorY: 0.5 }); self.lifetime = 30; self.alpha = 1; self.scale.set(1); self.update = function () { self.lifetime--; self.alpha = self.lifetime / 30; self.scale.set(1 - self.lifetime / 30 * 0.5); if (self.lifetime <= 0) { self.destroy(); return true; } return false; }; }); var Platform = Container.expand(function (width, layer) { var self = Container.call(this); var platformWidth = width || 200; var platformGraphics = self.attachAsset('platform', { anchorX: 0.5, anchorY: 0.5, width: platformWidth }); // Color platforms based on layer var layerColors = [0x00ffff, 0x00ccff, 0x0099ff, 0x0066ff, 0x0033ff]; if (layer !== undefined && layer < layerColors.length) { platformGraphics.tint = layerColors[layer]; } self.speed = 12; self.layer = layer || 0; self.update = function (gameSpeed) { self.x -= self.speed * gameSpeed * 0.7; return self.x < -platformWidth / 2; }; self.getWidth = function () { return platformWidth; }; self.getHeight = function () { return platformGraphics.height; }; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('platform', { anchorX: 0.5, anchorY: 0.5, width: 60, height: 60 }); playerGraphics.tint = 0x00ffaa; self.velocity = { x: 0, y: 0 }; self.baseX = 300; self.speed = 20; self.jumpForce = -25; self.gravity = 1; self.isJumping = false; self.isDashing = false; self.dashCooldown = 0; self.dashDuration = 0; self.dashDistance = 0; self.dashMaxDistance = 200; self.hasShield = false; self.shieldObj = null; self.particles = []; self.onPlatform = false; self.currentPlatform = null; self.jump = function () { if (!self.isJumping || self.onPlatform) { self.velocity.y = self.jumpForce; self.isJumping = true; self.onPlatform = false; self.currentPlatform = null; LK.getSound('jump').play(); // Play jump sound } }; self.dash = function () { if (self.dashCooldown <= 0) { LK.getSound('dash-fast').play(); self.isDashing = true; self.dashDuration = 15; self.dashCooldown = 60; self.dashDistance = 0; // Create dash effect var effect = new DashEffect(); effect.x = self.x - 50; effect.y = self.y; self.parent.addChild(effect); } }; self.activateShield = function () { self.hasShield = true; if (!self.shieldObj) { self.shieldObj = self.addChild(new Shield()); } }; self.deactivateShield = function () { self.hasShield = false; if (self.shieldObj) { self.shieldObj.destroy(); self.shieldObj = null; } }; self.update = function () { // Apply gravity if jumping if (self.isJumping && !self.onPlatform) { self.velocity.y += self.gravity; } // Update position self.y += self.velocity.y; // Handle dash if (self.isDashing) { if (self.dashDistance < self.dashMaxDistance) { self.x += 15 * 0.7; self.dashDistance += 15 * 0.7; } else { self.x = Math.max(self.x - 10, self.baseX); if (self.x <= self.baseX) { self.isDashing = false; } } self.dashDuration--; if (self.dashDuration <= 0) { self.isDashing = false; } } else { // Return to base position if not dashing if (self.x > self.baseX) { self.x = Math.max(self.x - 5, self.baseX); } } // Update dash cooldown if (self.dashCooldown > 0) { self.dashCooldown--; } // Ceiling collision if (self.y < 60) { self.y = 60; self.velocity.y = 0; } // Platform collision self.onPlatform = false; for (var i = 0; i < platforms.length; i++) { var platform = platforms[i]; // Check if player is above platform and falling if (self.velocity.y >= 0 && self.y + 30 >= platform.y - platform.getHeight() / 2 && self.y - 30 <= platform.y - platform.getHeight() / 2 && self.x + 30 >= platform.x - platform.getWidth() / 2 && self.x - 30 <= platform.x + platform.getWidth() / 2) { self.y = platform.y - platform.getHeight() / 2 - 30; self.velocity.y = 0; self.isJumping = false; self.onPlatform = true; self.currentPlatform = platform; break; } } // If was on platform but platform moved away if (self.currentPlatform && !self.onPlatform) { self.isJumping = true; self.currentPlatform = null; } // Create trail particles if (LK.ticks % 3 === 0) { var particle = new Particle(); particle.x = self.x - 30; particle.y = self.y; particle.tint = self.isDashing ? 0xffffff : 0x00ffaa; self.parent.addChild(particle); self.particles.push(particle); } // Update particles for (var j = self.particles.length - 1; j >= 0; j--) { if (self.particles[j].update()) { self.particles.splice(j, 1); } } }; }); var PowerUp = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); self.type = Math.random() < 0.5 ? 'shield' : 'score'; powerupGraphics.tint = self.type === 'shield' ? 0x3399ff : 0xffff00; self.speed = 8; self.rotation = 0; self.update = function (gameSpeed) { self.x -= self.speed * gameSpeed * 0.7; self.rotation += 0.05; return self.x < -100; }; }); var ScorePopup = Container.expand(function (value, color) { var self = Container.call(this); var scoreTxt = new Text2("+" + value, { size: 40, fill: color || 0xffff00 }); scoreTxt.anchor.set(0.5); self.addChild(scoreTxt); self.lifetime = 30; self.update = function () { self.lifetime--; self.y -= 2; self.alpha = self.lifetime / 30; if (self.lifetime <= 0) { self.destroy(); return true; } return false; }; }); var Shield = Container.expand(function () { var self = Container.call(this); var shieldGraphics = self.attachAsset('shield', { anchorX: 0.5, anchorY: 0.5 }); shieldGraphics.alpha = 0.5; self.update = function () { self.rotation += 0.02; }; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000033 }); /**** * Game Code ****/ // Play background music in a loop LK.playMusic('background', { loop: true }); // Update player var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var PLATFORM_SPEED = 8; var PLAYER_WIDTH = 60; var MIN_GAP = PLAYER_WIDTH * 2; var LAYERS = 3; var LAYER_HEIGHT = 250; var FLOOR_HEIGHT = GAME_HEIGHT - 350; // Background var background = game.attachAsset('background', {}); game.addChildAt(background, 0); // Death zone var deathZone = game.attachAsset('deathZone', { anchorX: 0.5, anchorY: 0 }); deathZone.x = GAME_WIDTH / 2; deathZone.y = GAME_HEIGHT - 100; deathZone.alpha = 0.5; game.addChildAt(deathZone, 1); // Game variables var player = game.addChild(new Player()); player.x = 300; player.y = FLOOR_HEIGHT - 400; var obstacles = []; var powerups = []; var enemies = []; var platforms = []; var rightmostPlatforms = []; // Tracks the rightmost platform in each layer var effects = []; var scorePopups = []; var score = 0; var distance = 0; var gameSpeed = 1; var isGameOver = false; // Initialize rightmostPlatforms array for (var i = 0; i < LAYERS; i++) { rightmostPlatforms[i] = null; } // Create initial platforms for (var layer = 0; layer < LAYERS; layer++) { var layerY = FLOOR_HEIGHT - layer * LAYER_HEIGHT; // Create wider starting platforms for each layer var initialWidth = layer === 0 ? 800 : 600 - layer * 50; var startingPlatform = new Platform(initialWidth, layer); startingPlatform.x = initialWidth / 2 + 100; startingPlatform.y = layerY; platforms.push(startingPlatform); game.addChild(startingPlatform); rightmostPlatforms[layer] = startingPlatform; // Add a series of additional starting platforms for each layer for (var p = 0; p < 3; p++) { var additionalWidth = initialWidth * 0.7; var additionalPlatform = new Platform(additionalWidth, layer); var gap = layer === 0 ? MIN_GAP + 20 : MIN_GAP + layer * 40; additionalPlatform.x = rightmostPlatforms[layer].x + rightmostPlatforms[layer].getWidth() / 2 + gap + additionalWidth / 2; additionalPlatform.y = layerY; platforms.push(additionalPlatform); game.addChild(additionalPlatform); rightmostPlatforms[layer] = additionalPlatform; } } // Place player on the first platform player.y = rightmostPlatforms[0].y - rightmostPlatforms[0].getHeight() / 2 - player.height / 2; // UI elements var scoreTxt = new Text2('SCORE: 0', { size: 50, fill: 0xffffff }); scoreTxt.anchor.set(0, 0); scoreTxt.x = 20; scoreTxt.y = 20; LK.gui.top.addChild(scoreTxt); var distanceTxt = new Text2('DISTANCE: 0m', { size: 50, fill: 0xffffff }); distanceTxt.anchor.set(0, 0); distanceTxt.x = 20; distanceTxt.y = 80; LK.gui.top.addChild(distanceTxt); var dashMeter = new Container(); dashMeter.x = 20; dashMeter.y = 140; LK.gui.top.addChild(dashMeter); var dashBg = new Container(); var dashBgGraphics = dashBg.attachAsset('dashEffect', { anchorX: 0, anchorY: 0 }); dashBgGraphics.width = 200; dashBgGraphics.height = 20; dashBgGraphics.tint = 0x333333; dashMeter.addChild(dashBg); var dashFill = new Container(); var dashFillGraphics = dashFill.attachAsset('dashEffect', { anchorX: 0, anchorY: 0 }); dashFillGraphics.width = 200; dashFillGraphics.height = 20; dashFillGraphics.tint = 0x00ffaa; dashMeter.addChild(dashFill); var dashTxt = new Text2('DASH', { size: 30, fill: 0xffffff }); dashTxt.anchor.set(0, 0.5); dashTxt.x = 210; dashTxt.y = 10; dashMeter.addChild(dashTxt); // Control hints var controlsContainer = new Container(); controlsContainer.y = GAME_HEIGHT - 150; game.addChild(controlsContainer); var leftControlBg = new Container(); var leftControlGraphics = leftControlBg.attachAsset('platform', { anchorX: 0, anchorY: 0, width: GAME_WIDTH / 2, height: 100 }); leftControlGraphics.alpha = 0.2; controlsContainer.addChild(leftControlBg); var rightControlBg = new Container(); var rightControlGraphics = rightControlBg.attachAsset('platform', { anchorX: 0, anchorY: 0, width: GAME_WIDTH / 2, height: 100 }); rightControlGraphics.alpha = 0.2; rightControlBg.x = GAME_WIDTH / 2; controlsContainer.addChild(rightControlBg); var jumpTxt = new Text2('JUMP', { size: 40, fill: 0xffffff }); jumpTxt.anchor.set(0.5); jumpTxt.x = GAME_WIDTH / 4; jumpTxt.y = 50; controlsContainer.addChild(jumpTxt); var dashControlTxt = new Text2('DASH', { size: 40, fill: 0xffffff }); dashControlTxt.anchor.set(0.5); dashControlTxt.x = GAME_WIDTH / 4 * 3; dashControlTxt.y = 50; controlsContainer.addChild(dashControlTxt); // Input handling game.on('down', function (x, y, obj) { if (isGameOver) { return; } var event = obj; var pos = game.toLocal(event.global); if (pos.x < GAME_WIDTH / 2) { player.jump(); } else { player.dash(); } }); // Game loop LK.on('tick', function () { if (isGameOver) { return; } // Update player player.update(); // Update dash meter dashFill.scale.x = (60 - player.dashCooldown) / 60; // Update game speed gameSpeed = (1.5 + distance / 5000) * 0.7; // Update distance distance += gameSpeed; distanceTxt.setText('DISTANCE: ' + Math.floor(distance) + 'm'); // Check if player fell to death zone if (player.y > GAME_HEIGHT - 160) { gameOver(); return; } // Platform generation logic for (var layer = 0; layer < LAYERS; layer++) { // Calculate layer-specific values var layerY = FLOOR_HEIGHT - layer * LAYER_HEIGHT; var platformWidth = 400 - layer * 70 + Math.random() * 100; // Wider platforms at bottom var gapMultiplier = 1 + layer * 0.4; // Larger gaps at higher layers var minGap = MIN_GAP * gapMultiplier; var maxGap = minGap * 1.5; var actualGap = minGap + Math.random() * (maxGap - minGap); // Check if we need to generate a new platform if (!rightmostPlatforms[layer] || rightmostPlatforms[layer].x < GAME_WIDTH + 200) { // Determine new platform position var newX; if (rightmostPlatforms[layer]) { newX = rightmostPlatforms[layer].x + rightmostPlatforms[layer].getWidth() / 2 + actualGap + platformWidth / 2; } else { newX = GAME_WIDTH + platformWidth / 2; } // Create new platform var newPlatform = new Platform(platformWidth, layer); newPlatform.x = newX; newPlatform.y = layerY; platforms.push(newPlatform); game.addChild(newPlatform); rightmostPlatforms[layer] = newPlatform; } } // Spawn obstacles (less frequently) if (LK.ticks % Math.floor(90 / gameSpeed) === 0 && Math.random() < 0.3) { var obstacle = new Obstacle(); obstacle.x = GAME_WIDTH + 100; // Place obstacles on platforms or in air if (platforms.length > 0 && Math.random() < 0.7) { // Find platforms that are currently on screen or just off to the right var viablePlatforms = platforms.filter(function (p) { return p.x > player.x && p.x < GAME_WIDTH + 200; }); if (viablePlatforms.length > 0) { var randomPlatform = viablePlatforms[Math.floor(Math.random() * viablePlatforms.length)]; obstacle.x = randomPlatform.x; obstacle.y = randomPlatform.y - randomPlatform.getHeight() / 2 - obstacle.height / 2; } else { obstacle.y = player.y + (Math.random() * 200 - 100); } } else { obstacle.y = player.y + (Math.random() * 200 - 100); } obstacles.push(obstacle); game.addChild(obstacle); } // Spawn enemies (more frequently) if (LK.ticks % Math.floor(60 / gameSpeed) === 0 && Math.random() < 0.6) { var enemy = new Enemy(); enemy.x = GAME_WIDTH + 100; // Spawn enemies close to player height enemy.y = player.y + (Math.random() * 300 - 150); // Keep within playable bounds enemy.y = Math.max(100, Math.min(GAME_HEIGHT - 400, enemy.y)); enemies.push(enemy); game.addChild(enemy); } // Spawn powerups (occasionally) if (LK.ticks % Math.floor(180 / gameSpeed) === 0 && Math.random() < 0.4) { var powerup = new PowerUp(); powerup.x = GAME_WIDTH + 100; // Place powerups on platforms or in air if (platforms.length > 0 && Math.random() < 0.7) { // Find platforms that are currently on screen or just off to the right var viablePlatforms = platforms.filter(function (p) { return p.x > GAME_WIDTH / 2 && p.x < GAME_WIDTH + 200; }); if (viablePlatforms.length > 0) { var randomPlatform = viablePlatforms[Math.floor(Math.random() * viablePlatforms.length)]; powerup.x = randomPlatform.x; powerup.y = randomPlatform.y - randomPlatform.getHeight() / 2 - powerup.height / 2; } else { powerup.y = FLOOR_HEIGHT - 200 - Math.random() * 300; } } else { powerup.y = FLOOR_HEIGHT - 200 - Math.random() * 300; } powerups.push(powerup); game.addChild(powerup); } // Update platforms for (var p = platforms.length - 1; p >= 0; p--) { if (platforms[p].update(gameSpeed)) { // If this was a rightmost platform, clear that reference for (var l = 0; l < LAYERS; l++) { if (rightmostPlatforms[l] === platforms[p]) { rightmostPlatforms[l] = null; } } platforms[p].destroy(); platforms.splice(p, 1); } } // Update obstacles for (var i = obstacles.length - 1; i >= 0; i--) { if (obstacles[i].update(gameSpeed)) { obstacles[i].destroy(); obstacles.splice(i, 1); continue; } // Collision with player if (obstacles[i].intersects(player)) { if (player.isDashing) { // Destroy obstacle when dashing var points = 50; score += points; var popup = new ScorePopup(points, 0x00ffaa); popup.x = obstacles[i].x; popup.y = obstacles[i].y; scorePopups.push(popup); game.addChild(popup); obstacles[i].destroy(); obstacles.splice(i, 1); } else if (player.hasShield) { // Shield protects from one hit player.deactivateShield(); obstacles[i].destroy(); obstacles.splice(i, 1); } else { // Game over gameOver(); } } } // Update powerups for (var j = powerups.length - 1; j >= 0; j--) { if (powerups[j].update(gameSpeed)) { powerups[j].destroy(); powerups.splice(j, 1); continue; } // Collision with player if (powerups[j].intersects(player)) { if (powerups[j].type === 'shield') { player.activateShield(); var shieldPopup = new ScorePopup("SHIELD", 0x3399ff); shieldPopup.x = powerups[j].x; shieldPopup.y = powerups[j].y; scorePopups.push(shieldPopup); game.addChild(shieldPopup); LK.getSound('pick-shield').play(); // Play pick-shield sound } else { var bonusPoints = 100; score += bonusPoints; var scoreBonus = new ScorePopup(bonusPoints); scoreBonus.x = powerups[j].x; scoreBonus.y = powerups[j].y; scorePopups.push(scoreBonus); game.addChild(scoreBonus); LK.getSound('pick-powerup').play(); // Play pick-powerup sound } powerups[j].destroy(); powerups.splice(j, 1); } } // Update enemies for (var k = enemies.length - 1; k >= 0; k--) { if (enemies[k].update(gameSpeed)) { enemies[k].destroy(); enemies.splice(k, 1); continue; } // Collision with player if (enemies[k].intersects(player)) { if (player.isDashing) { // Destroy enemy when dashing var enemyPoints = 200; score += enemyPoints; var enemyPopup = new ScorePopup(enemyPoints, 0xff00ff); enemyPopup.x = enemies[k].x; enemyPopup.y = enemies[k].y; scorePopups.push(enemyPopup); game.addChild(enemyPopup); enemies[k].destroy(); enemies.splice(k, 1); } else if (player.hasShield) { // Shield protects from one hit player.deactivateShield(); enemies[k].destroy(); enemies.splice(k, 1); } else { // Game over gameOver(); } } } // Update shield if (player.shieldObj) { player.shieldObj.update(); } // Update score popups for (var m = scorePopups.length - 1; m >= 0; m--) { if (scorePopups[m].update()) { scorePopups.splice(m, 1); } } // Update score score += Math.floor(gameSpeed); scoreTxt.setText('SCORE: ' + score); LK.setScore(score); }); function gameOver() { isGameOver = true; LK.showGameOver(); }
/****
* Classes
****/
var DashEffect = Container.expand(function () {
var self = Container.call(this);
var effectGraphics = self.attachAsset('dashEffect', {
anchorX: 0.5,
anchorY: 0.5
});
self.lifetime = 10;
self.alpha = 0.8;
self.update = function () {
self.lifetime--;
self.alpha = self.lifetime / 10;
self.x -= 15 * 0.7;
if (self.lifetime <= 0) {
self.destroy();
return true;
}
return false;
};
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemyShape', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 10;
self.verticalSpeed = Math.random() * 4 - 2;
self.verticalDirection = 1;
self.verticalDistance = 0;
self.maxVerticalDistance = 100 + Math.random() * 200;
self.update = function (gameSpeed) {
self.x -= self.speed * gameSpeed * 0.7;
// Vertical movement
self.verticalDistance += Math.abs(self.verticalSpeed);
if (self.verticalDistance > self.maxVerticalDistance) {
self.verticalDirection *= -1;
self.verticalDistance = 0;
}
self.y += self.verticalSpeed * self.verticalDirection;
// Keep within bounds
if (self.y < self.height / 2) {
self.y = self.height / 2;
self.verticalDirection *= -1;
} else if (self.y > 2732 - 400) {
self.y = 2732 - 400;
self.verticalDirection *= -1;
}
return self.x < -100;
};
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 15;
self.update = function (gameSpeed) {
self.x -= self.speed * gameSpeed * 0.7;
return self.x < -100;
};
});
var Particle = Container.expand(function () {
var self = Container.call(this);
var particleGraphics = self.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5
});
self.lifetime = 30;
self.alpha = 1;
self.scale.set(1);
self.update = function () {
self.lifetime--;
self.alpha = self.lifetime / 30;
self.scale.set(1 - self.lifetime / 30 * 0.5);
if (self.lifetime <= 0) {
self.destroy();
return true;
}
return false;
};
});
var Platform = Container.expand(function (width, layer) {
var self = Container.call(this);
var platformWidth = width || 200;
var platformGraphics = self.attachAsset('platform', {
anchorX: 0.5,
anchorY: 0.5,
width: platformWidth
});
// Color platforms based on layer
var layerColors = [0x00ffff, 0x00ccff, 0x0099ff, 0x0066ff, 0x0033ff];
if (layer !== undefined && layer < layerColors.length) {
platformGraphics.tint = layerColors[layer];
}
self.speed = 12;
self.layer = layer || 0;
self.update = function (gameSpeed) {
self.x -= self.speed * gameSpeed * 0.7;
return self.x < -platformWidth / 2;
};
self.getWidth = function () {
return platformWidth;
};
self.getHeight = function () {
return platformGraphics.height;
};
});
var Player = Container.expand(function () {
var self = Container.call(this);
var playerGraphics = self.attachAsset('platform', {
anchorX: 0.5,
anchorY: 0.5,
width: 60,
height: 60
});
playerGraphics.tint = 0x00ffaa;
self.velocity = {
x: 0,
y: 0
};
self.baseX = 300;
self.speed = 20;
self.jumpForce = -25;
self.gravity = 1;
self.isJumping = false;
self.isDashing = false;
self.dashCooldown = 0;
self.dashDuration = 0;
self.dashDistance = 0;
self.dashMaxDistance = 200;
self.hasShield = false;
self.shieldObj = null;
self.particles = [];
self.onPlatform = false;
self.currentPlatform = null;
self.jump = function () {
if (!self.isJumping || self.onPlatform) {
self.velocity.y = self.jumpForce;
self.isJumping = true;
self.onPlatform = false;
self.currentPlatform = null;
LK.getSound('jump').play(); // Play jump sound
}
};
self.dash = function () {
if (self.dashCooldown <= 0) {
LK.getSound('dash-fast').play();
self.isDashing = true;
self.dashDuration = 15;
self.dashCooldown = 60;
self.dashDistance = 0;
// Create dash effect
var effect = new DashEffect();
effect.x = self.x - 50;
effect.y = self.y;
self.parent.addChild(effect);
}
};
self.activateShield = function () {
self.hasShield = true;
if (!self.shieldObj) {
self.shieldObj = self.addChild(new Shield());
}
};
self.deactivateShield = function () {
self.hasShield = false;
if (self.shieldObj) {
self.shieldObj.destroy();
self.shieldObj = null;
}
};
self.update = function () {
// Apply gravity if jumping
if (self.isJumping && !self.onPlatform) {
self.velocity.y += self.gravity;
}
// Update position
self.y += self.velocity.y;
// Handle dash
if (self.isDashing) {
if (self.dashDistance < self.dashMaxDistance) {
self.x += 15 * 0.7;
self.dashDistance += 15 * 0.7;
} else {
self.x = Math.max(self.x - 10, self.baseX);
if (self.x <= self.baseX) {
self.isDashing = false;
}
}
self.dashDuration--;
if (self.dashDuration <= 0) {
self.isDashing = false;
}
} else {
// Return to base position if not dashing
if (self.x > self.baseX) {
self.x = Math.max(self.x - 5, self.baseX);
}
}
// Update dash cooldown
if (self.dashCooldown > 0) {
self.dashCooldown--;
}
// Ceiling collision
if (self.y < 60) {
self.y = 60;
self.velocity.y = 0;
}
// Platform collision
self.onPlatform = false;
for (var i = 0; i < platforms.length; i++) {
var platform = platforms[i];
// Check if player is above platform and falling
if (self.velocity.y >= 0 && self.y + 30 >= platform.y - platform.getHeight() / 2 && self.y - 30 <= platform.y - platform.getHeight() / 2 && self.x + 30 >= platform.x - platform.getWidth() / 2 && self.x - 30 <= platform.x + platform.getWidth() / 2) {
self.y = platform.y - platform.getHeight() / 2 - 30;
self.velocity.y = 0;
self.isJumping = false;
self.onPlatform = true;
self.currentPlatform = platform;
break;
}
}
// If was on platform but platform moved away
if (self.currentPlatform && !self.onPlatform) {
self.isJumping = true;
self.currentPlatform = null;
}
// Create trail particles
if (LK.ticks % 3 === 0) {
var particle = new Particle();
particle.x = self.x - 30;
particle.y = self.y;
particle.tint = self.isDashing ? 0xffffff : 0x00ffaa;
self.parent.addChild(particle);
self.particles.push(particle);
}
// Update particles
for (var j = self.particles.length - 1; j >= 0; j--) {
if (self.particles[j].update()) {
self.particles.splice(j, 1);
}
}
};
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerupGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = Math.random() < 0.5 ? 'shield' : 'score';
powerupGraphics.tint = self.type === 'shield' ? 0x3399ff : 0xffff00;
self.speed = 8;
self.rotation = 0;
self.update = function (gameSpeed) {
self.x -= self.speed * gameSpeed * 0.7;
self.rotation += 0.05;
return self.x < -100;
};
});
var ScorePopup = Container.expand(function (value, color) {
var self = Container.call(this);
var scoreTxt = new Text2("+" + value, {
size: 40,
fill: color || 0xffff00
});
scoreTxt.anchor.set(0.5);
self.addChild(scoreTxt);
self.lifetime = 30;
self.update = function () {
self.lifetime--;
self.y -= 2;
self.alpha = self.lifetime / 30;
if (self.lifetime <= 0) {
self.destroy();
return true;
}
return false;
};
});
var Shield = Container.expand(function () {
var self = Container.call(this);
var shieldGraphics = self.attachAsset('shield', {
anchorX: 0.5,
anchorY: 0.5
});
shieldGraphics.alpha = 0.5;
self.update = function () {
self.rotation += 0.02;
};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000033
});
/****
* Game Code
****/
// Play background music in a loop
LK.playMusic('background', {
loop: true
});
// Update player
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
var PLATFORM_SPEED = 8;
var PLAYER_WIDTH = 60;
var MIN_GAP = PLAYER_WIDTH * 2;
var LAYERS = 3;
var LAYER_HEIGHT = 250;
var FLOOR_HEIGHT = GAME_HEIGHT - 350;
// Background
var background = game.attachAsset('background', {});
game.addChildAt(background, 0);
// Death zone
var deathZone = game.attachAsset('deathZone', {
anchorX: 0.5,
anchorY: 0
});
deathZone.x = GAME_WIDTH / 2;
deathZone.y = GAME_HEIGHT - 100;
deathZone.alpha = 0.5;
game.addChildAt(deathZone, 1);
// Game variables
var player = game.addChild(new Player());
player.x = 300;
player.y = FLOOR_HEIGHT - 400;
var obstacles = [];
var powerups = [];
var enemies = [];
var platforms = [];
var rightmostPlatforms = []; // Tracks the rightmost platform in each layer
var effects = [];
var scorePopups = [];
var score = 0;
var distance = 0;
var gameSpeed = 1;
var isGameOver = false;
// Initialize rightmostPlatforms array
for (var i = 0; i < LAYERS; i++) {
rightmostPlatforms[i] = null;
}
// Create initial platforms
for (var layer = 0; layer < LAYERS; layer++) {
var layerY = FLOOR_HEIGHT - layer * LAYER_HEIGHT;
// Create wider starting platforms for each layer
var initialWidth = layer === 0 ? 800 : 600 - layer * 50;
var startingPlatform = new Platform(initialWidth, layer);
startingPlatform.x = initialWidth / 2 + 100;
startingPlatform.y = layerY;
platforms.push(startingPlatform);
game.addChild(startingPlatform);
rightmostPlatforms[layer] = startingPlatform;
// Add a series of additional starting platforms for each layer
for (var p = 0; p < 3; p++) {
var additionalWidth = initialWidth * 0.7;
var additionalPlatform = new Platform(additionalWidth, layer);
var gap = layer === 0 ? MIN_GAP + 20 : MIN_GAP + layer * 40;
additionalPlatform.x = rightmostPlatforms[layer].x + rightmostPlatforms[layer].getWidth() / 2 + gap + additionalWidth / 2;
additionalPlatform.y = layerY;
platforms.push(additionalPlatform);
game.addChild(additionalPlatform);
rightmostPlatforms[layer] = additionalPlatform;
}
}
// Place player on the first platform
player.y = rightmostPlatforms[0].y - rightmostPlatforms[0].getHeight() / 2 - player.height / 2;
// UI elements
var scoreTxt = new Text2('SCORE: 0', {
size: 50,
fill: 0xffffff
});
scoreTxt.anchor.set(0, 0);
scoreTxt.x = 20;
scoreTxt.y = 20;
LK.gui.top.addChild(scoreTxt);
var distanceTxt = new Text2('DISTANCE: 0m', {
size: 50,
fill: 0xffffff
});
distanceTxt.anchor.set(0, 0);
distanceTxt.x = 20;
distanceTxt.y = 80;
LK.gui.top.addChild(distanceTxt);
var dashMeter = new Container();
dashMeter.x = 20;
dashMeter.y = 140;
LK.gui.top.addChild(dashMeter);
var dashBg = new Container();
var dashBgGraphics = dashBg.attachAsset('dashEffect', {
anchorX: 0,
anchorY: 0
});
dashBgGraphics.width = 200;
dashBgGraphics.height = 20;
dashBgGraphics.tint = 0x333333;
dashMeter.addChild(dashBg);
var dashFill = new Container();
var dashFillGraphics = dashFill.attachAsset('dashEffect', {
anchorX: 0,
anchorY: 0
});
dashFillGraphics.width = 200;
dashFillGraphics.height = 20;
dashFillGraphics.tint = 0x00ffaa;
dashMeter.addChild(dashFill);
var dashTxt = new Text2('DASH', {
size: 30,
fill: 0xffffff
});
dashTxt.anchor.set(0, 0.5);
dashTxt.x = 210;
dashTxt.y = 10;
dashMeter.addChild(dashTxt);
// Control hints
var controlsContainer = new Container();
controlsContainer.y = GAME_HEIGHT - 150;
game.addChild(controlsContainer);
var leftControlBg = new Container();
var leftControlGraphics = leftControlBg.attachAsset('platform', {
anchorX: 0,
anchorY: 0,
width: GAME_WIDTH / 2,
height: 100
});
leftControlGraphics.alpha = 0.2;
controlsContainer.addChild(leftControlBg);
var rightControlBg = new Container();
var rightControlGraphics = rightControlBg.attachAsset('platform', {
anchorX: 0,
anchorY: 0,
width: GAME_WIDTH / 2,
height: 100
});
rightControlGraphics.alpha = 0.2;
rightControlBg.x = GAME_WIDTH / 2;
controlsContainer.addChild(rightControlBg);
var jumpTxt = new Text2('JUMP', {
size: 40,
fill: 0xffffff
});
jumpTxt.anchor.set(0.5);
jumpTxt.x = GAME_WIDTH / 4;
jumpTxt.y = 50;
controlsContainer.addChild(jumpTxt);
var dashControlTxt = new Text2('DASH', {
size: 40,
fill: 0xffffff
});
dashControlTxt.anchor.set(0.5);
dashControlTxt.x = GAME_WIDTH / 4 * 3;
dashControlTxt.y = 50;
controlsContainer.addChild(dashControlTxt);
// Input handling
game.on('down', function (x, y, obj) {
if (isGameOver) {
return;
}
var event = obj;
var pos = game.toLocal(event.global);
if (pos.x < GAME_WIDTH / 2) {
player.jump();
} else {
player.dash();
}
});
// Game loop
LK.on('tick', function () {
if (isGameOver) {
return;
}
// Update player
player.update();
// Update dash meter
dashFill.scale.x = (60 - player.dashCooldown) / 60;
// Update game speed
gameSpeed = (1.5 + distance / 5000) * 0.7;
// Update distance
distance += gameSpeed;
distanceTxt.setText('DISTANCE: ' + Math.floor(distance) + 'm');
// Check if player fell to death zone
if (player.y > GAME_HEIGHT - 160) {
gameOver();
return;
}
// Platform generation logic
for (var layer = 0; layer < LAYERS; layer++) {
// Calculate layer-specific values
var layerY = FLOOR_HEIGHT - layer * LAYER_HEIGHT;
var platformWidth = 400 - layer * 70 + Math.random() * 100; // Wider platforms at bottom
var gapMultiplier = 1 + layer * 0.4; // Larger gaps at higher layers
var minGap = MIN_GAP * gapMultiplier;
var maxGap = minGap * 1.5;
var actualGap = minGap + Math.random() * (maxGap - minGap);
// Check if we need to generate a new platform
if (!rightmostPlatforms[layer] || rightmostPlatforms[layer].x < GAME_WIDTH + 200) {
// Determine new platform position
var newX;
if (rightmostPlatforms[layer]) {
newX = rightmostPlatforms[layer].x + rightmostPlatforms[layer].getWidth() / 2 + actualGap + platformWidth / 2;
} else {
newX = GAME_WIDTH + platformWidth / 2;
}
// Create new platform
var newPlatform = new Platform(platformWidth, layer);
newPlatform.x = newX;
newPlatform.y = layerY;
platforms.push(newPlatform);
game.addChild(newPlatform);
rightmostPlatforms[layer] = newPlatform;
}
}
// Spawn obstacles (less frequently)
if (LK.ticks % Math.floor(90 / gameSpeed) === 0 && Math.random() < 0.3) {
var obstacle = new Obstacle();
obstacle.x = GAME_WIDTH + 100;
// Place obstacles on platforms or in air
if (platforms.length > 0 && Math.random() < 0.7) {
// Find platforms that are currently on screen or just off to the right
var viablePlatforms = platforms.filter(function (p) {
return p.x > player.x && p.x < GAME_WIDTH + 200;
});
if (viablePlatforms.length > 0) {
var randomPlatform = viablePlatforms[Math.floor(Math.random() * viablePlatforms.length)];
obstacle.x = randomPlatform.x;
obstacle.y = randomPlatform.y - randomPlatform.getHeight() / 2 - obstacle.height / 2;
} else {
obstacle.y = player.y + (Math.random() * 200 - 100);
}
} else {
obstacle.y = player.y + (Math.random() * 200 - 100);
}
obstacles.push(obstacle);
game.addChild(obstacle);
}
// Spawn enemies (more frequently)
if (LK.ticks % Math.floor(60 / gameSpeed) === 0 && Math.random() < 0.6) {
var enemy = new Enemy();
enemy.x = GAME_WIDTH + 100;
// Spawn enemies close to player height
enemy.y = player.y + (Math.random() * 300 - 150);
// Keep within playable bounds
enemy.y = Math.max(100, Math.min(GAME_HEIGHT - 400, enemy.y));
enemies.push(enemy);
game.addChild(enemy);
}
// Spawn powerups (occasionally)
if (LK.ticks % Math.floor(180 / gameSpeed) === 0 && Math.random() < 0.4) {
var powerup = new PowerUp();
powerup.x = GAME_WIDTH + 100;
// Place powerups on platforms or in air
if (platforms.length > 0 && Math.random() < 0.7) {
// Find platforms that are currently on screen or just off to the right
var viablePlatforms = platforms.filter(function (p) {
return p.x > GAME_WIDTH / 2 && p.x < GAME_WIDTH + 200;
});
if (viablePlatforms.length > 0) {
var randomPlatform = viablePlatforms[Math.floor(Math.random() * viablePlatforms.length)];
powerup.x = randomPlatform.x;
powerup.y = randomPlatform.y - randomPlatform.getHeight() / 2 - powerup.height / 2;
} else {
powerup.y = FLOOR_HEIGHT - 200 - Math.random() * 300;
}
} else {
powerup.y = FLOOR_HEIGHT - 200 - Math.random() * 300;
}
powerups.push(powerup);
game.addChild(powerup);
}
// Update platforms
for (var p = platforms.length - 1; p >= 0; p--) {
if (platforms[p].update(gameSpeed)) {
// If this was a rightmost platform, clear that reference
for (var l = 0; l < LAYERS; l++) {
if (rightmostPlatforms[l] === platforms[p]) {
rightmostPlatforms[l] = null;
}
}
platforms[p].destroy();
platforms.splice(p, 1);
}
}
// Update obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
if (obstacles[i].update(gameSpeed)) {
obstacles[i].destroy();
obstacles.splice(i, 1);
continue;
}
// Collision with player
if (obstacles[i].intersects(player)) {
if (player.isDashing) {
// Destroy obstacle when dashing
var points = 50;
score += points;
var popup = new ScorePopup(points, 0x00ffaa);
popup.x = obstacles[i].x;
popup.y = obstacles[i].y;
scorePopups.push(popup);
game.addChild(popup);
obstacles[i].destroy();
obstacles.splice(i, 1);
} else if (player.hasShield) {
// Shield protects from one hit
player.deactivateShield();
obstacles[i].destroy();
obstacles.splice(i, 1);
} else {
// Game over
gameOver();
}
}
}
// Update powerups
for (var j = powerups.length - 1; j >= 0; j--) {
if (powerups[j].update(gameSpeed)) {
powerups[j].destroy();
powerups.splice(j, 1);
continue;
}
// Collision with player
if (powerups[j].intersects(player)) {
if (powerups[j].type === 'shield') {
player.activateShield();
var shieldPopup = new ScorePopup("SHIELD", 0x3399ff);
shieldPopup.x = powerups[j].x;
shieldPopup.y = powerups[j].y;
scorePopups.push(shieldPopup);
game.addChild(shieldPopup);
LK.getSound('pick-shield').play(); // Play pick-shield sound
} else {
var bonusPoints = 100;
score += bonusPoints;
var scoreBonus = new ScorePopup(bonusPoints);
scoreBonus.x = powerups[j].x;
scoreBonus.y = powerups[j].y;
scorePopups.push(scoreBonus);
game.addChild(scoreBonus);
LK.getSound('pick-powerup').play(); // Play pick-powerup sound
}
powerups[j].destroy();
powerups.splice(j, 1);
}
}
// Update enemies
for (var k = enemies.length - 1; k >= 0; k--) {
if (enemies[k].update(gameSpeed)) {
enemies[k].destroy();
enemies.splice(k, 1);
continue;
}
// Collision with player
if (enemies[k].intersects(player)) {
if (player.isDashing) {
// Destroy enemy when dashing
var enemyPoints = 200;
score += enemyPoints;
var enemyPopup = new ScorePopup(enemyPoints, 0xff00ff);
enemyPopup.x = enemies[k].x;
enemyPopup.y = enemies[k].y;
scorePopups.push(enemyPopup);
game.addChild(enemyPopup);
enemies[k].destroy();
enemies.splice(k, 1);
} else if (player.hasShield) {
// Shield protects from one hit
player.deactivateShield();
enemies[k].destroy();
enemies.splice(k, 1);
} else {
// Game over
gameOver();
}
}
}
// Update shield
if (player.shieldObj) {
player.shieldObj.update();
}
// Update score popups
for (var m = scorePopups.length - 1; m >= 0; m--) {
if (scorePopups[m].update()) {
scorePopups.splice(m, 1);
}
}
// Update score
score += Math.floor(gameSpeed);
scoreTxt.setText('SCORE: ' + score);
LK.setScore(score);
});
function gameOver() {
isGameOver = true;
LK.showGameOver();
}
neon for obstacle in endless runner game, like a spiky obstacle but still many rectangle or angled surfaces, not round, pink neon colors. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows. neon. polygon shapes
flying neon enemy, blocky, sharp angles. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows