User prompt
Make the controls more consistent and stop screen scrolling
User prompt
Make the screen scroll slower
User prompt
Let's add the soundtrack
User prompt
Please add sound effects and music
Code edit (1 edits merged)
Please save this source code
User prompt
Rock & Hop: Riff Runner
Initial prompt
Let's make a platformer in which you play as an electric guitar the coins will be guitar picks and the obstacles are string cutters the death sounds will be a guitar sequel
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Guitar = Container.expand(function () { var self = Container.call(this); var guitarGraphics = self.attachAsset('guitar', { anchorX: 0.5, anchorY: 0.5 }); self.vx = 0; self.vy = 0; self.isJumping = false; self.canJump = true; self.hasDoubleJump = true; // Flag to track double jump availability self.isDoubleJumping = false; // Flag to track if currently in double jump self.gravity = 0.75; // Slightly reduced gravity for longer air time self.jumpForce = -20; // Adjusted jump force to match new platform spacing self.moveSpeed = 15; // Increased horizontal movement for better platform navigation self.hasWhammy = false; self.hasAmp = false; self.ampTimer = 0; self.whammyTimer = 0; self.jump = function () { if (self.canJump) { // First jump self.vy = self.jumpForce; self.isJumping = true; self.canJump = false; LK.getSound('jump').play(); } else if (self.hasDoubleJump && !self.isDoubleJumping) { // Double jump - stronger to ensure reaching higher platforms self.vy = self.jumpForce * 0.9; // Increased from 0.8 to 0.9 for better height self.isDoubleJumping = true; self.hasDoubleJump = false; LK.getSound('jump').play(); } }; self.update = function () { // Apply gravity self.vy += self.gravity; // Move guitar self.y += self.vy; // Update powerup timers if (self.hasAmp) { self.ampTimer--; if (self.ampTimer <= 0) { self.hasAmp = false; guitarGraphics.tint = 0xFFFFFF; } } if (self.hasWhammy) { self.whammyTimer--; if (self.whammyTimer <= 0) { self.hasWhammy = false; guitarGraphics.alpha = 1; } } }; self.activateAmplifier = function () { self.hasAmp = true; self.ampTimer = 300; // 5 seconds at 60fps guitarGraphics.tint = 0xFF00FF; // Change color to indicate amplified }; self.activateWhammy = function () { self.hasWhammy = true; self.whammyTimer = 300; // 5 seconds at 60fps guitarGraphics.alpha = 0.6; // Fade to indicate whammy bar protection }; self.reset = function () { self.vx = 0; self.vy = 0; self.isJumping = false; self.isDoubleJumping = false; // Reset double jump status self.hasDoubleJump = true; // Reset double jump availability self.canJump = true; self.hasWhammy = false; self.hasAmp = false; guitarGraphics.tint = 0xFFFFFF; guitarGraphics.alpha = 1; }; return self; }); var GuitarPick = Container.expand(function () { var self = Container.call(this); var pickGraphics = self.attachAsset('guitarPick', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 5; // Move at the same speed as platforms self.active = true; self.collected = false; self.update = function () { if (self.active && !self.collected) { self.y += scrollSpeed; // Rotation for nice visual effect pickGraphics.rotation += 0.02; // Remove if off-screen (above or below) if (self.y > 2832 || self.y < -100) { self.active = false; } } }; self.collect = function () { self.collected = true; self.visible = false; LK.getSound('pickCollect').play(); }; self.reset = function () { self.active = true; self.collected = false; self.visible = true; }; return self; }); var Platform = Container.expand(function () { var self = Container.call(this); var platformGraphics = self.attachAsset('platform', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 5; // Default platform speed self.active = true; self.update = function () { if (self.active) { self.y += scrollSpeed; // Remove platform if it's completely off-screen (above or below) // Adjusted to account for platform height (30px) if (self.y > 2832 + platformGraphics.height / 2 || self.y < -100 - platformGraphics.height / 2) { self.active = false; } } }; self.reset = function () { self.active = true; }; return self; }); var PowerUp = Container.expand(function (type) { var self = Container.call(this); self.type = type || 'amplifier'; // Default to amplifier var powerupGraphics = self.attachAsset(self.type, { anchorX: 0.5, anchorY: 0.5 }); self.speed = 5; // Move at the same speed as platforms self.active = true; self.collected = false; self.update = function () { if (self.active && !self.collected) { self.y += scrollSpeed; // Rotation for nice visual effect powerupGraphics.rotation += 0.01; // Remove if off-screen (above or below) if (self.y > 2832 || self.y < -100) { self.active = false; } } }; self.collect = function () { self.collected = true; self.visible = false; LK.getSound('powerUp').play(); }; self.reset = function () { self.active = true; self.collected = false; self.visible = true; }; return self; }); var StringCutter = Container.expand(function () { var self = Container.call(this); var cutterGraphics = self.attachAsset('stringCutter', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 7; // Slightly faster than platforms self.active = true; self.update = function () { if (self.active) { self.y += scrollSpeed + 2; // Simple animation cutterGraphics.rotation += 0.04; // Remove if off-screen (above or below) if (self.y > 2832 || self.y < -100) { self.active = false; } } }; self.reset = function () { self.active = true; }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x202020 }); /**** * Game Code ****/ // Game state variables var scrollSpeed = 0; // Set to 0 to stop screen scrolling var score = 0; var gameRunning = true; var difficulty = 1; var platformSpawnTimer = 0; var pickSpawnTimer = 0; var cutterSpawnTimer = 0; var powerupSpawnTimer = 0; var lastPlatformY = 0; // Arrays to hold game objects var platforms = []; var picks = []; var cutters = []; var powerups = []; // Set up background var background = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5, x: 2048 / 2, y: 2732 / 2 }); game.addChild(background); // Create player guitar var guitar = new Guitar(); guitar.x = 2048 / 2; guitar.y = 2732 / 2; game.addChild(guitar); // Create UI elements var scoreTxt = new Text2('SCORE: 0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Spawner functions function spawnPlatform() { // Don't spawn new platforms if scrollSpeed is 0 if (scrollSpeed === 0) { // Create platforms throughout the screen var platform = new Platform(); platform.x = Math.random() * (2048 - 300) + 150; // Random position within screen bounds // Find last platform position var lastY = 0; if (platforms.length > 0) { var highestPlatform = null; var highestY = 2732; for (var i = 0; i < platforms.length; i++) { if (platforms[i].y < highestY) { highestY = platforms[i].y; highestPlatform = platforms[i]; } } if (highestPlatform) { // Place new platform above the highest one with appropriate spacing // 150 pixels is a better jump distance for regular jumps platform.y = highestY - 150; // Randomize a bit to make it more interesting but still jumpable platform.y += Math.random() * 20 - 10; // Reduced to +/- 10 pixels for more predictable jumps // Ensure platform doesn't go off the top of the screen and isn't too close to the top platform.y = Math.max(platform.y, 200); // Increased from 50 to 200 for more space at top } else { platform.y = 2732 / 2; } } else { platform.y = 2732 / 2; } platforms.push(platform); game.addChild(platform); // Track the Y-position for spawning objects on platforms lastPlatformY = platform.y; // Randomly decide if we should spawn a pick on this platform if (Math.random() < 0.5) { spawnPickOnPlatform(platform.x, platform.y); } // Randomly spawn a powerup (less frequently) if (Math.random() < 0.15) { spawnPowerupOnPlatform(platform.x, platform.y); } return; } var platform = new Platform(); platform.x = Math.random() * (2048 - 300) + 150; // Random position within screen bounds // Ensure platform starts just above the screen but not too far platform.y = -50; // Start above the screen // Track the Y-position for spawning objects on platforms lastPlatformY = platform.y; platforms.push(platform); game.addChild(platform); // Randomly decide if we should spawn a pick on this platform if (Math.random() < 0.5) { spawnPickOnPlatform(platform.x, platform.y); } // Randomly spawn a powerup (less frequently) if (Math.random() < 0.15) { spawnPowerupOnPlatform(platform.x, platform.y); } } function spawnPickOnPlatform(x, y) { var pick = new GuitarPick(); pick.x = x; pick.y = y - 50; // Position slightly above the platform picks.push(pick); game.addChild(pick); } function spawnPowerupOnPlatform(x, y) { var type = Math.random() < 0.5 ? 'amplifier' : 'whammyBar'; var powerup = new PowerUp(type); powerup.x = x; powerup.y = y - 70; // Position above the platform powerups.push(powerup); game.addChild(powerup); } function spawnCutter() { var cutter = new StringCutter(); cutter.x = Math.random() * (2048 - 100) + 50; // Random position cutter.y = -50; // Start above the screen cutters.push(cutter); game.addChild(cutter); } // Collision check functions function checkPlatformCollisions() { for (var i = 0; i < platforms.length; i++) { var platform = platforms[i]; if (platform.active && guitar.vy > 0) { // Only check when falling if (guitar.intersects(platform)) { // Land on the platform guitar.y = platform.y - (platform.height / 2 + guitar.height / 2) + 10; guitar.vy = 0; guitar.isJumping = false; guitar.isDoubleJumping = false; // Reset double jump status guitar.hasDoubleJump = true; // Enable double jump again guitar.canJump = true; } } } } function checkPickCollisions() { for (var i = 0; i < picks.length; i++) { var pick = picks[i]; if (pick.active && !pick.collected && guitar.intersects(pick)) { pick.collect(); score += 10; scoreTxt.setText('SCORE: ' + score); // No win condition - game continues regardless of score } } } function checkCutterCollisions() { for (var i = 0; i < cutters.length; i++) { var cutter = cutters[i]; if (cutter.active && guitar.intersects(cutter)) { if (guitar.hasWhammy) { // Whammy bar protects from one hit guitar.hasWhammy = false; cutter.active = false; cutter.visible = false; } else { // Game over LK.getSound('guitarSqueal').play(); LK.effects.flashScreen(0xFF0000, 500); gameRunning = false; LK.showGameOver(); } } } } function checkPowerupCollisions() { for (var i = 0; i < powerups.length; i++) { var powerup = powerups[i]; if (powerup.active && !powerup.collected && guitar.intersects(powerup)) { powerup.collect(); if (powerup.type === 'amplifier') { guitar.activateAmplifier(); } else if (powerup.type === 'whammyBar') { guitar.activateWhammy(); } } } } function checkBoundaries() { // Don't let guitar go off the sides if (guitar.x < guitar.width / 2) { guitar.x = guitar.width / 2; } else if (guitar.x > 2048 - guitar.width / 2) { guitar.x = 2048 - guitar.width / 2; } // Reset game if guitar goes off the top or falls off the bottom if (guitar.y > 2732 + guitar.height || guitar.y < -guitar.height) { LK.getSound('guitarSqueal').play(); LK.effects.flashScreen(0xFF0000, 500); // Reset player position guitar.reset(); // Find a random platform without a guitar pick var availablePlatforms = platforms.filter(function (platform) { // Check if platform doesn't have a pick on it return platform.active && !picks.some(function (pick) { return !pick.collected && Math.abs(pick.x - platform.x) < 10 && Math.abs(pick.y - (platform.y - 50)) < 10; }); }); // If we have available platforms, place the guitar on a random one if (availablePlatforms.length > 0) { // Filter out platforms that are in corner areas var safePlatforms = availablePlatforms.filter(function (platform) { // Keep platforms that are not in the top corners (avoid top 200px and 300px from sides) var notInTopCorner = !(platform.y < 200 && (platform.x < 300 || platform.x > 2048 - 300)); // Keep platforms that are not in the bottom corners (avoid bottom 200px and 300px from sides) var notInBottomCorner = !(platform.y > 2732 - 200 && (platform.x < 300 || platform.x > 2048 - 300)); return notInTopCorner && notInBottomCorner; }); // If we have safe platforms, use them, otherwise fall back to all available platforms var platformsToUse = safePlatforms.length > 0 ? safePlatforms : availablePlatforms; var randomPlatform = platformsToUse[Math.floor(Math.random() * platformsToUse.length)]; guitar.x = randomPlatform.x; guitar.y = randomPlatform.y - 120; // Position above the platform } else { // Fallback to center if no platform is available guitar.x = 2048 / 2; guitar.y = 2732 / 2; } // Reset score score = 0; scoreTxt.setText('SCORE: ' + score); LK.setScore(score); } } // Event handlers game.down = function (x, y, obj) { // Jump when tapping upper half of screen if (y < 2732 / 2) { guitar.jump(); } // Move left/right when tapping bottom half else { if (x < 2048 / 2) { guitar.x -= guitar.moveSpeed * 6; // Move left faster for better responsiveness } else { guitar.x += guitar.moveSpeed * 6; // Move right faster for better responsiveness } } }; game.move = function (x, y, obj) { // No dragging implementation for now }; game.up = function (x, y, obj) { // Release handling }; // Keyboard event handling for arrow keys var keyState = {}; // Listen for keydown events LK.on('keydown', function (obj) { keyState[obj.event.key] = true; // Jump with up arrow if (obj.event.key === 'ArrowUp' && guitar.canJump) { guitar.jump(); } }); // Listen for keyup events LK.on('keyup', function (obj) { keyState[obj.event.key] = false; }); // Function to handle keyboard movement function handleKeyboardInput() { // Move left with left arrow if (keyState['ArrowLeft']) { guitar.x -= guitar.moveSpeed * 1.2; // Slightly faster horizontal movement } // Move right with right arrow if (keyState['ArrowRight']) { guitar.x += guitar.moveSpeed * 1.2; // Slightly faster horizontal movement } } // Update function game.update = function () { if (!gameRunning) { return; } // Process keyboard input if (gameRunning) { handleKeyboardInput(); } // Increase difficulty over time if (LK.ticks % 600 === 0 && difficulty < 5) { difficulty += 0.5; // Keep scrollSpeed at 0 (no movement) scrollSpeed = 0; } // Update guitar guitar.update(); // Update platforms for (var i = platforms.length - 1; i >= 0; i--) { platforms[i].update(); if (!platforms[i].active) { platforms[i].destroy(); platforms.splice(i, 1); } } // Update picks for (var i = picks.length - 1; i >= 0; i--) { picks[i].update(); if (!picks[i].active || picks[i].collected) { picks[i].destroy(); picks.splice(i, 1); } } // Update cutters for (var i = cutters.length - 1; i >= 0; i--) { cutters[i].update(); if (!cutters[i].active) { cutters[i].destroy(); cutters.splice(i, 1); } } // Update powerups for (var i = powerups.length - 1; i >= 0; i--) { powerups[i].update(); if (!powerups[i].active || powerups[i].collected) { powerups[i].destroy(); powerups.splice(i, 1); } } // Check collisions checkPlatformCollisions(); checkPickCollisions(); checkCutterCollisions(); checkPowerupCollisions(); checkBoundaries(); // Spawn objects platformSpawnTimer++; cutterSpawnTimer++; // Make sure there are always 12 guitar picks if (picks.length < 12 && platforms.length > 0) { // Choose a random active platform to place the pick on var validPlatforms = platforms.filter(function (platform) { return platform.active; }); if (validPlatforms.length > 0) { var randomPlatform = validPlatforms[Math.floor(Math.random() * validPlatforms.length)]; var newPick = new GuitarPick(); newPick.x = randomPlatform.x; newPick.y = randomPlatform.y - 50; // Position above the platform picks.push(newPick); game.addChild(newPick); } } // Only spawn platforms if we're scrolling if (scrollSpeed != 0 && platformSpawnTimer > 5) { // Further reduced from 10 to 5 for more frequent platforms spawnPlatform(); platformSpawnTimer = 0; } // Only spawn cutters if we're scrolling if (scrollSpeed != 0 && score > 0 && score % 20 === 0 && cutterSpawnTimer > 60) { spawnCutter(); cutterSpawnTimer = 0; } // Only guitar pick collection will increase score now if (LK.ticks % 60 === 0) { // Just update the global score without incrementing it LK.setScore(score); } }; // Initial platform setup - platforms along the bottom portion of the screen for (var i = 0; i < 20; i++) { var startingPlatform = new Platform(); // Distribute platforms more evenly horizontally startingPlatform.x = 150 + i % 4 * (1748 / 3) + Math.random() * 150; // Better spacing vertically for proper jump height startingPlatform.y = 2732 - 200 - i * 150; // Reduced to 150 pixels for better accessibility // Add very small random variation to avoid making platforms unreachable startingPlatform.y += Math.random() * 20 - 10; // Reduced to +/- 10 pixels for more predictable jumps // Ensure platform doesn't go off the top of the screen and isn't too close to the top startingPlatform.y = Math.max(startingPlatform.y, 200); // Increased from 50 to 200 for more space at top platforms.push(startingPlatform); game.addChild(startingPlatform); // Add a pick to some of the initial platforms if (Math.random() < 0.5) { var initialPick = new GuitarPick(); initialPick.x = startingPlatform.x; initialPick.y = startingPlatform.y - 50; // Position above the platform picks.push(initialPick); game.addChild(initialPick); } } // Starting platform for player at the bottom of the map var homePlatform = new Platform(); homePlatform.x = 2048 / 2; homePlatform.y = 2732 - 100; // Near bottom of the screen platforms.push(homePlatform); game.addChild(homePlatform); // Make sure no guitar pick spawns on the home platform for (var i = picks.length - 1; i >= 0; i--) { if (picks[i].x === homePlatform.x && Math.abs(picks[i].y - (homePlatform.y - 50)) < 10) { picks[i].destroy(); picks.splice(i, 1); } } // Select a random platform for the guitar to spawn on (not the home platform) var availablePlatforms = platforms.filter(function (platform) { // Skip home platform and check if platform doesn't have a pick on it return platform !== homePlatform && !picks.some(function (pick) { return Math.abs(pick.x - platform.x) < 10 && Math.abs(pick.y - (platform.y - 50)) < 10; }); }); // If we have available platforms, place the guitar on a random one if (availablePlatforms.length > 0) { // Filter out platforms that are too close to the top or in corners var safeplatforms = availablePlatforms.filter(function (platform) { // Keep platforms that are at least 400px from the top (increased from 200px) var notTooHigh = platform.y > 400; // Keep platforms that are not in the top corners var notInTopCorner = !(platform.y < 400 && (platform.x < 300 || platform.x > 2048 - 300)); // Keep platforms that are not in the bottom corners var notInBottomCorner = !(platform.y > 2732 - 200 && (platform.x < 300 || platform.x > 2048 - 300)); return notTooHigh && notInTopCorner && notInBottomCorner; }); // If no safe platforms, use all available platforms if (safeplatforms.length === 0) { safeplatforms = availablePlatforms; } var randomPlatform = safeplatforms[Math.floor(Math.random() * safeplatforms.length)]; guitar.x = randomPlatform.x; guitar.y = randomPlatform.y - 120; // Position above the platform } else { // Fallback to home platform if no other options are available guitar.x = homePlatform.x; guitar.y = homePlatform.y - 120; } // Start the game music with a fade-in effect LK.playMusic('rockTrack', { fade: { start: 0, end: 1, duration: 1000 } });
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Guitar = Container.expand(function () {
var self = Container.call(this);
var guitarGraphics = self.attachAsset('guitar', {
anchorX: 0.5,
anchorY: 0.5
});
self.vx = 0;
self.vy = 0;
self.isJumping = false;
self.canJump = true;
self.hasDoubleJump = true; // Flag to track double jump availability
self.isDoubleJumping = false; // Flag to track if currently in double jump
self.gravity = 0.75; // Slightly reduced gravity for longer air time
self.jumpForce = -20; // Adjusted jump force to match new platform spacing
self.moveSpeed = 15; // Increased horizontal movement for better platform navigation
self.hasWhammy = false;
self.hasAmp = false;
self.ampTimer = 0;
self.whammyTimer = 0;
self.jump = function () {
if (self.canJump) {
// First jump
self.vy = self.jumpForce;
self.isJumping = true;
self.canJump = false;
LK.getSound('jump').play();
} else if (self.hasDoubleJump && !self.isDoubleJumping) {
// Double jump - stronger to ensure reaching higher platforms
self.vy = self.jumpForce * 0.9; // Increased from 0.8 to 0.9 for better height
self.isDoubleJumping = true;
self.hasDoubleJump = false;
LK.getSound('jump').play();
}
};
self.update = function () {
// Apply gravity
self.vy += self.gravity;
// Move guitar
self.y += self.vy;
// Update powerup timers
if (self.hasAmp) {
self.ampTimer--;
if (self.ampTimer <= 0) {
self.hasAmp = false;
guitarGraphics.tint = 0xFFFFFF;
}
}
if (self.hasWhammy) {
self.whammyTimer--;
if (self.whammyTimer <= 0) {
self.hasWhammy = false;
guitarGraphics.alpha = 1;
}
}
};
self.activateAmplifier = function () {
self.hasAmp = true;
self.ampTimer = 300; // 5 seconds at 60fps
guitarGraphics.tint = 0xFF00FF; // Change color to indicate amplified
};
self.activateWhammy = function () {
self.hasWhammy = true;
self.whammyTimer = 300; // 5 seconds at 60fps
guitarGraphics.alpha = 0.6; // Fade to indicate whammy bar protection
};
self.reset = function () {
self.vx = 0;
self.vy = 0;
self.isJumping = false;
self.isDoubleJumping = false; // Reset double jump status
self.hasDoubleJump = true; // Reset double jump availability
self.canJump = true;
self.hasWhammy = false;
self.hasAmp = false;
guitarGraphics.tint = 0xFFFFFF;
guitarGraphics.alpha = 1;
};
return self;
});
var GuitarPick = Container.expand(function () {
var self = Container.call(this);
var pickGraphics = self.attachAsset('guitarPick', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 5; // Move at the same speed as platforms
self.active = true;
self.collected = false;
self.update = function () {
if (self.active && !self.collected) {
self.y += scrollSpeed;
// Rotation for nice visual effect
pickGraphics.rotation += 0.02;
// Remove if off-screen (above or below)
if (self.y > 2832 || self.y < -100) {
self.active = false;
}
}
};
self.collect = function () {
self.collected = true;
self.visible = false;
LK.getSound('pickCollect').play();
};
self.reset = function () {
self.active = true;
self.collected = false;
self.visible = true;
};
return self;
});
var Platform = Container.expand(function () {
var self = Container.call(this);
var platformGraphics = self.attachAsset('platform', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 5; // Default platform speed
self.active = true;
self.update = function () {
if (self.active) {
self.y += scrollSpeed;
// Remove platform if it's completely off-screen (above or below)
// Adjusted to account for platform height (30px)
if (self.y > 2832 + platformGraphics.height / 2 || self.y < -100 - platformGraphics.height / 2) {
self.active = false;
}
}
};
self.reset = function () {
self.active = true;
};
return self;
});
var PowerUp = Container.expand(function (type) {
var self = Container.call(this);
self.type = type || 'amplifier'; // Default to amplifier
var powerupGraphics = self.attachAsset(self.type, {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 5; // Move at the same speed as platforms
self.active = true;
self.collected = false;
self.update = function () {
if (self.active && !self.collected) {
self.y += scrollSpeed;
// Rotation for nice visual effect
powerupGraphics.rotation += 0.01;
// Remove if off-screen (above or below)
if (self.y > 2832 || self.y < -100) {
self.active = false;
}
}
};
self.collect = function () {
self.collected = true;
self.visible = false;
LK.getSound('powerUp').play();
};
self.reset = function () {
self.active = true;
self.collected = false;
self.visible = true;
};
return self;
});
var StringCutter = Container.expand(function () {
var self = Container.call(this);
var cutterGraphics = self.attachAsset('stringCutter', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 7; // Slightly faster than platforms
self.active = true;
self.update = function () {
if (self.active) {
self.y += scrollSpeed + 2;
// Simple animation
cutterGraphics.rotation += 0.04;
// Remove if off-screen (above or below)
if (self.y > 2832 || self.y < -100) {
self.active = false;
}
}
};
self.reset = function () {
self.active = true;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x202020
});
/****
* Game Code
****/
// Game state variables
var scrollSpeed = 0; // Set to 0 to stop screen scrolling
var score = 0;
var gameRunning = true;
var difficulty = 1;
var platformSpawnTimer = 0;
var pickSpawnTimer = 0;
var cutterSpawnTimer = 0;
var powerupSpawnTimer = 0;
var lastPlatformY = 0;
// Arrays to hold game objects
var platforms = [];
var picks = [];
var cutters = [];
var powerups = [];
// Set up background
var background = LK.getAsset('background', {
anchorX: 0.5,
anchorY: 0.5,
x: 2048 / 2,
y: 2732 / 2
});
game.addChild(background);
// Create player guitar
var guitar = new Guitar();
guitar.x = 2048 / 2;
guitar.y = 2732 / 2;
game.addChild(guitar);
// Create UI elements
var scoreTxt = new Text2('SCORE: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Spawner functions
function spawnPlatform() {
// Don't spawn new platforms if scrollSpeed is 0
if (scrollSpeed === 0) {
// Create platforms throughout the screen
var platform = new Platform();
platform.x = Math.random() * (2048 - 300) + 150; // Random position within screen bounds
// Find last platform position
var lastY = 0;
if (platforms.length > 0) {
var highestPlatform = null;
var highestY = 2732;
for (var i = 0; i < platforms.length; i++) {
if (platforms[i].y < highestY) {
highestY = platforms[i].y;
highestPlatform = platforms[i];
}
}
if (highestPlatform) {
// Place new platform above the highest one with appropriate spacing
// 150 pixels is a better jump distance for regular jumps
platform.y = highestY - 150;
// Randomize a bit to make it more interesting but still jumpable
platform.y += Math.random() * 20 - 10; // Reduced to +/- 10 pixels for more predictable jumps
// Ensure platform doesn't go off the top of the screen and isn't too close to the top
platform.y = Math.max(platform.y, 200); // Increased from 50 to 200 for more space at top
} else {
platform.y = 2732 / 2;
}
} else {
platform.y = 2732 / 2;
}
platforms.push(platform);
game.addChild(platform);
// Track the Y-position for spawning objects on platforms
lastPlatformY = platform.y;
// Randomly decide if we should spawn a pick on this platform
if (Math.random() < 0.5) {
spawnPickOnPlatform(platform.x, platform.y);
}
// Randomly spawn a powerup (less frequently)
if (Math.random() < 0.15) {
spawnPowerupOnPlatform(platform.x, platform.y);
}
return;
}
var platform = new Platform();
platform.x = Math.random() * (2048 - 300) + 150; // Random position within screen bounds
// Ensure platform starts just above the screen but not too far
platform.y = -50; // Start above the screen
// Track the Y-position for spawning objects on platforms
lastPlatformY = platform.y;
platforms.push(platform);
game.addChild(platform);
// Randomly decide if we should spawn a pick on this platform
if (Math.random() < 0.5) {
spawnPickOnPlatform(platform.x, platform.y);
}
// Randomly spawn a powerup (less frequently)
if (Math.random() < 0.15) {
spawnPowerupOnPlatform(platform.x, platform.y);
}
}
function spawnPickOnPlatform(x, y) {
var pick = new GuitarPick();
pick.x = x;
pick.y = y - 50; // Position slightly above the platform
picks.push(pick);
game.addChild(pick);
}
function spawnPowerupOnPlatform(x, y) {
var type = Math.random() < 0.5 ? 'amplifier' : 'whammyBar';
var powerup = new PowerUp(type);
powerup.x = x;
powerup.y = y - 70; // Position above the platform
powerups.push(powerup);
game.addChild(powerup);
}
function spawnCutter() {
var cutter = new StringCutter();
cutter.x = Math.random() * (2048 - 100) + 50; // Random position
cutter.y = -50; // Start above the screen
cutters.push(cutter);
game.addChild(cutter);
}
// Collision check functions
function checkPlatformCollisions() {
for (var i = 0; i < platforms.length; i++) {
var platform = platforms[i];
if (platform.active && guitar.vy > 0) {
// Only check when falling
if (guitar.intersects(platform)) {
// Land on the platform
guitar.y = platform.y - (platform.height / 2 + guitar.height / 2) + 10;
guitar.vy = 0;
guitar.isJumping = false;
guitar.isDoubleJumping = false; // Reset double jump status
guitar.hasDoubleJump = true; // Enable double jump again
guitar.canJump = true;
}
}
}
}
function checkPickCollisions() {
for (var i = 0; i < picks.length; i++) {
var pick = picks[i];
if (pick.active && !pick.collected && guitar.intersects(pick)) {
pick.collect();
score += 10;
scoreTxt.setText('SCORE: ' + score);
// No win condition - game continues regardless of score
}
}
}
function checkCutterCollisions() {
for (var i = 0; i < cutters.length; i++) {
var cutter = cutters[i];
if (cutter.active && guitar.intersects(cutter)) {
if (guitar.hasWhammy) {
// Whammy bar protects from one hit
guitar.hasWhammy = false;
cutter.active = false;
cutter.visible = false;
} else {
// Game over
LK.getSound('guitarSqueal').play();
LK.effects.flashScreen(0xFF0000, 500);
gameRunning = false;
LK.showGameOver();
}
}
}
}
function checkPowerupCollisions() {
for (var i = 0; i < powerups.length; i++) {
var powerup = powerups[i];
if (powerup.active && !powerup.collected && guitar.intersects(powerup)) {
powerup.collect();
if (powerup.type === 'amplifier') {
guitar.activateAmplifier();
} else if (powerup.type === 'whammyBar') {
guitar.activateWhammy();
}
}
}
}
function checkBoundaries() {
// Don't let guitar go off the sides
if (guitar.x < guitar.width / 2) {
guitar.x = guitar.width / 2;
} else if (guitar.x > 2048 - guitar.width / 2) {
guitar.x = 2048 - guitar.width / 2;
}
// Reset game if guitar goes off the top or falls off the bottom
if (guitar.y > 2732 + guitar.height || guitar.y < -guitar.height) {
LK.getSound('guitarSqueal').play();
LK.effects.flashScreen(0xFF0000, 500);
// Reset player position
guitar.reset();
// Find a random platform without a guitar pick
var availablePlatforms = platforms.filter(function (platform) {
// Check if platform doesn't have a pick on it
return platform.active && !picks.some(function (pick) {
return !pick.collected && Math.abs(pick.x - platform.x) < 10 && Math.abs(pick.y - (platform.y - 50)) < 10;
});
});
// If we have available platforms, place the guitar on a random one
if (availablePlatforms.length > 0) {
// Filter out platforms that are in corner areas
var safePlatforms = availablePlatforms.filter(function (platform) {
// Keep platforms that are not in the top corners (avoid top 200px and 300px from sides)
var notInTopCorner = !(platform.y < 200 && (platform.x < 300 || platform.x > 2048 - 300));
// Keep platforms that are not in the bottom corners (avoid bottom 200px and 300px from sides)
var notInBottomCorner = !(platform.y > 2732 - 200 && (platform.x < 300 || platform.x > 2048 - 300));
return notInTopCorner && notInBottomCorner;
});
// If we have safe platforms, use them, otherwise fall back to all available platforms
var platformsToUse = safePlatforms.length > 0 ? safePlatforms : availablePlatforms;
var randomPlatform = platformsToUse[Math.floor(Math.random() * platformsToUse.length)];
guitar.x = randomPlatform.x;
guitar.y = randomPlatform.y - 120; // Position above the platform
} else {
// Fallback to center if no platform is available
guitar.x = 2048 / 2;
guitar.y = 2732 / 2;
}
// Reset score
score = 0;
scoreTxt.setText('SCORE: ' + score);
LK.setScore(score);
}
}
// Event handlers
game.down = function (x, y, obj) {
// Jump when tapping upper half of screen
if (y < 2732 / 2) {
guitar.jump();
}
// Move left/right when tapping bottom half
else {
if (x < 2048 / 2) {
guitar.x -= guitar.moveSpeed * 6; // Move left faster for better responsiveness
} else {
guitar.x += guitar.moveSpeed * 6; // Move right faster for better responsiveness
}
}
};
game.move = function (x, y, obj) {
// No dragging implementation for now
};
game.up = function (x, y, obj) {
// Release handling
};
// Keyboard event handling for arrow keys
var keyState = {};
// Listen for keydown events
LK.on('keydown', function (obj) {
keyState[obj.event.key] = true;
// Jump with up arrow
if (obj.event.key === 'ArrowUp' && guitar.canJump) {
guitar.jump();
}
});
// Listen for keyup events
LK.on('keyup', function (obj) {
keyState[obj.event.key] = false;
});
// Function to handle keyboard movement
function handleKeyboardInput() {
// Move left with left arrow
if (keyState['ArrowLeft']) {
guitar.x -= guitar.moveSpeed * 1.2; // Slightly faster horizontal movement
}
// Move right with right arrow
if (keyState['ArrowRight']) {
guitar.x += guitar.moveSpeed * 1.2; // Slightly faster horizontal movement
}
}
// Update function
game.update = function () {
if (!gameRunning) {
return;
}
// Process keyboard input
if (gameRunning) {
handleKeyboardInput();
}
// Increase difficulty over time
if (LK.ticks % 600 === 0 && difficulty < 5) {
difficulty += 0.5;
// Keep scrollSpeed at 0 (no movement)
scrollSpeed = 0;
}
// Update guitar
guitar.update();
// Update platforms
for (var i = platforms.length - 1; i >= 0; i--) {
platforms[i].update();
if (!platforms[i].active) {
platforms[i].destroy();
platforms.splice(i, 1);
}
}
// Update picks
for (var i = picks.length - 1; i >= 0; i--) {
picks[i].update();
if (!picks[i].active || picks[i].collected) {
picks[i].destroy();
picks.splice(i, 1);
}
}
// Update cutters
for (var i = cutters.length - 1; i >= 0; i--) {
cutters[i].update();
if (!cutters[i].active) {
cutters[i].destroy();
cutters.splice(i, 1);
}
}
// Update powerups
for (var i = powerups.length - 1; i >= 0; i--) {
powerups[i].update();
if (!powerups[i].active || powerups[i].collected) {
powerups[i].destroy();
powerups.splice(i, 1);
}
}
// Check collisions
checkPlatformCollisions();
checkPickCollisions();
checkCutterCollisions();
checkPowerupCollisions();
checkBoundaries();
// Spawn objects
platformSpawnTimer++;
cutterSpawnTimer++;
// Make sure there are always 12 guitar picks
if (picks.length < 12 && platforms.length > 0) {
// Choose a random active platform to place the pick on
var validPlatforms = platforms.filter(function (platform) {
return platform.active;
});
if (validPlatforms.length > 0) {
var randomPlatform = validPlatforms[Math.floor(Math.random() * validPlatforms.length)];
var newPick = new GuitarPick();
newPick.x = randomPlatform.x;
newPick.y = randomPlatform.y - 50; // Position above the platform
picks.push(newPick);
game.addChild(newPick);
}
}
// Only spawn platforms if we're scrolling
if (scrollSpeed != 0 && platformSpawnTimer > 5) {
// Further reduced from 10 to 5 for more frequent platforms
spawnPlatform();
platformSpawnTimer = 0;
}
// Only spawn cutters if we're scrolling
if (scrollSpeed != 0 && score > 0 && score % 20 === 0 && cutterSpawnTimer > 60) {
spawnCutter();
cutterSpawnTimer = 0;
}
// Only guitar pick collection will increase score now
if (LK.ticks % 60 === 0) {
// Just update the global score without incrementing it
LK.setScore(score);
}
};
// Initial platform setup - platforms along the bottom portion of the screen
for (var i = 0; i < 20; i++) {
var startingPlatform = new Platform();
// Distribute platforms more evenly horizontally
startingPlatform.x = 150 + i % 4 * (1748 / 3) + Math.random() * 150;
// Better spacing vertically for proper jump height
startingPlatform.y = 2732 - 200 - i * 150; // Reduced to 150 pixels for better accessibility
// Add very small random variation to avoid making platforms unreachable
startingPlatform.y += Math.random() * 20 - 10; // Reduced to +/- 10 pixels for more predictable jumps
// Ensure platform doesn't go off the top of the screen and isn't too close to the top
startingPlatform.y = Math.max(startingPlatform.y, 200); // Increased from 50 to 200 for more space at top
platforms.push(startingPlatform);
game.addChild(startingPlatform);
// Add a pick to some of the initial platforms
if (Math.random() < 0.5) {
var initialPick = new GuitarPick();
initialPick.x = startingPlatform.x;
initialPick.y = startingPlatform.y - 50; // Position above the platform
picks.push(initialPick);
game.addChild(initialPick);
}
}
// Starting platform for player at the bottom of the map
var homePlatform = new Platform();
homePlatform.x = 2048 / 2;
homePlatform.y = 2732 - 100; // Near bottom of the screen
platforms.push(homePlatform);
game.addChild(homePlatform);
// Make sure no guitar pick spawns on the home platform
for (var i = picks.length - 1; i >= 0; i--) {
if (picks[i].x === homePlatform.x && Math.abs(picks[i].y - (homePlatform.y - 50)) < 10) {
picks[i].destroy();
picks.splice(i, 1);
}
}
// Select a random platform for the guitar to spawn on (not the home platform)
var availablePlatforms = platforms.filter(function (platform) {
// Skip home platform and check if platform doesn't have a pick on it
return platform !== homePlatform && !picks.some(function (pick) {
return Math.abs(pick.x - platform.x) < 10 && Math.abs(pick.y - (platform.y - 50)) < 10;
});
});
// If we have available platforms, place the guitar on a random one
if (availablePlatforms.length > 0) {
// Filter out platforms that are too close to the top or in corners
var safeplatforms = availablePlatforms.filter(function (platform) {
// Keep platforms that are at least 400px from the top (increased from 200px)
var notTooHigh = platform.y > 400;
// Keep platforms that are not in the top corners
var notInTopCorner = !(platform.y < 400 && (platform.x < 300 || platform.x > 2048 - 300));
// Keep platforms that are not in the bottom corners
var notInBottomCorner = !(platform.y > 2732 - 200 && (platform.x < 300 || platform.x > 2048 - 300));
return notTooHigh && notInTopCorner && notInBottomCorner;
});
// If no safe platforms, use all available platforms
if (safeplatforms.length === 0) {
safeplatforms = availablePlatforms;
}
var randomPlatform = safeplatforms[Math.floor(Math.random() * safeplatforms.length)];
guitar.x = randomPlatform.x;
guitar.y = randomPlatform.y - 120; // Position above the platform
} else {
// Fallback to home platform if no other options are available
guitar.x = homePlatform.x;
guitar.y = homePlatform.y - 120;
}
// Start the game music with a fade-in effect
LK.playMusic('rockTrack', {
fade: {
start: 0,
end: 1,
duration: 1000
}
});
Blue Electric guitar flying v. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Electric guitar Amplifier. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Guitar pick. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Whammy bar. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
String cutters. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows