/**** * 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