User prompt
Please fix the bug: 'TypeError: storage.save is not a function. (In 'storage.save()', 'storage.save' is undefined)' in or related to this line: 'storage.save();' Line Number: 145 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Don’t make it say level 120 make it still say level one and then when you’ve completed level one, you move onto level two but when you die on level two and reset you’re still on level two ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Once you’re on level two when you die and reset you’re still on level two
Initial prompt
if you get score 10, it goes to level two and level two is different
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0, currentLevel: 1 }); /**** * Classes ****/ var Particle = Container.expand(function () { var self = Container.call(this); var particleGraphics = self.attachAsset('particle', { anchorX: 0.5, anchorY: 0.5 }); self.velX = (Math.random() - 0.5) * 10; self.velY = (Math.random() - 0.5) * 10 - 5; self.gravity = 0.3; self.life = 30 + Math.random() * 30; self.maxLife = self.life; self.update = function () { self.velY += self.gravity; self.x += self.velX; self.y += self.velY; self.life--; self.alpha = self.life / self.maxLife; if (self.life <= 0) { self.destroy(); var index = particles.indexOf(self); if (index !== -1) { particles.splice(index, 1); } } }; 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; self.active = true; self.verticalMovement = false; self.verticalDirection = 1; self.verticalSpeed = 2; self.startY = 0; // Make level 2+ platforms different if (storage.currentLevel >= 2) { platformGraphics.tint = 0x3498db; // Blue platforms for level 2+ self.verticalMovement = Math.random() > 0.5; // 50% chance of vertical movement } self.update = function () { if (!self.active) { return; } self.x -= self.speed; // Level 2+ platforms can move vertically if (self.verticalMovement && storage.currentLevel >= 2) { // Store initial Y position if not already set if (self.startY === 0) { self.startY = self.y; } // Move platform up and down within a range self.y += self.verticalDirection * self.verticalSpeed; // Change direction when reached limits if (self.y > self.startY + 150 || self.y < self.startY - 150) { self.verticalDirection *= -1; } } // If platform is off-screen to the left, deactivate it if (self.x < -platformGraphics.width) { self.active = false; } }; return self; }); var Player = Container.expand(function () { var self = Container.call(this); var playerGraphics = self.attachAsset('player', { anchorX: 0.5, anchorY: 0.5 }); self.gravity = 0.6; self.jumpForce = -19; self.velocity = 0; self.isJumping = false; self.isDead = false; self.isOnGround = false; self.jump = function () { if (self.isOnGround && !self.isDead) { self.velocity = self.jumpForce; self.isJumping = true; self.isOnGround = false; // Play jump sound with proper volume LK.getSound('jump').play({ volume: 0.7 }); self.createJumpEffect(); // Add a small boost at the peak of jump for better spike dodging LK.setTimeout(function () { if (self.isJumping && !self.isDead && self.velocity > -2 && self.velocity < 2) { // Small horizontal push tween(self, { x: self.x + 20 }, { duration: 300, easing: tween.easeOut }); } }, 300); } }; self.createJumpEffect = function () { for (var i = 0; i < 5; i++) { var particle = new Particle(); particle.x = self.x; particle.y = self.y + 30; game.addChild(particle); particles.push(particle); } }; self.die = function () { if (!self.isDead) { self.isDead = true; // Make sure the current level is saved before game over // storage plugin uses direct property assignment for persistence storage.currentLevel = storage.currentLevel; // This persists the current level // Play death sound with proper volume LK.getSound('death').play({ volume: 0.8 }); LK.stopMusic(); LK.effects.flashObject(self, 0xff0000, 500); LK.effects.flashScreen(0xff0000, 300); // Create death particles for (var i = 0; i < 15; i++) { var particle = new Particle(); particle.x = self.x; particle.y = self.y; game.addChild(particle); particles.push(particle); } LK.setTimeout(function () { LK.showGameOver(); }, 1000); } }; self.update = function () { if (self.isDead) { return; } // Apply gravity self.velocity += self.gravity; self.y += self.velocity; // Check ground collision if (self.y >= groundY - playerGraphics.height / 2) { self.y = groundY - playerGraphics.height / 2; self.velocity = 0; self.isJumping = false; self.isOnGround = true; } // Check ceiling collision if (self.y <= ceilingY + playerGraphics.height / 2) { self.y = ceilingY + playerGraphics.height / 2; self.velocity = 0; } // Rotate player based on movement if (self.isJumping) { playerGraphics.rotation += 0.1; } else { // Gradually reset rotation when on ground playerGraphics.rotation = playerGraphics.rotation % (Math.PI * 2); if (playerGraphics.rotation > 0.1) { playerGraphics.rotation -= 0.1; } else if (playerGraphics.rotation < -0.1) { playerGraphics.rotation += 0.1; } else { playerGraphics.rotation = 0; } } }; return self; }); var Spike = Container.expand(function () { var self = Container.call(this); var spikeGraphics = self.attachAsset('spike', { anchorX: 0.5, anchorY: 0.5 }); self.rotation = Math.PI / 4; // Rotate to make it look like a spike self.speed = 5; self.active = true; // Check if we're in level 2+ and make the spike different if (storage.currentLevel >= 2) { spikeGraphics.tint = 0xf1c40f; // Yellow spikes for level 2+ self.scaleX = 1.2; // Slightly larger spikes self.scaleY = 1.2; } self.update = function () { if (!self.active) { return; } // Store the last x position to detect when passing the player if (self.lastX === undefined) { self.lastX = self.x; self.passed = false; } self.x -= self.speed; // If spike is off-screen to the left, deactivate it if (self.x < -50) { self.active = false; } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x34495e }); /**** * Game Code ****/ // Game variables var player; var obstacles = []; var platforms = []; var particles = []; var groundY = 2500; var ceilingY = 200; var score = 0; var obstacleTimer = 0; var obstacleInterval = 90; // Frames between obstacle spawns var platformTimer = 0; var platformInterval = 180; // Frames between platform spawns var difficultyTimer = 0; var difficultyInterval = 600; // Frames before increasing difficulty var gameSpeed = 5; var maxGameSpeed = 12; var isGameStarted = false; var distanceTraveled = 0; var passedObstacles = []; // Track which obstacles have been passed // Create score text var scoreTxt = new Text2('0', { size: 100, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Create level text var levelTxt = new Text2('Level 1', { size: 60, fill: 0xFFFFFF }); levelTxt.anchor.set(0.5, 0); levelTxt.y = 120; LK.gui.top.addChild(levelTxt); // Create ground var ground = game.addChild(LK.getAsset('ground', { anchorX: 0, anchorY: 0, x: 0, y: groundY })); // Create ceiling var ceiling = game.addChild(LK.getAsset('ceiling', { anchorX: 0, anchorY: 0, x: 0, y: ceilingY - 40 })); // Create player player = new Player(); player.x = 400; player.y = groundY - 100; game.addChild(player); // Create instructions text var instructionsTxt = new Text2('Tap to jump and avoid spikes!', { size: 80, fill: 0xFFFFFF }); instructionsTxt.anchor.set(0.5, 0.5); instructionsTxt.x = 2048 / 2; instructionsTxt.y = 2732 / 2; game.addChild(instructionsTxt); // Create tap to start text var startTxt = new Text2('Tap to Start', { size: 120, fill: 0xFFFFFF }); startTxt.anchor.set(0.5, 0.5); startTxt.x = 2048 / 2; startTxt.y = 2732 / 2 + 200; game.addChild(startTxt); // Handle user input game.down = function (x, y, obj) { if (!isGameStarted) { startGame(); } else if (!player.isDead) { player.jump(); } }; function startGame() { isGameStarted = true; instructionsTxt.visible = false; startTxt.visible = false; // Reset score but keep the current level from storage score = 0; updateScore(0); // Make sure we use the stored level that persists through game resets if (!storage.currentLevel || storage.currentLevel < 1) { storage.currentLevel = 1; } updateLevel(storage.currentLevel); // Play background music LK.playMusic('gameMusic', { volume: 0.6, fade: { start: 0, end: 1, duration: 1000 } }); } function createSpike() { var spike = new Spike(); spike.x = 2100; spike.y = groundY - spike.height / 2; game.addChild(spike); obstacles.push(spike); } function createPlatform() { var platform = new Platform(); platform.x = 2100; // Random y position but ensure it's not too close to ground or ceiling var minY = ceilingY + 200; var maxY = groundY - 200; platform.y = minY + Math.random() * (maxY - minY); game.addChild(platform); platforms.push(platform); } function updateScore(value) { score = value; scoreTxt.setText('Score: ' + score); LK.setScore(score); // Update high score if needed if (score > storage.highScore) { storage.highScore = score; } // For visual effect when score increases significantly if (value % 50 === 0) { // Add particle effects to celebrate milestones for (var i = 0; i < 10; i++) { var particle = new Particle(); particle.x = scoreTxt.x; particle.y = scoreTxt.y; game.addChild(particle); particles.push(particle); } } } function updateLevel(level) { storage.currentLevel = level; levelTxt.setText('Level ' + level); // Make gameplay different for level 2 if (level === 2) { // Change the player's appearance for level 2 player.getChildAt(0).tint = 0xe74c3c; // Red player in level 2 // Make level 2 more challenging obstacleInterval = 60; // More frequent obstacles platformInterval = 120; // More frequent platforms gameSpeed = 7; // Faster game speed // Increase jump force for higher jumps in level 2 player.jumpForce = -22; // Create initial level 2 obstacles for (var i = 0; i < 3; i++) { var spike = new Spike(); spike.x = 2100 + i * 500; spike.y = groundY - spike.height / 2; game.addChild(spike); obstacles.push(spike); } } else { // Adjust difficulty based on level for other levels obstacleInterval = Math.max(30, 90 - (level - 1) * 10); platformInterval = Math.max(60, 180 - (level - 1) * 20); gameSpeed = Math.min(maxGameSpeed, 5 + (level - 1) * 0.5); } // Update obstacle speeds obstacles.forEach(function (obstacle) { if (obstacle.active) { obstacle.speed = gameSpeed; } }); // Update platform speeds platforms.forEach(function (platform) { if (platform.active) { platform.speed = gameSpeed; } }); } function checkCollisions() { if (player.isDead) { return; } // Check spike collisions for (var i = 0; i < obstacles.length; i++) { var obstacle = obstacles[i]; if (obstacle.active && player.intersects(obstacle)) { player.die(); return; } } // Check platform collisions var wasOnPlatform = false; for (var j = 0; j < platforms.length; j++) { var platform = platforms[j]; if (platform.active && player.intersects(platform)) { // Only if player is falling and above the platform if (player.velocity > 0 && player.y < platform.y - platform.height / 2) { player.y = platform.y - platform.height / 2 - player.height / 2; player.velocity = 0; player.isJumping = false; player.isOnGround = true; wasOnPlatform = true; } } } // If not on a platform and not on the ground, player is in the air if (!wasOnPlatform && player.y < groundY - player.height / 2) { player.isOnGround = false; } } function clearInactiveObjects() { // Clear inactive obstacles for (var i = obstacles.length - 1; i >= 0; i--) { if (!obstacles[i].active) { obstacles[i].destroy(); obstacles.splice(i, 1); } } // Clear inactive platforms for (var j = platforms.length - 1; j >= 0; j--) { if (!platforms[j].active) { platforms[j].destroy(); platforms.splice(j, 1); } } } function levelComplete() { // Play level complete sound with proper volume LK.getSound('levelComplete').play({ volume: 0.9 }); LK.effects.flashScreen(0x27ae60, 500); var levelCompleteTxt = new Text2('LEVEL COMPLETE!', { size: 120, fill: 0xFFFFFF }); levelCompleteTxt.anchor.set(0.5, 0.5); levelCompleteTxt.x = 2048 / 2; levelCompleteTxt.y = 2732 / 2; game.addChild(levelCompleteTxt); // Clear current obstacles and platforms if moving to level 2 if (storage.currentLevel === 1 && score >= 10) { // Clear obstacles for (var i = obstacles.length - 1; i >= 0; i--) { obstacles[i].destroy(); obstacles.splice(i, 1); } // Clear platforms for (var j = platforms.length - 1; j >= 0; j--) { platforms[j].destroy(); platforms.splice(j, 1); } // Change game environment for level 2 ground.tint = 0x8e44ad; // Purple ground for level 2 ceiling.tint = 0x8e44ad; // Purple ceiling for level 2 game.setBackgroundColor(0x2c3e50); // Darker background for level 2 } else { // Keep obstacles and platforms but increase their speed // This ensures continuous gameplay rather than resetting obstacles.forEach(function (obstacle) { if (obstacle.active) { obstacle.speed = Math.min(maxGameSpeed, obstacle.speed + 0.5); } }); platforms.forEach(function (platform) { if (platform.active) { platform.speed = Math.min(maxGameSpeed, platform.speed + 0.5); } }); } // Don't reset player position, let them continue playing // Advance to next level after a short delay LK.setTimeout(function () { levelCompleteTxt.destroy(); updateLevel(storage.currentLevel + 1); }, 2000); } // Main game update loop game.update = function () { if (!isGameStarted || player.isDead) { return; } // Increase distance traveled distanceTraveled += gameSpeed; // Check for obstacles that player has passed for (var i = 0; i < obstacles.length; i++) { var obstacle = obstacles[i]; if (obstacle.active && !obstacle.passed && obstacle.x < player.x && obstacle.lastX >= player.x) { obstacle.passed = true; updateScore(score + 1); // Increase score by 1 when passing a spike LK.effects.flashObject(player, 0x00ff00, 200); // Visual feedback } // Update lastX after checking obstacle.lastX = obstacle.x; } // Remove automatic score increase based on distance traveled // No longer increasing score just for traveling distance // Check for level progression at score 10 if (score === 10 && storage.currentLevel === 1) { levelComplete(); } else if (score > 10 && score % 100 === 0) { // For later levels, progress every 100 points // Only trigger once when exactly hitting the target if (score % 200 !== 0) { levelComplete(); } } // Spawn new obstacles obstacleTimer++; if (obstacleTimer >= obstacleInterval) { createSpike(); obstacleTimer = 0; } // Spawn new platforms platformTimer++; if (platformTimer >= platformInterval) { createPlatform(); platformTimer = 0; } // Increase difficulty over time difficultyTimer++; if (difficultyTimer >= difficultyInterval) { gameSpeed = Math.min(maxGameSpeed, gameSpeed + 0.1); difficultyTimer = 0; } // Update obstacles for (var i = 0; i < obstacles.length; i++) { obstacles[i].update(); } // Update platforms for (var j = 0; j < platforms.length; j++) { platforms[j].update(); } // Update particles for (var k = 0; k < particles.length; k++) { particles[k].update(); } // Update player player.update(); // Check collisions checkCollisions(); // Clean up inactive objects clearInactiveObjects(); };
===================================================================
--- original.js
+++ change.js
@@ -127,9 +127,10 @@
self.die = function () {
if (!self.isDead) {
self.isDead = true;
// Make sure the current level is saved before game over
- storage.save();
+ // storage plugin uses direct property assignment for persistence
+ storage.currentLevel = storage.currentLevel; // This persists the current level
// Play death sound with proper volume
LK.getSound('death').play({
volume: 0.8
});