User prompt
Increase slide speed
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'tween(self, {' Line Number: 261
User prompt
Slide faster is not working
User prompt
Swipe right side any where on the screen to slide
User prompt
Add swipe to slide faster for 200 ms and get back normal ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Remove hold to slide
User prompt
replace hold to slided to swipe right to slide 1 sec fasster
User prompt
swipe to slide fast for a second is not working properly
User prompt
player hit by the enemey cube for three times to game over
User prompt
replace hold to slide to right swipe to faster slide (slide 1 sec faster)
User prompt
swipe right to move 2 sec faster
User prompt
replace hold to slide to swipe to slide
User prompt
double jump should be little higher jump
User prompt
aadd double bounce to the player for double clicl
User prompt
i need enemy obstacle on the top parellel like player shooting the cubes towards the player from upside if the cubes hit the player game over
User prompt
search lights always follows thge player
User prompt
i need the cube should rotate while moving ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
particles also rotate along with cube
User prompt
cube need to rotate slowly while moving ↪💡 Consider importing and using the following plugins: @upit/tween.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Sqube Darkness
Initial prompt
Key Features of Sqube Darkness: You play as a small cube (sqube) running across platforms. The game is set in a shadowy world, where the background and obstacles are dark, and the cube is often the only clear object. The gameplay involves: Running, jumping, sliding. Avoiding obstacles like spikes and lasers. Sometimes, using the shadows to hide from enemies (like searchlights or shooters). The game has a procedurally generated endless level, meaning every run is different. 🎨 Aesthetic: Monochrome color palette: Mostly black, white, and gray tones. Minimal UI and a smooth, satisfying movement system. Cool audio effects and smooth transitions.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Enemy = Container.expand(function () { var self = Container.call(this); // Enemy visual var cube = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5, tint: 0xff0000 }); self.width = cube.width; self.height = cube.height; self.speed = 7; self.shootTimer = 0; self.shootInterval = 120; // Shoot every 120 frames (2 seconds) self.update = function () { self.x -= self.speed; self.shootTimer++; if (self.shootTimer >= self.shootInterval) { self.shoot(); self.shootTimer = 0; } // Remove if off screen if (self.x < -self.width) { self.destroy(); return true; // Signal to remove from the array } return false; }; self.shoot = function () { if (gameRunning && !player.isDead) { // Only create enemy cube if there are no enemy cubes currently in the game if (enemyCubes.length === 0) { createEnemyCube(self.x, self.y); } } }; return self; }); var EnemyCube = Container.expand(function () { var self = Container.call(this); // Cube visual var cube = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6, tint: 0xff6666 }); self.width = cube.width * 0.6; self.height = cube.height * 0.6; // Calculate direction towards player's position self.velocity = { x: 0, y: 0 }; self.update = function () { // Move the cube self.x += self.velocity.x; self.y += self.velocity.y; // Rotate the cube for visual effect cube.rotation += 0.05; // Remove if off screen if (self.y > 2732 || self.x < -self.width || self.x > 2048 + self.width) { self.destroy(); return true; } return false; }; return self; }); var Obstacle = Container.expand(function (type) { var self = Container.call(this); self.type = type || 'spike'; self.speed = 10; if (self.type === 'spike') { var spikeGraphic = self.attachAsset('spike', { anchorX: 0.5, anchorY: 1.0 }); self.width = spikeGraphic.width; self.height = spikeGraphic.height; } else if (self.type === 'greenSpike') { var greenSpikeGraphic = self.attachAsset('greenSpike', { anchorX: 0.5, anchorY: 1.0 }); self.width = greenSpikeGraphic.width; self.height = greenSpikeGraphic.height; } else if (self.type === 'laser') { var laserGraphic = self.attachAsset('laser', { anchorX: 0.0, anchorY: 0.5, alpha: 0.7 }); self.width = laserGraphic.width; self.height = laserGraphic.height; // Laser activation self.active = false; self.warningTime = 30; self.activeTime = 60; self.timer = self.warningTime; // Warning effect self.flash = function () { if (self.timer % 5 === 0) { laserGraphic.alpha = laserGraphic.alpha === 0.3 ? 0.7 : 0.3; } }; } else if (self.type === 'searchlight') { var searchlightGraphic = self.attachAsset('searchlight', { anchorX: 0.5, anchorY: 0.0, alpha: 0.5 }); self.width = searchlightGraphic.width; self.height = searchlightGraphic.height; } self.update = function () { self.x -= self.speed; // Laser special behavior if (self.type === 'laser') { self.timer--; if (self.timer > 0 && !self.active) { // Warning phase self.flash(); } else if (!self.active) { // Activate self.active = true; laserGraphic.alpha = 1; self.timer = self.activeTime; // Play laser sound when activated LK.getSound('laser').play(); } else if (self.timer <= 0) { // Deactivate self.destroy(); return true; } } // Remove if off screen if (self.x < -self.width) { self.destroy(); return true; // Signal to remove from the array } return false; }; return self; }); var Platform = Container.expand(function () { var self = Container.call(this); var platformGraphic = self.attachAsset('platform', { anchorX: 0.5, anchorY: 0.0 }); self.width = platformGraphic.width; self.height = platformGraphic.height; self.speed = 10; self.update = function () { self.x -= self.speed; // Remove if off screen if (self.x < -self.width) { self.destroy(); return true; // Signal to remove from the array } return false; }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); // Player states self.isJumping = false; self.isSliding = false; self.isHiding = false; self.isDead = false; self.health = 3; // Player starts with 3 health points self.invulnerable = false; // Invulnerability after getting hit self.invulnerableTime = 0; // Track invulnerability duration self.canDoubleJump = false; self.hasDoubleJumped = false; self.canTripleJump = false; self.lastJumpTime = 0; self.velocity = { x: 0, y: 0 }; self.gravity = 1.2; self.jumpForce = -30; // Increased from -25 to -30 for higher first jump self.groundY = 2200; // Visual components var cube = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); // Set initial rotation and rotation speed self.rotationSpeed = 0.05; self.currentRotation = 0; // Particle system for the player's trail self.particles = []; // Player controls self.jump = function () { var currentTime = LK.ticks; if (!self.isDead && !self.isSliding) { if (!self.isJumping) { // First jump self.velocity.y = self.jumpForce; self.isJumping = true; self.canDoubleJump = true; self.hasDoubleJumped = false; self.canTripleJump = false; self.lastJumpTime = currentTime; // Increase rotation speed temporarily when jumping tween(self, { rotationSpeed: 0.15 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { rotationSpeed: 0.05 }, { duration: 500, easing: tween.easeIn }); } }); LK.getSound('jump').play(); } else if (self.canDoubleJump && !self.hasDoubleJumped && currentTime - self.lastJumpTime < 30) { // Double jump (only if tapped quickly after first jump) self.velocity.y = self.jumpForce * 1.2; // Higher second jump self.hasDoubleJumped = true; self.canDoubleJump = false; self.canTripleJump = true; // Enable triple jump after double jump self.lastJumpTime = currentTime; // Extra rotation boost for double jump tween(self, { rotationSpeed: 0.25 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { rotationSpeed: 0.05 }, { duration: 400, easing: tween.easeIn }); } }); LK.getSound('jump').play(); } else if (self.canTripleJump && self.hasDoubleJumped && currentTime - self.lastJumpTime < 30) { // Triple jump (only if tapped quickly after second jump) self.velocity.y = self.jumpForce * 1.3; // Even higher third jump self.canTripleJump = false; // Extreme rotation boost for triple jump tween(self, { rotationSpeed: 0.35 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { rotationSpeed: 0.05 }, { duration: 300, easing: tween.easeIn }); } }); LK.getSound('jump').play(); } } }; self.slide = function () { if (!self.isDead && !self.isSliding) { self.isSliding = true; // Set velocity directly instead of trying to tween it self.velocity.x = 10; // Increased from 5 to 10 for faster slide // Temporarily increase player speed and rotation tween(self, { rotationSpeed: 0.3 // Increased rotation speed for more visual impact }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { // Reset to normal speed after 300ms self.isSliding = false; self.velocity.x = 0; // Reset velocity directly // Store the current x position before slide ends var originalX = self.x; // Tween back to normal position tween(self, { x: originalX - 50 // Move back slightly from the slid position }, { duration: 150, easing: tween.easeOut }); tween(self, { rotationSpeed: 0.05 }, { duration: 200, easing: tween.easeIn }); } }); } }; self.hide = function (shadow) { if (!self.isDead && shadow) { self.isHiding = true; cube.alpha = 0.3; LK.getSound('hide').play(); } }; self.unhide = function () { self.isHiding = false; cube.alpha = 1; }; self.die = function () { if (self.invulnerable) { return; } // Don't take damage if invulnerable if (!self.isDead) { self.health--; if (self.health <= 0) { // Player is dead after losing all health self.isDead = true; // Stop rotation by tweening to zero tween(self, { rotationSpeed: 0 }, { duration: 100 }); LK.getSound('death').play(); LK.effects.flashScreen(0xff0000, 500); // Create death particles for (var i = 0; i < 20; i++) { var particle = LK.getAsset('particle', { anchorX: 0.5, anchorY: 0.5, x: self.x, y: self.y }); // Random velocity for each particle var angle = Math.random() * Math.PI * 2; var speed = 5 + Math.random() * 10; particle.vx = Math.cos(angle) * speed; particle.vy = Math.sin(angle) * speed; game.addChild(particle); deathParticles.push(particle); } LK.setTimeout(function () { LK.showGameOver(); }, 1000); } else { // Player still has health, make invulnerable temporarily self.invulnerable = true; self.invulnerableTime = 60; // 1 second invulnerability (60 frames) LK.effects.flashScreen(0xff0000, 200); // Play hit sound LK.getSound('hit').play(); // Flash the player to indicate damage var flashCount = 0; var flashInterval = LK.setInterval(function () { cube.alpha = cube.alpha === 1 ? 0.3 : 1; flashCount++; if (flashCount >= 6) { // Flash 3 times (6 state changes) LK.clearInterval(flashInterval); cube.alpha = 1; } }, 100); } } }; // Physics update self.updatePhysics = function () { if (self.isDead) { return; } // Update invulnerability timer if (self.invulnerable) { self.invulnerableTime--; if (self.invulnerableTime <= 0) { self.invulnerable = false; cube.alpha = 1; // Ensure player is fully visible } } // Apply gravity self.velocity.y += self.gravity; // Update position self.y += self.velocity.y; self.x += self.velocity.x; // Apply horizontal velocity for sliding // Check floor collision if (self.y >= self.groundY) { self.y = self.groundY; self.velocity.y = 0; self.isJumping = false; self.canDoubleJump = false; self.hasDoubleJumped = false; self.canTripleJump = false; } // Update cube rotation when moving if (gameRunning && !self.isDead) { self.currentRotation += self.rotationSpeed; cube.rotation = self.currentRotation; } // Create trail particles if (gameRunning && LK.ticks % 5 === 0) { var particle = LK.getAsset('particle', { anchorX: 0.5, anchorY: 0.5, x: self.x - 30, y: self.y + (self.isSliding ? 25 : 0) }); particle.alpha = 0.7; particle.life = 30; game.addChild(particle); self.particles.push(particle); } // Update particles for (var i = self.particles.length - 1; i >= 0; i--) { var p = self.particles[i]; p.alpha -= 0.02; p.scaleX -= 0.02; p.scaleY -= 0.02; p.life--; if (p.life <= 0 || p.alpha <= 0) { p.destroy(); self.particles.splice(i, 1); } } }; return self; }); var Shadow = Container.expand(function () { var self = Container.call(this); var shadowGraphic = self.attachAsset('shadow', { anchorX: 0.5, anchorY: 0.5, alpha: 0.5 }); self.width = shadowGraphic.width; self.height = shadowGraphic.height; self.speed = 10; self.update = function () { self.x -= self.speed; // Remove if off screen if (self.x < -self.width) { self.destroy(); return true; // Signal to remove from the array } return false; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x111111 }); /**** * Game Code ****/ // Game state var gameRunning = false; var speed = 10; var score = 0; var highScore = storage.highScore || 0; var platformY = 2200; var spawnDistance = 800; var nextSpawnX = 2048 + 200; var difficultyTimer = 0; var difficultyInterval = 1000; var lastTouchX = 0; var lastTouchY = 0; var touchStartTime = 0; // Game elements var player; var platforms = []; var obstacles = []; var shadows = []; var deathParticles = []; var enemies = []; var enemyCubes = []; // UI elements var scoreTxt; var highScoreTxt; var healthTxt; var tapToStartTxt; // Initialize the game function initGame() { gameRunning = false; speed = 10; score = 0; platformY = 2200; spawnDistance = 800; nextSpawnX = 2048 + 200; difficultyTimer = 0; // Clear existing elements while (platforms.length > 0) { platforms[0].destroy(); platforms.shift(); } while (obstacles.length > 0) { obstacles[0].destroy(); obstacles.shift(); } while (shadows.length > 0) { shadows[0].destroy(); shadows.shift(); } while (deathParticles.length > 0) { deathParticles[0].destroy(); deathParticles.shift(); } // Clear enemies and enemy cubes while (enemies.length > 0) { enemies[0].destroy(); enemies.shift(); } while (enemyCubes.length > 0) { enemyCubes[0].destroy(); enemyCubes.shift(); } // Add background var background = LK.getAsset('background', { anchorX: 0, anchorY: 0 }); game.addChildAt(background, 0); // Add at index 0 to ensure it's at the back // Create player player = new Player(); player.x = 400; player.y = platformY; // Position player on top edge of platform game.addChild(player); // Create initial platform createPlatform(0, platformY, 2048 + 500); // Create UI if (!scoreTxt) { scoreTxt = new Text2('Score: 0', { size: 60, fill: 0xFFFFFF }); scoreTxt.anchor.set(0, 0); LK.gui.topRight.addChild(scoreTxt); scoreTxt.x = -250; scoreTxt.y = 50; } // Create health display healthTxt = new Text2('Health: 3', { size: 60, fill: 0xFF5555 }); healthTxt.anchor.set(0, 0); LK.gui.topLeft.addChild(healthTxt); healthTxt.x = 120; // Keep away from top-left corner menu icon healthTxt.y = 50; if (!highScoreTxt) { highScoreTxt = new Text2('High Score: ' + highScore, { size: 40, fill: 0xAAAAAA }); highScoreTxt.anchor.set(0, 0); LK.gui.topRight.addChild(highScoreTxt); highScoreTxt.x = -250; highScoreTxt.y = 120; } // Create start instruction tapToStartTxt = new Text2('Tap to Start\nTap to Jump\nSwipe Right to Slide Faster', { size: 70, fill: 0xFFFFFF }); tapToStartTxt.anchor.set(0.5, 0.5); LK.gui.center.addChild(tapToStartTxt); // Start the background music LK.playMusic('gameBgm', { fade: { start: 0, end: 0.4, duration: 1000 } }); } // Create a platform at the specified position function createPlatform(x, y, width) { var platform = new Platform(); platform.x = x; platform.y = y; if (width) { platform.width = width; platform.getChildAt(0).width = width; } game.addChild(platform); platforms.push(platform); return platform; } // Create an obstacle function createObstacle(type, x, y) { var obstacle = new Obstacle(type); obstacle.x = x; obstacle.y = y; if (type === 'laser') { obstacle.y = Math.random() * 1500 + 500; } game.addChild(obstacle); obstacles.push(obstacle); return obstacle; } // Create a shadow area function createShadow(x, y) { var shadow = new Shadow(); shadow.x = x; shadow.y = y; game.addChild(shadow); shadows.push(shadow); return shadow; } // Create an enemy function createEnemy(x, y) { var enemy = new Enemy(); enemy.x = x; enemy.y = y; game.addChild(enemy); enemies.push(enemy); return enemy; } // Create an enemy cube function createEnemyCube(x, y) { var cube = new EnemyCube(); cube.x = x; cube.y = y; // Calculate direction vector towards player var dx = player.x - x; var dy = player.y - y; var distance = Math.sqrt(dx * dx + dy * dy); // Normalize and set speed cube.velocity.x = dx / distance * 12; cube.velocity.y = dy / distance * 12; game.addChild(cube); enemyCubes.push(cube); // Remove any spike obstacles that are at the bottom when enemy cubes are spawned for (var i = obstacles.length - 1; i >= 0; i--) { if (obstacles[i].type === 'spike' && obstacles[i].y === platformY) { obstacles[i].destroy(); obstacles.splice(i, 1); } } return cube; } // Spawn game elements function spawnElements() { if (nextSpawnX <= 2048 + 200) { // Decide what to spawn var rand = Math.random(); // Always spawn a platform var platform = createPlatform(nextSpawnX, platformY); // Maybe spawn an obstacle if (rand < 0.7) { // Only spawn spikes if there are no enemy cubes if (rand < 0.4 && enemyCubes.length === 0) { // Randomly decide between regular spike and green spike if (Math.random() < 0.5) { // Spawn regular spike createObstacle('spike', nextSpawnX, platformY); } else { // Spawn green spike createObstacle('greenSpike', nextSpawnX, platformY); } } else if (rand < 0.6) { // Spawn searchlight createObstacle('searchlight', nextSpawnX, 0); } else { // Spawn laser createObstacle('laser', 0, 0); } } // Maybe spawn a shadow if (Math.random() < 0.3) { createShadow(nextSpawnX, platformY - 40); } // Maybe spawn an enemy at the top if (Math.random() < 0.2) { var enemyX = nextSpawnX + Math.random() * 300; var enemyY = 200 + Math.random() * 300; createEnemy(enemyX, enemyY); } nextSpawnX += spawnDistance; } nextSpawnX -= speed; } // Check for collisions function checkCollisions() { if (player.isDead) { return; } // Check obstacle collisions for (var i = 0; i < obstacles.length; i++) { var obstacle = obstacles[i]; if (obstacle.type === 'laser' && !obstacle.active) { continue; // Skip inactive lasers } if (player.intersects(obstacle)) { // If in a shadow and it's a searchlight, you're safe if (obstacle.type === 'searchlight' && player.isHiding) { continue; } player.die(); break; } } // Check enemy cube collisions for (var i = enemyCubes.length - 1; i >= 0; i--) { if (player.intersects(enemyCubes[i])) { player.die(); // Remove the enemy cube that hit the player enemyCubes[i].destroy(); enemyCubes.splice(i, 1); // Update health display if (healthTxt) { healthTxt.setText('Health: ' + Math.max(0, player.health)); } break; } } // Check shadow interactions var inShadow = false; for (var j = 0; j < shadows.length; j++) { if (player.intersects(shadows[j])) { inShadow = true; break; } } if (inShadow) { player.hide(); } else { player.unhide(); } } // Update score function updateScore() { if (!gameRunning || player.isDead) { return; } score++; if (score > highScore) { highScore = score; storage.highScore = highScore; highScoreTxt.setText('High Score: ' + highScore); } if (score % 10 === 0) { scoreTxt.setText('Score: ' + score); } } // Increase difficulty over time function updateDifficulty() { difficultyTimer++; if (difficultyTimer >= difficultyInterval) { difficultyTimer = 0; // Increase speed speed += 0.5; for (var i = 0; i < platforms.length; i++) { platforms[i].speed = speed; } for (var j = 0; j < obstacles.length; j++) { obstacles[j].speed = speed; } for (var k = 0; k < shadows.length; k++) { shadows[k].speed = speed; } for (var e = 0; e < enemies.length; e++) { enemies[e].speed = speed * 0.7; // Enemies move a bit slower than obstacles } // Decrease spawn distance spawnDistance = Math.max(400, spawnDistance - 10); } } // Main update function game.update = function () { if (gameRunning) { // Update game elements player.updatePhysics(); // Spawn new elements spawnElements(); // Update existing elements for (var i = platforms.length - 1; i >= 0; i--) { if (platforms[i].update()) { platforms.splice(i, 1); } } for (var j = obstacles.length - 1; j >= 0; j--) { if (obstacles[j].update()) { obstacles.splice(j, 1); } } for (var k = shadows.length - 1; k >= 0; k--) { if (shadows[k].update()) { shadows.splice(k, 1); } } // Update enemies for (var m = enemies.length - 1; m >= 0; m--) { if (enemies[m].update()) { enemies.splice(m, 1); } } // Update enemy cubes for (var n = enemyCubes.length - 1; n >= 0; n--) { if (enemyCubes[n].update()) { enemyCubes.splice(n, 1); } } // Update death particles for (var l = deathParticles.length - 1; l >= 0; l--) { var p = deathParticles[l]; p.x += p.vx; p.y += p.vy; p.vx *= 0.95; p.vy *= 0.95; p.vy += 0.5; // gravity p.alpha -= 0.02; if (p.alpha <= 0) { p.destroy(); deathParticles.splice(l, 1); } } // Check for collisions checkCollisions(); // Update score (every 10 ticks) if (LK.ticks % 10 === 0) { updateScore(); } // Update difficulty updateDifficulty(); } }; // Event handlers game.down = function (x, y, obj) { // Track touch position and time for swipe detection lastTouchX = x; lastTouchY = y; touchStartTime = Date.now(); if (!gameRunning) { // Start the game gameRunning = true; tapToStartTxt.destroy(); scoreTxt.setText('Score: 0'); } else if (!player.isDead) { player.jump(); } }; // Sliding functionality has been removed game.up = function (x, y, obj) { if (gameRunning && !player.isDead) { var dx = x - lastTouchX; var dy = y - lastTouchY; var distance = Math.sqrt(dx * dx + dy * dy); var time = Date.now() - touchStartTime; // Add swipe property to event if this appears to be a swipe if (distance > 50 && time < 300) { // This is a swipe, create a custom property on the event object obj.event = obj.event || {}; obj.event.isSwipe = true; // If it's a right swipe (simplified check for better responsiveness) if (dx > 50) { player.slide(); } } } }; game.move = function (x, y, obj) { if (gameRunning && !player.isDead) { // We'll let the up handler manage all slide triggers // This prevents double-triggering slides } }; // Initialize the game initGame();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Enemy = Container.expand(function () {
var self = Container.call(this);
// Enemy visual
var cube = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xff0000
});
self.width = cube.width;
self.height = cube.height;
self.speed = 7;
self.shootTimer = 0;
self.shootInterval = 120; // Shoot every 120 frames (2 seconds)
self.update = function () {
self.x -= self.speed;
self.shootTimer++;
if (self.shootTimer >= self.shootInterval) {
self.shoot();
self.shootTimer = 0;
}
// Remove if off screen
if (self.x < -self.width) {
self.destroy();
return true; // Signal to remove from the array
}
return false;
};
self.shoot = function () {
if (gameRunning && !player.isDead) {
// Only create enemy cube if there are no enemy cubes currently in the game
if (enemyCubes.length === 0) {
createEnemyCube(self.x, self.y);
}
}
};
return self;
});
var EnemyCube = Container.expand(function () {
var self = Container.call(this);
// Cube visual
var cube = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6,
tint: 0xff6666
});
self.width = cube.width * 0.6;
self.height = cube.height * 0.6;
// Calculate direction towards player's position
self.velocity = {
x: 0,
y: 0
};
self.update = function () {
// Move the cube
self.x += self.velocity.x;
self.y += self.velocity.y;
// Rotate the cube for visual effect
cube.rotation += 0.05;
// Remove if off screen
if (self.y > 2732 || self.x < -self.width || self.x > 2048 + self.width) {
self.destroy();
return true;
}
return false;
};
return self;
});
var Obstacle = Container.expand(function (type) {
var self = Container.call(this);
self.type = type || 'spike';
self.speed = 10;
if (self.type === 'spike') {
var spikeGraphic = self.attachAsset('spike', {
anchorX: 0.5,
anchorY: 1.0
});
self.width = spikeGraphic.width;
self.height = spikeGraphic.height;
} else if (self.type === 'greenSpike') {
var greenSpikeGraphic = self.attachAsset('greenSpike', {
anchorX: 0.5,
anchorY: 1.0
});
self.width = greenSpikeGraphic.width;
self.height = greenSpikeGraphic.height;
} else if (self.type === 'laser') {
var laserGraphic = self.attachAsset('laser', {
anchorX: 0.0,
anchorY: 0.5,
alpha: 0.7
});
self.width = laserGraphic.width;
self.height = laserGraphic.height;
// Laser activation
self.active = false;
self.warningTime = 30;
self.activeTime = 60;
self.timer = self.warningTime;
// Warning effect
self.flash = function () {
if (self.timer % 5 === 0) {
laserGraphic.alpha = laserGraphic.alpha === 0.3 ? 0.7 : 0.3;
}
};
} else if (self.type === 'searchlight') {
var searchlightGraphic = self.attachAsset('searchlight', {
anchorX: 0.5,
anchorY: 0.0,
alpha: 0.5
});
self.width = searchlightGraphic.width;
self.height = searchlightGraphic.height;
}
self.update = function () {
self.x -= self.speed;
// Laser special behavior
if (self.type === 'laser') {
self.timer--;
if (self.timer > 0 && !self.active) {
// Warning phase
self.flash();
} else if (!self.active) {
// Activate
self.active = true;
laserGraphic.alpha = 1;
self.timer = self.activeTime;
// Play laser sound when activated
LK.getSound('laser').play();
} else if (self.timer <= 0) {
// Deactivate
self.destroy();
return true;
}
}
// Remove if off screen
if (self.x < -self.width) {
self.destroy();
return true; // Signal to remove from the array
}
return false;
};
return self;
});
var Platform = Container.expand(function () {
var self = Container.call(this);
var platformGraphic = self.attachAsset('platform', {
anchorX: 0.5,
anchorY: 0.0
});
self.width = platformGraphic.width;
self.height = platformGraphic.height;
self.speed = 10;
self.update = function () {
self.x -= self.speed;
// Remove if off screen
if (self.x < -self.width) {
self.destroy();
return true; // Signal to remove from the array
}
return false;
};
return self;
});
var Player = Container.expand(function () {
var self = Container.call(this);
// Player states
self.isJumping = false;
self.isSliding = false;
self.isHiding = false;
self.isDead = false;
self.health = 3; // Player starts with 3 health points
self.invulnerable = false; // Invulnerability after getting hit
self.invulnerableTime = 0; // Track invulnerability duration
self.canDoubleJump = false;
self.hasDoubleJumped = false;
self.canTripleJump = false;
self.lastJumpTime = 0;
self.velocity = {
x: 0,
y: 0
};
self.gravity = 1.2;
self.jumpForce = -30; // Increased from -25 to -30 for higher first jump
self.groundY = 2200;
// Visual components
var cube = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 0.5
});
// Set initial rotation and rotation speed
self.rotationSpeed = 0.05;
self.currentRotation = 0;
// Particle system for the player's trail
self.particles = [];
// Player controls
self.jump = function () {
var currentTime = LK.ticks;
if (!self.isDead && !self.isSliding) {
if (!self.isJumping) {
// First jump
self.velocity.y = self.jumpForce;
self.isJumping = true;
self.canDoubleJump = true;
self.hasDoubleJumped = false;
self.canTripleJump = false;
self.lastJumpTime = currentTime;
// Increase rotation speed temporarily when jumping
tween(self, {
rotationSpeed: 0.15
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
rotationSpeed: 0.05
}, {
duration: 500,
easing: tween.easeIn
});
}
});
LK.getSound('jump').play();
} else if (self.canDoubleJump && !self.hasDoubleJumped && currentTime - self.lastJumpTime < 30) {
// Double jump (only if tapped quickly after first jump)
self.velocity.y = self.jumpForce * 1.2; // Higher second jump
self.hasDoubleJumped = true;
self.canDoubleJump = false;
self.canTripleJump = true; // Enable triple jump after double jump
self.lastJumpTime = currentTime;
// Extra rotation boost for double jump
tween(self, {
rotationSpeed: 0.25
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
rotationSpeed: 0.05
}, {
duration: 400,
easing: tween.easeIn
});
}
});
LK.getSound('jump').play();
} else if (self.canTripleJump && self.hasDoubleJumped && currentTime - self.lastJumpTime < 30) {
// Triple jump (only if tapped quickly after second jump)
self.velocity.y = self.jumpForce * 1.3; // Even higher third jump
self.canTripleJump = false;
// Extreme rotation boost for triple jump
tween(self, {
rotationSpeed: 0.35
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
rotationSpeed: 0.05
}, {
duration: 300,
easing: tween.easeIn
});
}
});
LK.getSound('jump').play();
}
}
};
self.slide = function () {
if (!self.isDead && !self.isSliding) {
self.isSliding = true;
// Set velocity directly instead of trying to tween it
self.velocity.x = 10; // Increased from 5 to 10 for faster slide
// Temporarily increase player speed and rotation
tween(self, {
rotationSpeed: 0.3 // Increased rotation speed for more visual impact
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
// Reset to normal speed after 300ms
self.isSliding = false;
self.velocity.x = 0; // Reset velocity directly
// Store the current x position before slide ends
var originalX = self.x;
// Tween back to normal position
tween(self, {
x: originalX - 50 // Move back slightly from the slid position
}, {
duration: 150,
easing: tween.easeOut
});
tween(self, {
rotationSpeed: 0.05
}, {
duration: 200,
easing: tween.easeIn
});
}
});
}
};
self.hide = function (shadow) {
if (!self.isDead && shadow) {
self.isHiding = true;
cube.alpha = 0.3;
LK.getSound('hide').play();
}
};
self.unhide = function () {
self.isHiding = false;
cube.alpha = 1;
};
self.die = function () {
if (self.invulnerable) {
return;
} // Don't take damage if invulnerable
if (!self.isDead) {
self.health--;
if (self.health <= 0) {
// Player is dead after losing all health
self.isDead = true;
// Stop rotation by tweening to zero
tween(self, {
rotationSpeed: 0
}, {
duration: 100
});
LK.getSound('death').play();
LK.effects.flashScreen(0xff0000, 500);
// Create death particles
for (var i = 0; i < 20; i++) {
var particle = LK.getAsset('particle', {
anchorX: 0.5,
anchorY: 0.5,
x: self.x,
y: self.y
});
// Random velocity for each particle
var angle = Math.random() * Math.PI * 2;
var speed = 5 + Math.random() * 10;
particle.vx = Math.cos(angle) * speed;
particle.vy = Math.sin(angle) * speed;
game.addChild(particle);
deathParticles.push(particle);
}
LK.setTimeout(function () {
LK.showGameOver();
}, 1000);
} else {
// Player still has health, make invulnerable temporarily
self.invulnerable = true;
self.invulnerableTime = 60; // 1 second invulnerability (60 frames)
LK.effects.flashScreen(0xff0000, 200);
// Play hit sound
LK.getSound('hit').play();
// Flash the player to indicate damage
var flashCount = 0;
var flashInterval = LK.setInterval(function () {
cube.alpha = cube.alpha === 1 ? 0.3 : 1;
flashCount++;
if (flashCount >= 6) {
// Flash 3 times (6 state changes)
LK.clearInterval(flashInterval);
cube.alpha = 1;
}
}, 100);
}
}
};
// Physics update
self.updatePhysics = function () {
if (self.isDead) {
return;
}
// Update invulnerability timer
if (self.invulnerable) {
self.invulnerableTime--;
if (self.invulnerableTime <= 0) {
self.invulnerable = false;
cube.alpha = 1; // Ensure player is fully visible
}
}
// Apply gravity
self.velocity.y += self.gravity;
// Update position
self.y += self.velocity.y;
self.x += self.velocity.x; // Apply horizontal velocity for sliding
// Check floor collision
if (self.y >= self.groundY) {
self.y = self.groundY;
self.velocity.y = 0;
self.isJumping = false;
self.canDoubleJump = false;
self.hasDoubleJumped = false;
self.canTripleJump = false;
}
// Update cube rotation when moving
if (gameRunning && !self.isDead) {
self.currentRotation += self.rotationSpeed;
cube.rotation = self.currentRotation;
}
// Create trail particles
if (gameRunning && LK.ticks % 5 === 0) {
var particle = LK.getAsset('particle', {
anchorX: 0.5,
anchorY: 0.5,
x: self.x - 30,
y: self.y + (self.isSliding ? 25 : 0)
});
particle.alpha = 0.7;
particle.life = 30;
game.addChild(particle);
self.particles.push(particle);
}
// Update particles
for (var i = self.particles.length - 1; i >= 0; i--) {
var p = self.particles[i];
p.alpha -= 0.02;
p.scaleX -= 0.02;
p.scaleY -= 0.02;
p.life--;
if (p.life <= 0 || p.alpha <= 0) {
p.destroy();
self.particles.splice(i, 1);
}
}
};
return self;
});
var Shadow = Container.expand(function () {
var self = Container.call(this);
var shadowGraphic = self.attachAsset('shadow', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.5
});
self.width = shadowGraphic.width;
self.height = shadowGraphic.height;
self.speed = 10;
self.update = function () {
self.x -= self.speed;
// Remove if off screen
if (self.x < -self.width) {
self.destroy();
return true; // Signal to remove from the array
}
return false;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x111111
});
/****
* Game Code
****/
// Game state
var gameRunning = false;
var speed = 10;
var score = 0;
var highScore = storage.highScore || 0;
var platformY = 2200;
var spawnDistance = 800;
var nextSpawnX = 2048 + 200;
var difficultyTimer = 0;
var difficultyInterval = 1000;
var lastTouchX = 0;
var lastTouchY = 0;
var touchStartTime = 0;
// Game elements
var player;
var platforms = [];
var obstacles = [];
var shadows = [];
var deathParticles = [];
var enemies = [];
var enemyCubes = [];
// UI elements
var scoreTxt;
var highScoreTxt;
var healthTxt;
var tapToStartTxt;
// Initialize the game
function initGame() {
gameRunning = false;
speed = 10;
score = 0;
platformY = 2200;
spawnDistance = 800;
nextSpawnX = 2048 + 200;
difficultyTimer = 0;
// Clear existing elements
while (platforms.length > 0) {
platforms[0].destroy();
platforms.shift();
}
while (obstacles.length > 0) {
obstacles[0].destroy();
obstacles.shift();
}
while (shadows.length > 0) {
shadows[0].destroy();
shadows.shift();
}
while (deathParticles.length > 0) {
deathParticles[0].destroy();
deathParticles.shift();
}
// Clear enemies and enemy cubes
while (enemies.length > 0) {
enemies[0].destroy();
enemies.shift();
}
while (enemyCubes.length > 0) {
enemyCubes[0].destroy();
enemyCubes.shift();
}
// Add background
var background = LK.getAsset('background', {
anchorX: 0,
anchorY: 0
});
game.addChildAt(background, 0); // Add at index 0 to ensure it's at the back
// Create player
player = new Player();
player.x = 400;
player.y = platformY; // Position player on top edge of platform
game.addChild(player);
// Create initial platform
createPlatform(0, platformY, 2048 + 500);
// Create UI
if (!scoreTxt) {
scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
scoreTxt.x = -250;
scoreTxt.y = 50;
}
// Create health display
healthTxt = new Text2('Health: 3', {
size: 60,
fill: 0xFF5555
});
healthTxt.anchor.set(0, 0);
LK.gui.topLeft.addChild(healthTxt);
healthTxt.x = 120; // Keep away from top-left corner menu icon
healthTxt.y = 50;
if (!highScoreTxt) {
highScoreTxt = new Text2('High Score: ' + highScore, {
size: 40,
fill: 0xAAAAAA
});
highScoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(highScoreTxt);
highScoreTxt.x = -250;
highScoreTxt.y = 120;
}
// Create start instruction
tapToStartTxt = new Text2('Tap to Start\nTap to Jump\nSwipe Right to Slide Faster', {
size: 70,
fill: 0xFFFFFF
});
tapToStartTxt.anchor.set(0.5, 0.5);
LK.gui.center.addChild(tapToStartTxt);
// Start the background music
LK.playMusic('gameBgm', {
fade: {
start: 0,
end: 0.4,
duration: 1000
}
});
}
// Create a platform at the specified position
function createPlatform(x, y, width) {
var platform = new Platform();
platform.x = x;
platform.y = y;
if (width) {
platform.width = width;
platform.getChildAt(0).width = width;
}
game.addChild(platform);
platforms.push(platform);
return platform;
}
// Create an obstacle
function createObstacle(type, x, y) {
var obstacle = new Obstacle(type);
obstacle.x = x;
obstacle.y = y;
if (type === 'laser') {
obstacle.y = Math.random() * 1500 + 500;
}
game.addChild(obstacle);
obstacles.push(obstacle);
return obstacle;
}
// Create a shadow area
function createShadow(x, y) {
var shadow = new Shadow();
shadow.x = x;
shadow.y = y;
game.addChild(shadow);
shadows.push(shadow);
return shadow;
}
// Create an enemy
function createEnemy(x, y) {
var enemy = new Enemy();
enemy.x = x;
enemy.y = y;
game.addChild(enemy);
enemies.push(enemy);
return enemy;
}
// Create an enemy cube
function createEnemyCube(x, y) {
var cube = new EnemyCube();
cube.x = x;
cube.y = y;
// Calculate direction vector towards player
var dx = player.x - x;
var dy = player.y - y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Normalize and set speed
cube.velocity.x = dx / distance * 12;
cube.velocity.y = dy / distance * 12;
game.addChild(cube);
enemyCubes.push(cube);
// Remove any spike obstacles that are at the bottom when enemy cubes are spawned
for (var i = obstacles.length - 1; i >= 0; i--) {
if (obstacles[i].type === 'spike' && obstacles[i].y === platformY) {
obstacles[i].destroy();
obstacles.splice(i, 1);
}
}
return cube;
}
// Spawn game elements
function spawnElements() {
if (nextSpawnX <= 2048 + 200) {
// Decide what to spawn
var rand = Math.random();
// Always spawn a platform
var platform = createPlatform(nextSpawnX, platformY);
// Maybe spawn an obstacle
if (rand < 0.7) {
// Only spawn spikes if there are no enemy cubes
if (rand < 0.4 && enemyCubes.length === 0) {
// Randomly decide between regular spike and green spike
if (Math.random() < 0.5) {
// Spawn regular spike
createObstacle('spike', nextSpawnX, platformY);
} else {
// Spawn green spike
createObstacle('greenSpike', nextSpawnX, platformY);
}
} else if (rand < 0.6) {
// Spawn searchlight
createObstacle('searchlight', nextSpawnX, 0);
} else {
// Spawn laser
createObstacle('laser', 0, 0);
}
}
// Maybe spawn a shadow
if (Math.random() < 0.3) {
createShadow(nextSpawnX, platformY - 40);
}
// Maybe spawn an enemy at the top
if (Math.random() < 0.2) {
var enemyX = nextSpawnX + Math.random() * 300;
var enemyY = 200 + Math.random() * 300;
createEnemy(enemyX, enemyY);
}
nextSpawnX += spawnDistance;
}
nextSpawnX -= speed;
}
// Check for collisions
function checkCollisions() {
if (player.isDead) {
return;
}
// Check obstacle collisions
for (var i = 0; i < obstacles.length; i++) {
var obstacle = obstacles[i];
if (obstacle.type === 'laser' && !obstacle.active) {
continue; // Skip inactive lasers
}
if (player.intersects(obstacle)) {
// If in a shadow and it's a searchlight, you're safe
if (obstacle.type === 'searchlight' && player.isHiding) {
continue;
}
player.die();
break;
}
}
// Check enemy cube collisions
for (var i = enemyCubes.length - 1; i >= 0; i--) {
if (player.intersects(enemyCubes[i])) {
player.die();
// Remove the enemy cube that hit the player
enemyCubes[i].destroy();
enemyCubes.splice(i, 1);
// Update health display
if (healthTxt) {
healthTxt.setText('Health: ' + Math.max(0, player.health));
}
break;
}
}
// Check shadow interactions
var inShadow = false;
for (var j = 0; j < shadows.length; j++) {
if (player.intersects(shadows[j])) {
inShadow = true;
break;
}
}
if (inShadow) {
player.hide();
} else {
player.unhide();
}
}
// Update score
function updateScore() {
if (!gameRunning || player.isDead) {
return;
}
score++;
if (score > highScore) {
highScore = score;
storage.highScore = highScore;
highScoreTxt.setText('High Score: ' + highScore);
}
if (score % 10 === 0) {
scoreTxt.setText('Score: ' + score);
}
}
// Increase difficulty over time
function updateDifficulty() {
difficultyTimer++;
if (difficultyTimer >= difficultyInterval) {
difficultyTimer = 0;
// Increase speed
speed += 0.5;
for (var i = 0; i < platforms.length; i++) {
platforms[i].speed = speed;
}
for (var j = 0; j < obstacles.length; j++) {
obstacles[j].speed = speed;
}
for (var k = 0; k < shadows.length; k++) {
shadows[k].speed = speed;
}
for (var e = 0; e < enemies.length; e++) {
enemies[e].speed = speed * 0.7; // Enemies move a bit slower than obstacles
}
// Decrease spawn distance
spawnDistance = Math.max(400, spawnDistance - 10);
}
}
// Main update function
game.update = function () {
if (gameRunning) {
// Update game elements
player.updatePhysics();
// Spawn new elements
spawnElements();
// Update existing elements
for (var i = platforms.length - 1; i >= 0; i--) {
if (platforms[i].update()) {
platforms.splice(i, 1);
}
}
for (var j = obstacles.length - 1; j >= 0; j--) {
if (obstacles[j].update()) {
obstacles.splice(j, 1);
}
}
for (var k = shadows.length - 1; k >= 0; k--) {
if (shadows[k].update()) {
shadows.splice(k, 1);
}
}
// Update enemies
for (var m = enemies.length - 1; m >= 0; m--) {
if (enemies[m].update()) {
enemies.splice(m, 1);
}
}
// Update enemy cubes
for (var n = enemyCubes.length - 1; n >= 0; n--) {
if (enemyCubes[n].update()) {
enemyCubes.splice(n, 1);
}
}
// Update death particles
for (var l = deathParticles.length - 1; l >= 0; l--) {
var p = deathParticles[l];
p.x += p.vx;
p.y += p.vy;
p.vx *= 0.95;
p.vy *= 0.95;
p.vy += 0.5; // gravity
p.alpha -= 0.02;
if (p.alpha <= 0) {
p.destroy();
deathParticles.splice(l, 1);
}
}
// Check for collisions
checkCollisions();
// Update score (every 10 ticks)
if (LK.ticks % 10 === 0) {
updateScore();
}
// Update difficulty
updateDifficulty();
}
};
// Event handlers
game.down = function (x, y, obj) {
// Track touch position and time for swipe detection
lastTouchX = x;
lastTouchY = y;
touchStartTime = Date.now();
if (!gameRunning) {
// Start the game
gameRunning = true;
tapToStartTxt.destroy();
scoreTxt.setText('Score: 0');
} else if (!player.isDead) {
player.jump();
}
};
// Sliding functionality has been removed
game.up = function (x, y, obj) {
if (gameRunning && !player.isDead) {
var dx = x - lastTouchX;
var dy = y - lastTouchY;
var distance = Math.sqrt(dx * dx + dy * dy);
var time = Date.now() - touchStartTime;
// Add swipe property to event if this appears to be a swipe
if (distance > 50 && time < 300) {
// This is a swipe, create a custom property on the event object
obj.event = obj.event || {};
obj.event.isSwipe = true;
// If it's a right swipe (simplified check for better responsiveness)
if (dx > 50) {
player.slide();
}
}
}
};
game.move = function (x, y, obj) {
if (gameRunning && !player.isDead) {
// We'll let the up handler manage all slide triggers
// This prevents double-triggering slides
}
};
// Initialize the game
initGame();
square re cube with 2 eyes and spike teeths inside In-Game asset. 2d. High contrast. No shadows
square white cube with 2 eyes and spike smily teeths inside In-Game asset. 2d. High contrast. No shadows
square yellowgreen cube with 2 eyes and smily face inside In-Game asset. 2d. High contrast. No shadows
background image for sqube darkness game. In-Game asset. 2d. High contrast. No shadows