User prompt
la carretera de fondo sera infinita
User prompt
un menu de inicio con un boton en medio para empezar a jugar con un carro acelerando de fondo ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
el sonido de encendido sonara en el momento en el que se empiece a jugar.
User prompt
un maximo de 7 carros en la pantalla
User prompt
que haya mayor posibilidad de que aparezcan potenciadores
User prompt
poco a poco vayan apareciendo mayor cantidad de vehiculoshaya mayor posibilidad de que aparezca
User prompt
menor cantidad de obstaculos el potenciador esta quieto y al momento de tocar el potenciador tengo una mayor velocidad
User prompt
al tocar el objeto inmediatamente tendre una invencibilidad de 10 segundos
User prompt
el objeto especial es de color amarillo
User prompt
mayor cantidad de obstaculos probabilidad de aparecer un objeto especial que te hara inmortal por 5 segundos ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
menor cantidad de obstaculos tengo 2 vidas y me siguen muchos enemigos
Code edit (1 edits merged)
Please save this source code
User prompt
Speed Runner
Initial prompt
un juego de carreras en el que esquivo obstaculos
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Barrier = Container.expand(function () { var self = Container.call(this); var barrierGraphics = self.attachAsset('barrier', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.blocking = true; self.update = function () { self.y += self.speed + gameSpeed; // Add sliding animation barrierGraphics.x = Math.sin(LK.ticks * 0.05) * 20; }; return self; }); var CharacterButton = Container.expand(function (vehicleType, vehicleAsset) { var self = Container.call(this); self.vehicleType = vehicleType; var buttonBg = self.attachAsset('startButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6 }); var vehiclePreview = self.attachAsset(vehicleAsset, { anchorX: 0.5, anchorY: 0.5, scaleX: 0.4, scaleY: 0.4 }); self.down = function (x, y, obj) { buttonBg.alpha = 0.7; selectedVehicle = self.vehicleType; // Update all character buttons to show selection updateCharacterButtons(); }; self.up = function (x, y, obj) { buttonBg.alpha = 1.0; }; self.setSelected = function (isSelected) { if (isSelected) { buttonBg.tint = 0x00ff00; vehiclePreview.tint = 0x00ff00; } else { buttonBg.tint = 0xffffff; vehiclePreview.tint = 0xffffff; } }; return self; }); var Obstacle = Container.expand(function () { var self = Container.call(this); var obstacleGraphics = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.update = function () { self.y += self.speed + gameSpeed; // Ensure cone doesn't rotate obstacleGraphics.rotation = 0; }; return self; }); var OilSpill = Container.expand(function () { var self = Container.call(this); var oilGraphics = self.attachAsset('oilspill', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.slippery = true; self.update = function () { self.y += self.speed + gameSpeed; }; return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.update = function () { // Power-up stays stationary, only rotate for visual effect powerupGraphics.rotation += 0.1; }; return self; }); var Spike = Container.expand(function () { var self = Container.call(this); var spikeGraphics = self.attachAsset('spike', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.deadly = true; self.update = function () { self.y += self.speed + gameSpeed; // Add pulsing effect spikeGraphics.scaleY = 1 + Math.sin(LK.ticks * 0.1) * 0.1; }; return self; }); var StartButton = Container.expand(function () { var self = Container.call(this); var buttonGraphics = self.attachAsset('startButton', { anchorX: 0.5, anchorY: 0.5 }); // Text removed from button self.down = function (x, y, obj) { buttonGraphics.alpha = 0.7; if (!gameStarted && characterSelectionVisible) { startGame(); } }; self.up = function (x, y, obj) { buttonGraphics.alpha = 1.0; }; return self; }); var TrapHole = Container.expand(function () { var self = Container.call(this); var trapGraphics = self.attachAsset('trap', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 8; self.stunEffect = true; self.update = function () { self.y += self.speed + gameSpeed; }; return self; }); var Vehicle = Container.expand(function () { var self = Container.call(this); var vehicleGraphics = self.attachAsset(selectedVehicle, { anchorX: 0.5, anchorY: 0.5 }); self.speed = 0; self.targetX = 0; self.update = function () { // Check if vehicle is stunned (cannot move) if (vehicleStunned) { // Vehicle cannot move at all when stunned return; } // Smooth movement toward target position var dx = self.targetX - self.x; var moveSpeed = originalVehicleSpeed; // Apply slowdown effect if active if (vehicleSlowed) { moveSpeed = originalVehicleSpeed * 0.3; // 70% slower } if (Math.abs(dx) > 2) { self.x += dx * moveSpeed; } else { self.x = self.targetX; } // Keep vehicle within bounds horizontally var halfWidth = vehicleGraphics.width / 2; if (self.x - halfWidth < 200) { self.x = 200 + halfWidth; self.targetX = self.x; } if (self.x + halfWidth > 1848) { self.x = 1848 - halfWidth; self.targetX = self.x; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2c3e50 }); /**** * Game Code ****/ // Add background var background = game.addChild(LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5 })); background.x = 1024; background.y = 1208; // Add white car background made with pixels var whiteCar = game.addChild(LK.getAsset('whitecar', { anchorX: 0.5, anchorY: 0.5 })); whiteCar.x = 1024; whiteCar.y = 1366; whiteCar.tint = 0xffffff; whiteCar.scaleX = 2; whiteCar.scaleY = 2; var gameSpeed = 5; var maxSpeed = 20; var speedIncrement = 0.01; var distanceTraveled = 0; var obstacles = []; var powerups = []; var vehicle = null; var dragNode = null; var gameRunning = true; var gameStarted = false; var lives = 3; var maxLives = 3; var heartIcons = []; var speedBoostActive = false; var speedBoostEndTime = 0; var originalSpeed = 5; var vehicleStunned = false; var vehicleStunnedEndTime = 0; var vehicleSlowed = false; var vehicleSlowedEndTime = 0; var originalVehicleSpeed = 0.15; var vehicleInvincible = false; var vehicleInvincibleEndTime = 0; var startButton = null; var selectedVehicle = 'vehicle'; var characterButtons = []; var characterSelectionVisible = false; // Create score display var scoreTxt = new Text2('0', { size: 100, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); scoreTxt.visible = false; LK.gui.top.addChild(scoreTxt); // Create speed display var speedTxt = new Text2('Speed: 5', { size: 60, fill: 0xFFFFFF }); speedTxt.anchor.set(0, 0); speedTxt.x = 50; speedTxt.y = 50; speedTxt.visible = false; LK.gui.topLeft.addChild(speedTxt); // Create heart icons for lives display for (var h = 0; h < maxLives; h++) { var heart = LK.getAsset('heart', { anchorX: 0.5, anchorY: 0.5 }); heart.x = 1950 - h * 80; // Position hearts from right to left heart.y = 80; heart.visible = false; heartIcons.push(heart); LK.gui.bottomRight.addChild(heart); } // Create character selection button startButton = game.addChild(new StartButton()); startButton.x = 1024; startButton.y = 1600; // Create speedrunner logo for character selection var speedrunnerLogo = game.addChild(LK.getAsset('speedrunner', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 })); speedrunnerLogo.x = 1024; speedrunnerLogo.y = 600; speedrunnerLogo.visible = false; // Create character selection buttons (initially hidden) var vehicleTypes = ['vehicle', 'vehicle2', 'vehicle3', 'vehicle4', 'truck', 'motorbike', 'policecar']; var vehicleAssets = ['vehicle', 'vehicle2', 'vehicle3', 'vehicle4', 'truck', 'motorbike', 'policecar']; for (var c = 0; c < vehicleTypes.length; c++) { var charButton = game.addChild(new CharacterButton(vehicleTypes[c], vehicleAssets[c])); charButton.x = 200 + c * 280; charButton.y = 1200; charButton.visible = false; characterButtons.push(charButton); } // Set default selection characterButtons[0].setSelected(true); // Create vehicle (initially hidden) - positioned higher vehicle = game.addChild(new Vehicle()); vehicle.x = 1024; vehicle.y = 2000; vehicle.targetX = vehicle.x; vehicle.visible = false; // Show character selection function showCharacterSelection() { characterSelectionVisible = true; // Show speedrunner logo speedrunnerLogo.visible = true; // Show character buttons for (var c = 0; c < characterButtons.length; c++) { characterButtons[c].visible = true; } } // Show character selection immediately on game start showCharacterSelection(); // Update character button selection states function updateCharacterButtons() { for (var c = 0; c < characterButtons.length; c++) { characterButtons[c].setSelected(characterButtons[c].vehicleType === selectedVehicle); } } // Start game function function startGame() { gameStarted = true; gameRunning = true; // Hide start menu startButton.visible = false; whiteCar.visible = false; // Hide speedrunner logo speedrunnerLogo.visible = false; // Hide character selection for (var c = 0; c < characterButtons.length; c++) { characterButtons[c].visible = false; } characterSelectionVisible = false; // Recreate vehicle with selected character vehicle.destroy(); vehicle = game.addChild(new Vehicle()); vehicle.x = 1024; vehicle.y = 2000; vehicle.targetX = vehicle.x; vehicle.visible = true; // Show UI elements scoreTxt.visible = true; speedTxt.visible = true; // Show heart icons for (var h = 0; h < heartIcons.length; h++) { heartIcons[h].visible = true; } // Play startup sound when game starts LK.getSound('startup').play(); // Start playing music on loop LK.playMusic('musica'); } // Spawn obstacles function spawnObstacle() { if (!gameRunning) return; var obstacle; var obstacleType = Math.random(); if (obstacleType < 0.3) { obstacle = new Obstacle(); } else if (obstacleType < 0.5) { obstacle = new OilSpill(); } else if (obstacleType < 0.7) { obstacle = new Spike(); } else if (obstacleType < 0.9) { obstacle = new TrapHole(); } else { obstacle = new Barrier(); } // Random position within track bounds obstacle.x = 300 + Math.random() * 1448; obstacle.y = -100; obstacles.push(obstacle); game.addChild(obstacle); } // Update and clean up power-ups for (var i = powerups.length - 1; i >= 0; i--) { var powerup = powerups[i]; // Check if power-up went off screen if (powerup.y > 2800) { powerup.destroy(); powerups.splice(i, 1); continue; } // Check collision with vehicle if (powerup.intersects(vehicle)) { // Activate speed boost speedBoostActive = true; speedBoostEndTime = LK.ticks + 600; // 10 seconds at 60 FPS originalSpeed = gameSpeed; gameSpeed = Math.min(gameSpeed + 10, maxSpeed); // Increase speed by 10 LK.getSound('powerup').play(); // Flash screen gold LK.effects.flashScreen(0xffd700, 500); // Animate vehicle with golden tint and pulsing effect tween(vehicle, { tint: 0xffd700 }, { duration: 200 }); // Remove the power-up powerup.destroy(); powerups.splice(i, 1); continue; } } // Update and clean up track lines function spawnPowerUp() { if (!gameRunning) return; var powerup = new PowerUp(); // Random position within track bounds powerup.x = 300 + Math.random() * 1448; powerup.y = -100; powerups.push(powerup); game.addChild(powerup); } // Handle touch input function handleMove(x, y, obj) { if (!gameRunning) return; if (dragNode) { // Convert touch position to vehicle target position vehicle.targetX = x; } } game.move = handleMove; game.down = function (x, y, obj) { if (!gameRunning) return; dragNode = vehicle; handleMove(x, y, obj); }; game.up = function (x, y, obj) { dragNode = null; }; // Main game loop game.update = function () { if (!gameStarted || !gameRunning) return; // Increase speed over time if (gameSpeed < maxSpeed) { gameSpeed += speedIncrement; } // Update distance traveled distanceTraveled += gameSpeed; // Update score based on distance var score = Math.floor(distanceTraveled / 10); LK.setScore(score); scoreTxt.setText(score); speedTxt.setText('Speed: ' + Math.floor(gameSpeed)); // Check win condition at 7,500 points if (score >= 7500) { gameRunning = false; LK.setTimeout(function () { LK.showYouWin(); }, 500); return; } // Check if speed boost expired if (speedBoostActive && LK.ticks > speedBoostEndTime) { speedBoostActive = false; // Restore normal speed (but keep natural progression) gameSpeed = Math.max(originalSpeed, 5 + distanceTraveled / 10000 * speedIncrement); // Stop tween and restore normal vehicle color tween.stop(vehicle); vehicle.tint = 0xffffff; } // Check if vehicle stun expired if (vehicleStunned && LK.ticks > vehicleStunnedEndTime) { vehicleStunned = false; // Stop tween and restore normal vehicle color tween.stop(vehicle); vehicle.tint = 0xffffff; // Reset rotation to normal vehicle.rotation = 0; } // Check if vehicle slowdown expired if (vehicleSlowed && LK.ticks > vehicleSlowedEndTime) { vehicleSlowed = false; // Stop tween and restore normal vehicle color if not stunned if (!vehicleStunned) { tween.stop(vehicle); vehicle.tint = 0xffffff; } } // Check if vehicle invincibility expired if (vehicleInvincible && LK.ticks > vehicleInvincibleEndTime) { vehicleInvincible = false; // Stop flashing effect tween.stop(vehicle, { alpha: true }); vehicle.alpha = 1.0; } // Progressive obstacle spawning - gradually increase frequency and probability var baseSpawnRate = Math.max(70 - Math.floor(gameSpeed * 2), 30); // Faster spawn rate var progressMultiplier = Math.min(1 + distanceTraveled / 5000, 3); // Up to 3x more likely over time var spawnProbability = Math.min(0.3 + distanceTraveled / 8000, 0.8); // Start at 30%, increase to 80% if (LK.ticks % baseSpawnRate === 0) { // Multiple obstacle spawning based on progress var numObstacles = Math.floor(progressMultiplier); for (var spawns = 0; spawns < numObstacles; spawns++) { // Check if we already have maximum number of obstacles on screen if (obstacles.length >= 5) { break; // Stop spawning if we have 5 or more obstacles } if (Math.random() < spawnProbability) { spawnObstacle(); } } } // Spawn power-ups occasionally (15% chance when spawning obstacles) if (LK.ticks % Math.max(60 - Math.floor(gameSpeed), 30) === 0 && Math.random() < 0.15) { spawnPowerUp(); } // Update and clean up obstacles for (var i = obstacles.length - 1; i >= 0; i--) { var obstacle = obstacles[i]; // Check if obstacle went off screen if (obstacle.y > 2800) { obstacle.destroy(); obstacles.splice(i, 1); continue; } // Check collision with vehicle if (obstacle.intersects(vehicle) && !vehicleInvincible) { if (obstacle.slippery) { // Oil spill effect - vehicle slides randomly and slows down for 1 second vehicle.targetX += (Math.random() - 0.5) * 400; vehicleSlowed = true; vehicleSlowedEndTime = LK.ticks + 60; // 1 second at 60 FPS LK.effects.flashScreen(0x8B4513, 300); // Tint vehicle brown to show oil effect tween(vehicle, { tint: 0x8B4513 }, { duration: 200 }); // Slight damage but no life lost } else if (obstacle.deadly) { // Spike - instant death lives = 0; LK.effects.flashScreen(0xff0000, 1000); LK.getSound('crash').play(); } else if (obstacle.stunEffect) { // Trap hole - stun vehicle for 2 seconds (cannot move) vehicleStunned = true; vehicleStunnedEndTime = LK.ticks + 120; // 2 seconds at 60 FPS // Add rotation animation while stunned tween(vehicle, { rotation: vehicle.rotation + Math.PI * 4 // 2 full rotations }, { duration: 2000, // 2 seconds easing: tween.easeOut }); // No life lost, just stunning effect } else if (obstacle.blocking) { // Barrier - damages vehicle and pushes it back lives--; LK.getSound('crash').play(); // Push vehicle back slightly vehicle.targetX = vehicle.x + (Math.random() - 0.5) * 200; } else { // Regular obstacle lives--; LK.effects.flashScreen(0xff0000, 500); LK.getSound('crash').play(); } // Hide a heart icon for regular, deadly, and blocking obstacles if (!obstacle.slippery && !obstacle.stunEffect && lives >= 0 && lives < heartIcons.length) { heartIcons[heartIcons.length - 1 - lives].visible = false; } // Activate invincibility for 1 second after any collision vehicleInvincible = true; vehicleInvincibleEndTime = LK.ticks + 60; // 1 second at 60 FPS // Add flashing effect during invincibility tween(vehicle, { alpha: 0.3 }, { duration: 100, easing: tween.linear, onFinish: function onFinish() { if (vehicleInvincible) { tween(vehicle, { alpha: 1.0 }, { duration: 100, easing: tween.linear, onFinish: function onFinish() { if (vehicleInvincible) { // Continue flashing by calling this recursively tween(vehicle, { alpha: 0.3 }, { duration: 100, easing: tween.linear, onFinish: function onFinish() { if (vehicleInvincible) { tween(vehicle, { alpha: 1.0 }, { duration: 100 }); } } }); } } }); } } }); // Remove the obstacle that was hit obstacle.destroy(); obstacles.splice(i, 1); // Check if game over if (lives <= 0) { gameRunning = false; LK.setTimeout(function () { LK.showGameOver(); }, 500); return; } continue; } } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Barrier = Container.expand(function () {
var self = Container.call(this);
var barrierGraphics = self.attachAsset('barrier', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.blocking = true;
self.update = function () {
self.y += self.speed + gameSpeed;
// Add sliding animation
barrierGraphics.x = Math.sin(LK.ticks * 0.05) * 20;
};
return self;
});
var CharacterButton = Container.expand(function (vehicleType, vehicleAsset) {
var self = Container.call(this);
self.vehicleType = vehicleType;
var buttonBg = self.attachAsset('startButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.6,
scaleY: 0.6
});
var vehiclePreview = self.attachAsset(vehicleAsset, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.4,
scaleY: 0.4
});
self.down = function (x, y, obj) {
buttonBg.alpha = 0.7;
selectedVehicle = self.vehicleType;
// Update all character buttons to show selection
updateCharacterButtons();
};
self.up = function (x, y, obj) {
buttonBg.alpha = 1.0;
};
self.setSelected = function (isSelected) {
if (isSelected) {
buttonBg.tint = 0x00ff00;
vehiclePreview.tint = 0x00ff00;
} else {
buttonBg.tint = 0xffffff;
vehiclePreview.tint = 0xffffff;
}
};
return self;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.update = function () {
self.y += self.speed + gameSpeed;
// Ensure cone doesn't rotate
obstacleGraphics.rotation = 0;
};
return self;
});
var OilSpill = Container.expand(function () {
var self = Container.call(this);
var oilGraphics = self.attachAsset('oilspill', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.slippery = true;
self.update = function () {
self.y += self.speed + gameSpeed;
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerupGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.update = function () {
// Power-up stays stationary, only rotate for visual effect
powerupGraphics.rotation += 0.1;
};
return self;
});
var Spike = Container.expand(function () {
var self = Container.call(this);
var spikeGraphics = self.attachAsset('spike', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.deadly = true;
self.update = function () {
self.y += self.speed + gameSpeed;
// Add pulsing effect
spikeGraphics.scaleY = 1 + Math.sin(LK.ticks * 0.1) * 0.1;
};
return self;
});
var StartButton = Container.expand(function () {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('startButton', {
anchorX: 0.5,
anchorY: 0.5
});
// Text removed from button
self.down = function (x, y, obj) {
buttonGraphics.alpha = 0.7;
if (!gameStarted && characterSelectionVisible) {
startGame();
}
};
self.up = function (x, y, obj) {
buttonGraphics.alpha = 1.0;
};
return self;
});
var TrapHole = Container.expand(function () {
var self = Container.call(this);
var trapGraphics = self.attachAsset('trap', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.stunEffect = true;
self.update = function () {
self.y += self.speed + gameSpeed;
};
return self;
});
var Vehicle = Container.expand(function () {
var self = Container.call(this);
var vehicleGraphics = self.attachAsset(selectedVehicle, {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 0;
self.targetX = 0;
self.update = function () {
// Check if vehicle is stunned (cannot move)
if (vehicleStunned) {
// Vehicle cannot move at all when stunned
return;
}
// Smooth movement toward target position
var dx = self.targetX - self.x;
var moveSpeed = originalVehicleSpeed;
// Apply slowdown effect if active
if (vehicleSlowed) {
moveSpeed = originalVehicleSpeed * 0.3; // 70% slower
}
if (Math.abs(dx) > 2) {
self.x += dx * moveSpeed;
} else {
self.x = self.targetX;
}
// Keep vehicle within bounds horizontally
var halfWidth = vehicleGraphics.width / 2;
if (self.x - halfWidth < 200) {
self.x = 200 + halfWidth;
self.targetX = self.x;
}
if (self.x + halfWidth > 1848) {
self.x = 1848 - halfWidth;
self.targetX = self.x;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x2c3e50
});
/****
* Game Code
****/
// Add background
var background = game.addChild(LK.getAsset('background', {
anchorX: 0.5,
anchorY: 0.5
}));
background.x = 1024;
background.y = 1208;
// Add white car background made with pixels
var whiteCar = game.addChild(LK.getAsset('whitecar', {
anchorX: 0.5,
anchorY: 0.5
}));
whiteCar.x = 1024;
whiteCar.y = 1366;
whiteCar.tint = 0xffffff;
whiteCar.scaleX = 2;
whiteCar.scaleY = 2;
var gameSpeed = 5;
var maxSpeed = 20;
var speedIncrement = 0.01;
var distanceTraveled = 0;
var obstacles = [];
var powerups = [];
var vehicle = null;
var dragNode = null;
var gameRunning = true;
var gameStarted = false;
var lives = 3;
var maxLives = 3;
var heartIcons = [];
var speedBoostActive = false;
var speedBoostEndTime = 0;
var originalSpeed = 5;
var vehicleStunned = false;
var vehicleStunnedEndTime = 0;
var vehicleSlowed = false;
var vehicleSlowedEndTime = 0;
var originalVehicleSpeed = 0.15;
var vehicleInvincible = false;
var vehicleInvincibleEndTime = 0;
var startButton = null;
var selectedVehicle = 'vehicle';
var characterButtons = [];
var characterSelectionVisible = false;
// Create score display
var scoreTxt = new Text2('0', {
size: 100,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
scoreTxt.visible = false;
LK.gui.top.addChild(scoreTxt);
// Create speed display
var speedTxt = new Text2('Speed: 5', {
size: 60,
fill: 0xFFFFFF
});
speedTxt.anchor.set(0, 0);
speedTxt.x = 50;
speedTxt.y = 50;
speedTxt.visible = false;
LK.gui.topLeft.addChild(speedTxt);
// Create heart icons for lives display
for (var h = 0; h < maxLives; h++) {
var heart = LK.getAsset('heart', {
anchorX: 0.5,
anchorY: 0.5
});
heart.x = 1950 - h * 80; // Position hearts from right to left
heart.y = 80;
heart.visible = false;
heartIcons.push(heart);
LK.gui.bottomRight.addChild(heart);
}
// Create character selection button
startButton = game.addChild(new StartButton());
startButton.x = 1024;
startButton.y = 1600;
// Create speedrunner logo for character selection
var speedrunnerLogo = game.addChild(LK.getAsset('speedrunner', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 3
}));
speedrunnerLogo.x = 1024;
speedrunnerLogo.y = 600;
speedrunnerLogo.visible = false;
// Create character selection buttons (initially hidden)
var vehicleTypes = ['vehicle', 'vehicle2', 'vehicle3', 'vehicle4', 'truck', 'motorbike', 'policecar'];
var vehicleAssets = ['vehicle', 'vehicle2', 'vehicle3', 'vehicle4', 'truck', 'motorbike', 'policecar'];
for (var c = 0; c < vehicleTypes.length; c++) {
var charButton = game.addChild(new CharacterButton(vehicleTypes[c], vehicleAssets[c]));
charButton.x = 200 + c * 280;
charButton.y = 1200;
charButton.visible = false;
characterButtons.push(charButton);
}
// Set default selection
characterButtons[0].setSelected(true);
// Create vehicle (initially hidden) - positioned higher
vehicle = game.addChild(new Vehicle());
vehicle.x = 1024;
vehicle.y = 2000;
vehicle.targetX = vehicle.x;
vehicle.visible = false;
// Show character selection
function showCharacterSelection() {
characterSelectionVisible = true;
// Show speedrunner logo
speedrunnerLogo.visible = true;
// Show character buttons
for (var c = 0; c < characterButtons.length; c++) {
characterButtons[c].visible = true;
}
}
// Show character selection immediately on game start
showCharacterSelection();
// Update character button selection states
function updateCharacterButtons() {
for (var c = 0; c < characterButtons.length; c++) {
characterButtons[c].setSelected(characterButtons[c].vehicleType === selectedVehicle);
}
}
// Start game function
function startGame() {
gameStarted = true;
gameRunning = true;
// Hide start menu
startButton.visible = false;
whiteCar.visible = false;
// Hide speedrunner logo
speedrunnerLogo.visible = false;
// Hide character selection
for (var c = 0; c < characterButtons.length; c++) {
characterButtons[c].visible = false;
}
characterSelectionVisible = false;
// Recreate vehicle with selected character
vehicle.destroy();
vehicle = game.addChild(new Vehicle());
vehicle.x = 1024;
vehicle.y = 2000;
vehicle.targetX = vehicle.x;
vehicle.visible = true;
// Show UI elements
scoreTxt.visible = true;
speedTxt.visible = true;
// Show heart icons
for (var h = 0; h < heartIcons.length; h++) {
heartIcons[h].visible = true;
}
// Play startup sound when game starts
LK.getSound('startup').play();
// Start playing music on loop
LK.playMusic('musica');
}
// Spawn obstacles
function spawnObstacle() {
if (!gameRunning) return;
var obstacle;
var obstacleType = Math.random();
if (obstacleType < 0.3) {
obstacle = new Obstacle();
} else if (obstacleType < 0.5) {
obstacle = new OilSpill();
} else if (obstacleType < 0.7) {
obstacle = new Spike();
} else if (obstacleType < 0.9) {
obstacle = new TrapHole();
} else {
obstacle = new Barrier();
}
// Random position within track bounds
obstacle.x = 300 + Math.random() * 1448;
obstacle.y = -100;
obstacles.push(obstacle);
game.addChild(obstacle);
}
// Update and clean up power-ups
for (var i = powerups.length - 1; i >= 0; i--) {
var powerup = powerups[i];
// Check if power-up went off screen
if (powerup.y > 2800) {
powerup.destroy();
powerups.splice(i, 1);
continue;
}
// Check collision with vehicle
if (powerup.intersects(vehicle)) {
// Activate speed boost
speedBoostActive = true;
speedBoostEndTime = LK.ticks + 600; // 10 seconds at 60 FPS
originalSpeed = gameSpeed;
gameSpeed = Math.min(gameSpeed + 10, maxSpeed); // Increase speed by 10
LK.getSound('powerup').play();
// Flash screen gold
LK.effects.flashScreen(0xffd700, 500);
// Animate vehicle with golden tint and pulsing effect
tween(vehicle, {
tint: 0xffd700
}, {
duration: 200
});
// Remove the power-up
powerup.destroy();
powerups.splice(i, 1);
continue;
}
}
// Update and clean up track lines
function spawnPowerUp() {
if (!gameRunning) return;
var powerup = new PowerUp();
// Random position within track bounds
powerup.x = 300 + Math.random() * 1448;
powerup.y = -100;
powerups.push(powerup);
game.addChild(powerup);
}
// Handle touch input
function handleMove(x, y, obj) {
if (!gameRunning) return;
if (dragNode) {
// Convert touch position to vehicle target position
vehicle.targetX = x;
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
if (!gameRunning) return;
dragNode = vehicle;
handleMove(x, y, obj);
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Main game loop
game.update = function () {
if (!gameStarted || !gameRunning) return;
// Increase speed over time
if (gameSpeed < maxSpeed) {
gameSpeed += speedIncrement;
}
// Update distance traveled
distanceTraveled += gameSpeed;
// Update score based on distance
var score = Math.floor(distanceTraveled / 10);
LK.setScore(score);
scoreTxt.setText(score);
speedTxt.setText('Speed: ' + Math.floor(gameSpeed));
// Check win condition at 7,500 points
if (score >= 7500) {
gameRunning = false;
LK.setTimeout(function () {
LK.showYouWin();
}, 500);
return;
}
// Check if speed boost expired
if (speedBoostActive && LK.ticks > speedBoostEndTime) {
speedBoostActive = false;
// Restore normal speed (but keep natural progression)
gameSpeed = Math.max(originalSpeed, 5 + distanceTraveled / 10000 * speedIncrement);
// Stop tween and restore normal vehicle color
tween.stop(vehicle);
vehicle.tint = 0xffffff;
}
// Check if vehicle stun expired
if (vehicleStunned && LK.ticks > vehicleStunnedEndTime) {
vehicleStunned = false;
// Stop tween and restore normal vehicle color
tween.stop(vehicle);
vehicle.tint = 0xffffff;
// Reset rotation to normal
vehicle.rotation = 0;
}
// Check if vehicle slowdown expired
if (vehicleSlowed && LK.ticks > vehicleSlowedEndTime) {
vehicleSlowed = false;
// Stop tween and restore normal vehicle color if not stunned
if (!vehicleStunned) {
tween.stop(vehicle);
vehicle.tint = 0xffffff;
}
}
// Check if vehicle invincibility expired
if (vehicleInvincible && LK.ticks > vehicleInvincibleEndTime) {
vehicleInvincible = false;
// Stop flashing effect
tween.stop(vehicle, {
alpha: true
});
vehicle.alpha = 1.0;
}
// Progressive obstacle spawning - gradually increase frequency and probability
var baseSpawnRate = Math.max(70 - Math.floor(gameSpeed * 2), 30); // Faster spawn rate
var progressMultiplier = Math.min(1 + distanceTraveled / 5000, 3); // Up to 3x more likely over time
var spawnProbability = Math.min(0.3 + distanceTraveled / 8000, 0.8); // Start at 30%, increase to 80%
if (LK.ticks % baseSpawnRate === 0) {
// Multiple obstacle spawning based on progress
var numObstacles = Math.floor(progressMultiplier);
for (var spawns = 0; spawns < numObstacles; spawns++) {
// Check if we already have maximum number of obstacles on screen
if (obstacles.length >= 5) {
break; // Stop spawning if we have 5 or more obstacles
}
if (Math.random() < spawnProbability) {
spawnObstacle();
}
}
}
// Spawn power-ups occasionally (15% chance when spawning obstacles)
if (LK.ticks % Math.max(60 - Math.floor(gameSpeed), 30) === 0 && Math.random() < 0.15) {
spawnPowerUp();
}
// Update and clean up obstacles
for (var i = obstacles.length - 1; i >= 0; i--) {
var obstacle = obstacles[i];
// Check if obstacle went off screen
if (obstacle.y > 2800) {
obstacle.destroy();
obstacles.splice(i, 1);
continue;
}
// Check collision with vehicle
if (obstacle.intersects(vehicle) && !vehicleInvincible) {
if (obstacle.slippery) {
// Oil spill effect - vehicle slides randomly and slows down for 1 second
vehicle.targetX += (Math.random() - 0.5) * 400;
vehicleSlowed = true;
vehicleSlowedEndTime = LK.ticks + 60; // 1 second at 60 FPS
LK.effects.flashScreen(0x8B4513, 300);
// Tint vehicle brown to show oil effect
tween(vehicle, {
tint: 0x8B4513
}, {
duration: 200
});
// Slight damage but no life lost
} else if (obstacle.deadly) {
// Spike - instant death
lives = 0;
LK.effects.flashScreen(0xff0000, 1000);
LK.getSound('crash').play();
} else if (obstacle.stunEffect) {
// Trap hole - stun vehicle for 2 seconds (cannot move)
vehicleStunned = true;
vehicleStunnedEndTime = LK.ticks + 120; // 2 seconds at 60 FPS
// Add rotation animation while stunned
tween(vehicle, {
rotation: vehicle.rotation + Math.PI * 4 // 2 full rotations
}, {
duration: 2000,
// 2 seconds
easing: tween.easeOut
});
// No life lost, just stunning effect
} else if (obstacle.blocking) {
// Barrier - damages vehicle and pushes it back
lives--;
LK.getSound('crash').play();
// Push vehicle back slightly
vehicle.targetX = vehicle.x + (Math.random() - 0.5) * 200;
} else {
// Regular obstacle
lives--;
LK.effects.flashScreen(0xff0000, 500);
LK.getSound('crash').play();
}
// Hide a heart icon for regular, deadly, and blocking obstacles
if (!obstacle.slippery && !obstacle.stunEffect && lives >= 0 && lives < heartIcons.length) {
heartIcons[heartIcons.length - 1 - lives].visible = false;
}
// Activate invincibility for 1 second after any collision
vehicleInvincible = true;
vehicleInvincibleEndTime = LK.ticks + 60; // 1 second at 60 FPS
// Add flashing effect during invincibility
tween(vehicle, {
alpha: 0.3
}, {
duration: 100,
easing: tween.linear,
onFinish: function onFinish() {
if (vehicleInvincible) {
tween(vehicle, {
alpha: 1.0
}, {
duration: 100,
easing: tween.linear,
onFinish: function onFinish() {
if (vehicleInvincible) {
// Continue flashing by calling this recursively
tween(vehicle, {
alpha: 0.3
}, {
duration: 100,
easing: tween.linear,
onFinish: function onFinish() {
if (vehicleInvincible) {
tween(vehicle, {
alpha: 1.0
}, {
duration: 100
});
}
}
});
}
}
});
}
}
});
// Remove the obstacle that was hit
obstacle.destroy();
obstacles.splice(i, 1);
// Check if game over
if (lives <= 0) {
gameRunning = false;
LK.setTimeout(function () {
LK.showGameOver();
}, 500);
return;
}
continue;
}
}
};
un propulsor turbo de carreras que expulse fuego con perspectiva hacia arriba In-Game asset. 2d. High contrast. No shadows
carretera oscura con perspectiva desde arriba. In-Game asset. 2d. High contrast. No shadows
carro azul deportivo con la perspectiva hacia arriba. In-Game asset. 2d. High contrast. No shadows hecho con pixeles acelerando con perspectiva trasera sin el rastro
un carro rojo deportivo con la perspectiva hacia arriba. In-Game asset. 2d. High contrast. No shadows hecho con pixeles
tres corazones hechos con pixeles. In-Game asset. 2d. High contrast. No shadows
un coche blanco deportivo hecho con pixeles con perspectiva desde arriba de la parte trasera. In-Game asset. 2d. High contrast. No shadows
tira de puas hecho con pixeles. In-Game asset. 2d. High contrast. No shadows
boton rojo hecho con pixeles con la palabra play en medio In-Game asset. 2d. High contrast. No shadows
un auto verde deportivo con perspectiva desde arriba hecho con pixeles. In-Game asset. 2d. High contrast. No shadows con perspectiva trasera
un auto amarillo deportivo con perspectiva desde arriba hecho con pixeles. In-Game asset. 2d. High contrast. No shadows con perspectiva trasera
un auto negro deportivo hecho con pixeles con la perspectiva desde arriba y trasera. In-Game asset. 2d. High contrast. No shadows
agujero de la calle hecho con pixeles. In-Game asset. 2d. High contrast. No shadows
un barril derramando petroleo negro hecho con pixeles In-Game asset. 2d. High contrast. No shadows
coche de policia hecho con pixeles con perspectiva desde arriba In-Game asset. 2d. High contrast. No shadows
motociclista de chaqueta negra hecha con pixeles con perspectiva desde arriba y trasera. In-Game asset. 2d. High contrast. No shadows
auto celeste deportivo con perspectiva desde arriba y trasera hecho con pixeles. In-Game asset. 2d. High contrast. No shadows
letras que dicen speed runner las letras speed tienen un color blanco con contorno negro y las letras runner un color celeste con un contorno azul todo hecho con pixeles y con una cursiva. In-Game asset. 2d. High contrast. No shadows