User prompt
Put the misses counter above the lives
User prompt
Change the text High Score to Your High Score. Move the entire text 20 pixels below current positio
User prompt
Move the high score to the bottom left of the screen
User prompt
Make the button and text bigger and mo e the button To the bottom right of the screen
User prompt
Change leaderboard icon to a button that says Leaderboard in capital letters
User prompt
High score is not visible
User prompt
The high score is not visible. Make ot 100px from screen bottom
User prompt
High score is not visible. Let it be on the bottom left just below the boundary line
User prompt
Move the Users high score to the bottom right of the screen. Label it Your high score:
User prompt
Move the top line 300px from acreen top
User prompt
Let the top line demarcating, the top HUD be visible. Also elements like the lives and the leaderboard button, let them be visible in the HUD.
User prompt
Let the top HUD be opaque to hide fruits behind it.
User prompt
Let the rop hud be opaque ao that druits disappear behind it.
User prompt
Let the top line be 200px from top of acreen and bottom li e 200px from bottom
User prompt
Draw a thick line below the hud at the top and 100 px from the bottom to demarcate the play area
User prompt
Let user have extra lives. Start with three lives at beginning of game. Clicking a bomb takes a life. Show how many lives left as small red hearts
User prompt
Show level 2 boss when user gets to 50
User prompt
New level starts as soon as a boss is defeated
User prompt
Please fix the bug: 'levelText.style is undefined' in or related to this line: 'levelText.style.size = 180;' Line Number: 714
User prompt
Show Level label when a new level begins.
User prompt
Let boss 2 appear when user has received 50 points.
User prompt
Make the bosses very large
User prompt
Make the bosses bigger versions of the fruit. Make the 300 px width
User prompt
Let there be 4 levels each with its own boss which is a larger version of the most recently introduced fruit for that level. Write the Level label and number at the beginning of each level e.g Level 1, Level 2 etc
User prompt
use the players upit username for the leaderboard if they are logged in, if not, use Anon ↪💡 Consider importing and using the following plugins: @upit/storage.v1
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var Blade = Container.expand(function () { var self = Container.call(this); self.active = false; self.points = []; self.maxPoints = 10; self.trail = []; for (var i = 0; i < self.maxPoints; i++) { var trailPart = self.attachAsset('blade', { anchorX: 0.5, anchorY: 0.5, alpha: 0 }); self.trail.push(trailPart); } self.update = function () { // Update trail visuals for (var i = 0; i < self.trail.length; i++) { if (i < self.points.length) { var point = self.points[i]; var trailPart = self.trail[i]; trailPart.x = point.x; trailPart.y = point.y; trailPart.alpha = 0; // Keep blade invisible if (i > 0) { var prevPoint = self.points[i - 1]; var angle = Math.atan2(point.y - prevPoint.y, point.x - prevPoint.x); trailPart.rotation = angle; } } else { self.trail[i].alpha = 0; } } }; self.addPoint = function (x, y) { self.points.unshift({ x: x, y: y }); if (self.points.length > self.maxPoints) { self.points.pop(); } }; self.reset = function () { self.points = []; self.active = false; for (var i = 0; i < self.trail.length; i++) { self.trail[i].alpha = 0; } }; return self; }); var Boss = Container.expand(function (level) { var self = Container.call(this); // Boss properties self.level = level || 1; self.health = 5 + self.level; // Health increases with level self.maxHealth = self.health; self.width = 800; self.height = 800; self.active = false; self.attackTimer = 0; self.attackInterval = 3000 - self.level * 250; // Attacks more frequently with higher levels // Determine boss type based on level var bossType = BOSS_FRUIT_TYPES[self.level - 1] || 'strawberry'; // Create boss visual var bossGraphic = self.attachAsset(bossType, { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2 }); // Health bar background var healthBarBg = new Container(); healthBarBg.x = -200; healthBarBg.y = -450; var healthBarBack = LK.getAsset('blade', { anchorX: 0, anchorY: 0.5, width: 400, height: 30 }); healthBarBack.tint = 0x333333; // Health bar fill var healthBarFill = LK.getAsset('blade', { anchorX: 0, anchorY: 0.5, width: 400, height: 30 }); healthBarFill.tint = 0xFF0000; healthBarBg.addChild(healthBarBack); healthBarBg.addChild(healthBarFill); self.addChild(healthBarBg); self.healthBar = healthBarFill; // Boss movement self.vx = 2 + self.level * 0.5; // Speed increases with level self.targetX = GAME_WIDTH / 2; self.activate = function () { self.active = true; self.health = self.maxHealth; self.x = GAME_WIDTH / 2; self.y = GAME_HEIGHT / 3; self.updateHealthBar(); }; self.updateHealthBar = function () { self.healthBar.width = self.health / self.maxHealth * 400; }; self.hit = function () { if (!self.active) { return; } self.health--; self.updateHealthBar(); // Flash the boss red bossGraphic.tint = 0xFF0000; LK.setTimeout(function () { bossGraphic.tint = 0xFFFFFF; }, 200); // Check if boss is defeated if (self.health <= 0) { self.defeat(); return true; } return false; }; self.defeat = function () { self.active = false; // Make the health bar transparent healthBarBg.alpha = 0; // Create explosion effect bossGraphic.tint = 0xFFFFFF; tween(bossGraphic, { alpha: 0, scaleX: 3, scaleY: 3, rotation: Math.PI * 2 }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { // Add bonus points (increased for higher level bosses) var bonus = 25 * self.level; LK.setScore(LK.getScore() + bonus); scoreTxt.setText(LK.getScore()); LK.effects.flashScreen(0x00FF00, 500); } }); // Play explosion sound LK.getSound('explosion').play(); }; self.throwFruit = function () { if (!self.active) { return; } // Launch multiple bombs at the player var bombCount = Math.floor(Math.random() * self.level) + 1; // More bombs at higher levels for (var i = 0; i < bombCount; i++) { var fruit = new Fruit('bomb'); // Generate random position on the boss perimeter var spawnAngle = Math.random() * Math.PI * 2; // Full 360 degrees var spawnRadius = self.width / 3; // Radius to spawn from (edge of boss) // Position the bomb on the perimeter fruit.x = self.x + Math.cos(spawnAngle) * spawnRadius; fruit.y = self.y + Math.sin(spawnAngle) * spawnRadius; // Aim outward from the spawn point with spread var angle = spawnAngle + Math.PI + (Math.random() - 0.5); // Outward direction with randomness var speed = 3 + Math.random() * 2 + self.level * 0.5; // Faster bombs at higher levels fruit.vx = Math.cos(angle) * speed; fruit.vy = Math.sin(angle) * speed; game.addChild(fruit); fruits.push(fruit); } }; self.update = function (delta) { if (!self.active) { return; } // Move boss back and forth if (Math.abs(self.x - self.targetX) < 10) { self.targetX = Math.random() * (GAME_WIDTH - 400) + 200; } var dirX = self.targetX - self.x; self.x += dirX / Math.abs(dirX) * self.vx; // Attack on timer var currentTime = Date.now(); if (currentTime >= self.attackTimer) { self.throwFruit(); self.attackTimer = currentTime + self.attackInterval; } }; self.down = function (x, y, obj) { // Allow clicking on boss to damage it if (self.active) { self.hit(); } }; return self; }); var Fruit = Container.expand(function (type) { var self = Container.call(this); self.type = type || 'apple'; self.sliced = false; self.width = 0; self.height = 0; self.points = 0; self.baseSpeed = 0; var fruitGraphics; switch (self.type) { case 'watermelon': self.width = 480; self.height = 480; self.points = 5; self.baseSpeed = 1.6; // Faster base speed break; case 'apple': self.width = 360; self.height = 360; self.points = 4; self.baseSpeed = 1.7; // Faster base speed break; case 'orange': self.width = 320; self.height = 320; self.points = 3; self.baseSpeed = 1.8; // Faster base speed break; case 'kiwi': self.width = 240; self.height = 240; self.points = 2; self.baseSpeed = 2.0; // Faster base speed break; case 'strawberry': self.width = 200; self.height = 200; self.points = 1; self.baseSpeed = 2.2; // Faster base speed break; case 'bomb': self.width = 320; self.height = 320; self.points = -10; self.baseSpeed = 1.7; // Faster base speed break; } fruitGraphics = self.attachAsset(self.type, { anchorX: 0.5, anchorY: 0.5 }); self.vx = 0; self.vy = 0; self.gravity = 0.01; // Reduced gravity to make fruits go higher self.rotationSpeed = (Math.random() - 0.5) * 0.018; // Slightly faster rotation self.init = function (x, y, direction) { self.x = x; self.y = y; var angle = direction * (Math.PI / 4) + Math.random() * Math.PI / 8 - Math.PI / 16; var currentLevel = Math.floor(LK.getScore() / 50) + 1; var levelMultiplier = 1 + (currentLevel - 1) * 0.1; // 10% increase per level var speed = (self.baseSpeed + Math.random() * 0.8) * levelMultiplier; // Further reduced random speed component self.vx = Math.cos(angle) * speed * 1.15; // Slightly faster horizontal movement self.vy = -Math.sin(angle) * speed - 8; // Higher initial upward velocity }; self.slice = function () { if (self.sliced || self.type === 'bomb') { return; } self.sliced = true; // Create explosive flash effect fruitGraphics.tint = 0xFFFFFF; fruitGraphics.alpha = 1; // Animate explosive flash effect with scaling tween(fruitGraphics, { alpha: 0, scaleX: 1.5, scaleY: 1.5 }, { duration: 300, easing: tween.easeOut, onUpdate: function onUpdate(progress) { // Create a pulsing effect with rotation during explosion fruitGraphics.rotation += 0.1; }, onFinish: function onFinish() { // Clean up after animation fruitGraphics.tint = 0xFFFFFF; fruitGraphics.scaleX = 1; fruitGraphics.scaleY = 1; } }); // Play slice sound LK.getSound('slice').play(); return self.points; }; self.down = function (x, y, obj) { if (!self.sliced) { // Slice the fruit when clicked var points = self.slice(); // Check if it's a bomb if (self.type === 'bomb') { // Game over when clicking a bomb LK.getSound('explosion').play(); LK.effects.flashScreen(0xFF0000, 800); // Update high score if current score is higher if (LK.getScore() > highScore) { highScore = LK.getScore(); storage.highScore = highScore; } // Add score to global leaderboard addScoreToLeaderboard(LK.getScore()); // Pass the current score and high score to game over display LK.showGameOver({ score: LK.getScore(), highScore: highScore }); return; } // Add points to score LK.setScore(LK.getScore() + points); scoreTxt.setText(LK.getScore()); // Update combo comboCount++; comboTimer = Date.now() + comboTimeout; } }; self.update = function () { if (!self.sliced) { // Update whole fruit self.vy += self.gravity; self.x += self.vx; self.y += self.vy; self.rotation += self.rotationSpeed; // Bounce off walls if not sliced if (self.x < self.width / 2 && self.vx < 0) { self.vx = -self.vx * 0.8; // Bounce with some energy loss self.x = self.width / 2; } if (self.x > GAME_WIDTH - self.width / 2 && self.vx > 0) { self.vx = -self.vx * 0.8; // Bounce with some energy loss self.x = GAME_WIDTH - self.width / 2; } } else { // No update for sliced fruit since we're just flashing and fading them } }; self.isOffScreen = function () { return self.y > 2732 + self.height || self.x > GAME_WIDTH + self.width; }; return self; }); var Leaderboard = Container.expand(function () { var self = Container.call(this); self.visible = false; // Background panel var panel = self.attachAsset('blade', { anchorX: 0.5, anchorY: 0.5, width: 1500, height: 1800 }); panel.tint = 0x2c3e50; panel.alpha = 0.9; // Title var title = new Text2('GLOBAL LEADERBOARD', { size: 100, fill: 0xFFFFFF }); title.anchor.set(0.5, 0); title.y = -800; self.addChild(title); // Scores container var scoresContainer = new Container(); scoresContainer.y = -650; self.addChild(scoresContainer); self.scoresContainer = scoresContainer; // Close button var closeBtn = self.attachAsset('blade', { anchorX: 0.5, anchorY: 0.5, width: 80, height: 80 }); closeBtn.tint = 0xFF0000; closeBtn.x = 700; closeBtn.y = -800; // X symbol on close button var closeX1 = self.attachAsset('blade', { anchorX: 0.5, anchorY: 0.5, width: 40, height: 8 }); closeX1.tint = 0xFFFFFF; closeX1.rotation = Math.PI / 4; closeX1.x = 700; closeX1.y = -800; var closeX2 = self.attachAsset('blade', { anchorX: 0.5, anchorY: 0.5, width: 40, height: 8 }); closeX2.tint = 0xFFFFFF; closeX2.rotation = -Math.PI / 4; closeX2.x = 700; closeX2.y = -800; // Close button interaction closeBtn.interactive = true; closeBtn.down = function (x, y, obj) { self.hide(); }; // Show leaderboard self.show = function (scores) { self.visible = true; self.updateScores(scores); }; // Hide leaderboard self.hide = function () { self.visible = false; }; // Update scores display self.updateScores = function (scores) { // Clear existing score entries while (scoresContainer.children.length > 0) { scoresContainer.removeChildAt(0); } // Add score entries for (var i = 0; i < scores.length; i++) { var entry = scores[i]; var yPos = i * 120; // Rank var rank = new Text2(i + 1 + '.', { size: 80, fill: 0xFFFFFF }); rank.anchor.set(1, 0); rank.x = -600; rank.y = yPos; scoresContainer.addChild(rank); // Username var username = entry.username || "Player"; var usernameText = new Text2(username, { size: 60, fill: 0xFFFFFF }); usernameText.anchor.set(0, 0); usernameText.x = -500; usernameText.y = yPos; scoresContainer.addChild(usernameText); // Score value var scoreText = new Text2(entry.score.toString(), { size: 80, fill: 0xFFD700 }); scoreText.anchor.set(0, 0); scoreText.x = 0; scoreText.y = yPos; scoresContainer.addChild(scoreText); } // Add message if no scores if (scores.length === 0) { var noScores = new Text2("No scores yet!", { size: 80, fill: 0xFFFFFF }); noScores.anchor.set(0.5, 0); noScores.y = 100; scoresContainer.addChild(noScores); } }; return self; }); var LeaderboardButton = Container.expand(function () { var self = Container.call(this); // Create button background var buttonBg = self.attachAsset('blade', { anchorX: 0.5, anchorY: 0.5, width: 80, height: 80 }); buttonBg.tint = 0x3498db; // Create button icon (simple trophy shape) var icon = self.attachAsset('blade', { anchorX: 0.5, anchorY: 0.5, width: 40, height: 50 }); icon.tint = 0xFFD700; icon.y = -5; // Create button base var base = self.attachAsset('blade', { anchorX: 0.5, anchorY: 0.5, width: 30, height: 10 }); base.tint = 0xFFD700; base.y = 25; // Button interaction self.down = function (x, y, obj) { // Scale down effect on press tween(self, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); // Show leaderboard showLeaderboard(); }; self.up = function (x, y, obj) { // Scale back to normal on release tween(self, { scaleX: 1, scaleY: 1 }, { duration: 100 }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x3498DB }); /**** * Game Code ****/ // Game constants var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var SPAWN_INTERVAL_MIN = 1000; // Decreased spawn interval minimum for more frequent spawning var SPAWN_INTERVAL_MAX = 2000; // Decreased spawn interval maximum for more frequent spawning var SPAWN_COUNT_MIN = 1; var SPAWN_COUNT_MAX = 2; // Increased to spawn more fruits at once var FRUIT_TYPES = ['watermelon', 'apple', 'orange', 'kiwi', 'strawberry']; var BOSS_FRUIT_TYPES = ['strawberry', 'kiwi', 'orange', 'apple']; // Boss fruit for each level var LEVEL_THRESHOLDS = [5, 50, 150, 300]; // Score thresholds for each level boss var LEVEL_FRUITS = [['strawberry'], // Level 1 fruits ['strawberry', 'kiwi'], // Level 2 fruits ['strawberry', 'kiwi', 'orange'], // Level 3 fruits ['strawberry', 'kiwi', 'orange', 'apple'] // Level 4 fruits ]; var BOMB_PROBABILITY = 0.2; // Increased bomb probability // Game variables var fruits = []; var blade = null; var boss = null; var lastSpawnTime = 0; var nextSpawnTime = 0; var gameActive = true; var comboCount = 0; var comboTimer = 0; var comboTimeout = 1000; // ms to reset combo var currentLevel = 1; var bossActivated = false; var nextLevelNotified = false; var showingLevelText = false; var levelTextTimer = 0; var levelText; // Level notification text var missedFruits = 0; // Counter for missed fruits var missedText; // Text to display missed count var highScore = storage.highScore || 0; // Get high score from storage or default to 0 var highScoreText; // Text to display high score var leaderboardButton; // Button to open leaderboard var leaderboard; // Leaderboard UI component // Parse leaderboard scores from storage or use empty array if none exists var leaderboardScores = []; if (storage.leaderboardScores) { var scoresArray = storage.leaderboardScores.split(';'); for (var i = 0; i < scoresArray.length; i++) { if (scoresArray[i]) { var parts = scoresArray[i].split(','); var scoreObj = { score: parseInt(parts[0]) }; if (parts.length > 1) { scoreObj.username = parts[1]; } leaderboardScores.push(scoreObj); } } } // Global leaderboard data var playerName = storage.playerName || "Player"; // Get saved player name or use default // UI elements var scoreTxt; var comboTxt; function setupGame() { // Prompt for player name if not already stored if (!storage.playerName) { var defaultName = "Player"; // Skip popup for now and just use default name // LK.showPopup is not available in the current version storage.playerName = defaultName; playerName = defaultName; } // Create blade blade = game.addChild(new Blade()); // Create boss but don't activate it yet boss = game.addChild(new Boss(currentLevel)); // Set up score display scoreTxt = new Text2('0', { size: 100, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); scoreTxt.y = 30; LK.gui.top.addChild(scoreTxt); // Set up combo display comboTxt = new Text2('', { size: 60, fill: 0xFFFF00 }); comboTxt.anchor.set(0.5, 0); comboTxt.y = 140; comboTxt.alpha = 0; LK.gui.top.addChild(comboTxt); // Set up level text display levelText = new Text2('Level 1', { size: 120, fill: 0xFFFFFF }); levelText.anchor.set(0.5, 0.5); levelText.x = GAME_WIDTH / 2; levelText.y = GAME_HEIGHT / 2; levelText.alpha = 0; game.addChild(levelText); // Set up missed fruits display missedText = new Text2('Missed: 0/10', { size: 60, fill: 0xFF0000 }); missedText.anchor.set(0, 0); missedText.x = 50; missedText.y = 30; LK.gui.topLeft.addChild(missedText); // Set up high score display highScoreText = new Text2('High Score: ' + highScore, { size: 60, fill: 0xFFFFFF }); highScoreText.anchor.set(0, 0); highScoreText.x = 50; highScoreText.y = 100; // Position below the missed counter LK.gui.topLeft.addChild(highScoreText); // Set up leaderboard button leaderboardButton = new LeaderboardButton(); leaderboardButton.x = GAME_WIDTH - 80; leaderboardButton.y = 80; game.addChild(leaderboardButton); // Create and position leaderboard UI leaderboard = new Leaderboard(); leaderboard.x = GAME_WIDTH / 2; leaderboard.y = GAME_HEIGHT / 2; leaderboard.visible = false; game.addChild(leaderboard); // Set initial spawn time nextSpawnTime = Date.now() + Math.random() * (SPAWN_INTERVAL_MAX - SPAWN_INTERVAL_MIN) + SPAWN_INTERVAL_MIN; // Play background music LK.playMusic('gameMusic'); // Reset level tracking currentLevel = 1; bossActivated = false; nextLevelNotified = false; LK.setScore(0); missedFruits = 0; // Show level 1 text at start showLevelText(1); } // Function to display level text function showLevelText(level) { levelText.setText('Level ' + level); levelText.alpha = 0; showingLevelText = true; // Animate the level text tween(levelText, { alpha: 1 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { // Hold the text visible for a moment levelTextTimer = Date.now() + 2000; } }); } function spawnFruits() { var count = Math.floor(Math.random() * (SPAWN_COUNT_MAX - SPAWN_COUNT_MIN + 1)) + SPAWN_COUNT_MIN; // Get appropriate fruit types for current level var availableFruits = LEVEL_FRUITS[currentLevel - 1] || ['strawberry']; for (var i = 0; i < count; i++) { var isBomb = Math.random() < BOMB_PROBABILITY; var type = isBomb ? 'bomb' : availableFruits[Math.floor(Math.random() * availableFruits.length)]; var fruit = new Fruit(type); // Determine flight pattern var pattern = Math.random(); if (pattern < 0.5) { // Horizontal flight from left to right var x = -fruit.width; var y = Math.random() * (GAME_HEIGHT / 3) + 300; // Higher position range fruit.x = x; fruit.y = y; fruit.vx = fruit.baseSpeed + Math.random() * 2.5; // Slightly faster fruit.vy = -Math.random() * 2; // Add slight upward movement } else { // Vertical drop var x = Math.random() * (GAME_WIDTH - 200) + 100; var direction = Math.random(); // Random direction between 0 and 1 fruit.init(x, GAME_HEIGHT, direction); } game.addChild(fruit); fruits.push(fruit); } // Schedule next spawn nextSpawnTime = Date.now() + Math.random() * (SPAWN_INTERVAL_MAX - SPAWN_INTERVAL_MIN) + SPAWN_INTERVAL_MIN; } function updateCombo() { if (comboCount > 1) { comboTxt.setText('COMBO x' + comboCount + '!'); comboTxt.alpha = 1; // Add combo bonus points LK.setScore(LK.getScore() + comboCount * 2); // Play combo sound LK.getSound('combo').play(); // Animate combo text tween(comboTxt, { alpha: 0 }, { duration: 1000, easing: tween.easeOut }); } comboCount = 0; } function handleBladeCollisions() { if (!blade.active || blade.points.length < 2) { return; } var startPoint = blade.points[0]; var endPoint = blade.points[1]; // Check boss collision if active if (boss && boss.active && lineIntersectsCircle(startPoint.x, startPoint.y, endPoint.x, endPoint.y, boss.x, boss.y, boss.width / 3)) { // Hit the boss var defeated = boss.hit(); // Play slice sound LK.getSound('slice').play(); // Update combo comboCount++; comboTimer = Date.now() + comboTimeout; } for (var i = 0; i < fruits.length; i++) { var fruit = fruits[i]; if (!fruit.sliced && lineIntersectsCircle(startPoint.x, startPoint.y, endPoint.x, endPoint.y, fruit.x, fruit.y, fruit.width / 2)) { if (fruit.type === 'bomb') { // Game over when hitting a bomb LK.getSound('explosion').play(); LK.effects.flashScreen(0xFF0000, 800); // Update high score if current score is higher if (LK.getScore() > highScore) { highScore = LK.getScore(); storage.highScore = highScore; } // Add score to global leaderboard addScoreToLeaderboard(LK.getScore()); // Pass the current score and high score to game over display LK.showGameOver({ score: LK.getScore(), highScore: highScore }); return; } // Slice the fruit var points = fruit.slice(); LK.setScore(LK.getScore() + points); scoreTxt.setText(LK.getScore()); // Play slice sound LK.getSound('slice').play(); // Update combo comboCount++; comboTimer = Date.now() + comboTimeout; } } } function lineIntersectsCircle(x1, y1, x2, y2, cx, cy, r) { // Find the closest point on the line segment to the circle center var dx = x2 - x1; var dy = y2 - y1; var len = Math.sqrt(dx * dx + dy * dy); // Normalize direction vector dx /= len; dy /= len; // Vector from line start to circle center var vx = cx - x1; var vy = cy - y1; // Project this vector onto the line direction var projection = vx * dx + vy * dy; // Clamp projection to line segment projection = Math.max(0, Math.min(len, projection)); // Find the closest point on the line segment var closestX = x1 + projection * dx; var closestY = y1 + projection * dy; // Check if this point is within the circle var distanceSquared = (cx - closestX) * (cx - closestX) + (cy - closestY) * (cy - closestY); return distanceSquared <= r * r; } // Show the leaderboard UI function showLeaderboard() { if (leaderboard) { leaderboard.show(leaderboardScores); } } // Add a score to the leaderboard function addScoreToLeaderboard(score) { // Only add score if it's greater than 0 if (score <= 0) { return; } // Add new score to leaderboard with Upit username or 'Anon' var username = LK.getUptUsername ? LK.getUptUsername() : 'Anon'; leaderboardScores.push({ score: score, username: username }); // Sort leaderboard by score (highest first) leaderboardScores.sort(function (a, b) { return b.score - a.score; }); // Limit to top 10 scores if (leaderboardScores.length > 10) { leaderboardScores = leaderboardScores.slice(0, 10); } // Save to storage - convert to simple string format to avoid undefined JSON error var scoresString = ''; for (var i = 0; i < leaderboardScores.length; i++) { scoresString += leaderboardScores[i].score + "," + (leaderboardScores[i].username || "Player"); if (i < leaderboardScores.length - 1) { scoresString += ';'; } } storage.leaderboardScores = scoresString; } ; // Game update function game.update = function () { var currentTime = Date.now(); // Handle level text animation if (showingLevelText && currentTime > levelTextTimer && levelText.alpha > 0) { tween(levelText, { alpha: 0 }, { duration: 500, easing: tween.easeIn, onFinish: function onFinish() { showingLevelText = false; } }); } // Check if we should activate the boss fight based on score if (currentLevel <= 4 && LK.getScore() >= LEVEL_THRESHOLDS[currentLevel - 1] && !bossActivated && !nextLevelNotified) { bossActivated = true; // Create a new boss for the current level if (boss) { boss.destroy(); } boss = game.addChild(new Boss(currentLevel)); boss.activate(); // Clear existing fruits during boss transition for (var i = fruits.length - 1; i >= 0; i--) { fruits[i].destroy(); fruits.splice(i, 1); } } // Only spawn normal fruits if we're not in a boss fight if (currentTime >= nextSpawnTime && (!bossActivated || !boss.active)) { spawnFruits(); } // Update all fruits for (var i = fruits.length - 1; i >= 0; i--) { var fruit = fruits[i]; fruit.update(); // Remove fruits that are off-screen if (fruit.isOffScreen()) { // Only count missed fruits that aren't bombs or already sliced if (!fruit.sliced && fruit.type !== 'bomb') { missedFruits++; missedText.setText('Missed: ' + missedFruits + '/10'); // Game over if 10 fruits are missed if (missedFruits >= 10) { LK.effects.flashScreen(0xFF0000, 800); // Update high score if current score is higher if (LK.getScore() > highScore) { highScore = LK.getScore(); storage.highScore = highScore; } // Add score to global leaderboard addScoreToLeaderboard(LK.getScore()); // Pass the current score and high score to game over display LK.showGameOver({ score: LK.getScore(), highScore: highScore }); } } fruit.destroy(); fruits.splice(i, 1); } } // Check for blade collisions handleBladeCollisions(); // Update blade blade.update(); // Update boss if active if (boss && boss.active) { boss.update(1 / 60); // Pass approximate delta time } // If boss was defeated, move to next level if (bossActivated && boss && !boss.active) { bossActivated = false; nextLevelNotified = false; // Move to next level if we haven't reached level 4 yet if (currentLevel < 4) { currentLevel++; // Show level notification showLevelText(currentLevel); } else if (currentLevel === 4) { // Player has beaten all levels LK.effects.flashScreen(0x00FF00, 800); // Show "You Win" screen after completing all levels if (LK.getScore() > highScore) { highScore = LK.getScore(); storage.highScore = highScore; } // Add score to global leaderboard addScoreToLeaderboard(LK.getScore()); // Show you win screen LK.showYouWin({ score: LK.getScore(), highScore: highScore }); } } // Check combo timer if (comboCount > 0 && Date.now() > comboTimer) { updateCombo(); } }; // Handle touch/mouse events game.down = function (x, y, obj) { blade.active = true; blade.reset(); blade.addPoint(x, y); }; game.move = function (x, y, obj) { if (blade.active) { blade.addPoint(x, y); handleBladeCollisions(); } }; game.up = function (x, y, obj) { blade.active = false; }; // Start the game setupGame();
===================================================================
--- original.js
+++ change.js
@@ -57,20 +57,23 @@
}
};
return self;
});
-var Boss = Container.expand(function () {
+var Boss = Container.expand(function (level) {
var self = Container.call(this);
// Boss properties
- self.health = 5;
- self.maxHealth = 5;
+ self.level = level || 1;
+ self.health = 5 + self.level; // Health increases with level
+ self.maxHealth = self.health;
self.width = 800;
self.height = 800;
self.active = false;
self.attackTimer = 0;
- self.attackInterval = 3000; // Increased time between attacks for less frequent bombs
+ self.attackInterval = 3000 - self.level * 250; // Attacks more frequently with higher levels
+ // Determine boss type based on level
+ var bossType = BOSS_FRUIT_TYPES[self.level - 1] || 'strawberry';
// Create boss visual
- var bossGraphic = self.attachAsset('watermelon', {
+ var bossGraphic = self.attachAsset(bossType, {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
@@ -98,9 +101,9 @@
healthBarBg.addChild(healthBarFill);
self.addChild(healthBarBg);
self.healthBar = healthBarFill;
// Boss movement
- self.vx = 2;
+ self.vx = 2 + self.level * 0.5; // Speed increases with level
self.targetX = GAME_WIDTH / 2;
self.activate = function () {
self.active = true;
self.health = self.maxHealth;
@@ -143,10 +146,11 @@
}, {
duration: 1000,
easing: tween.easeOut,
onFinish: function onFinish() {
- // Add bonus points
- LK.setScore(LK.getScore() + 25);
+ // Add bonus points (increased for higher level bosses)
+ var bonus = 25 * self.level;
+ LK.setScore(LK.getScore() + bonus);
scoreTxt.setText(LK.getScore());
LK.effects.flashScreen(0x00FF00, 500);
}
});
@@ -157,9 +161,9 @@
if (!self.active) {
return;
}
// Launch multiple bombs at the player
- var bombCount = Math.floor(Math.random() * 2) + 1; // Spawn 1-2 bombs at once
+ var bombCount = Math.floor(Math.random() * self.level) + 1; // More bombs at higher levels
for (var i = 0; i < bombCount; i++) {
var fruit = new Fruit('bomb');
// Generate random position on the boss perimeter
var spawnAngle = Math.random() * Math.PI * 2; // Full 360 degrees
@@ -168,9 +172,9 @@
fruit.x = self.x + Math.cos(spawnAngle) * spawnRadius;
fruit.y = self.y + Math.sin(spawnAngle) * spawnRadius;
// Aim outward from the spawn point with spread
var angle = spawnAngle + Math.PI + (Math.random() - 0.5); // Outward direction with randomness
- var speed = 3 + Math.random() * 2; // Faster bombs
+ var speed = 3 + Math.random() * 2 + self.level * 0.5; // Faster bombs at higher levels
fruit.vx = Math.cos(angle) * speed;
fruit.vy = Math.sin(angle) * speed;
game.addChild(fruit);
fruits.push(fruit);
@@ -544,8 +548,18 @@
var SPAWN_INTERVAL_MAX = 2000; // Decreased spawn interval maximum for more frequent spawning
var SPAWN_COUNT_MIN = 1;
var SPAWN_COUNT_MAX = 2; // Increased to spawn more fruits at once
var FRUIT_TYPES = ['watermelon', 'apple', 'orange', 'kiwi', 'strawberry'];
+var BOSS_FRUIT_TYPES = ['strawberry', 'kiwi', 'orange', 'apple']; // Boss fruit for each level
+var LEVEL_THRESHOLDS = [5, 50, 150, 300]; // Score thresholds for each level boss
+var LEVEL_FRUITS = [['strawberry'],
+// Level 1 fruits
+['strawberry', 'kiwi'],
+// Level 2 fruits
+['strawberry', 'kiwi', 'orange'],
+// Level 3 fruits
+['strawberry', 'kiwi', 'orange', 'apple'] // Level 4 fruits
+];
var BOMB_PROBABILITY = 0.2; // Increased bomb probability
// Game variables
var fruits = [];
var blade = null;
@@ -557,9 +571,12 @@
var comboTimer = 0;
var comboTimeout = 1000; // ms to reset combo
var currentLevel = 1;
var bossActivated = false;
-var levelThreshold = 5; // Points needed to trigger boss in level 1
+var nextLevelNotified = false;
+var showingLevelText = false;
+var levelTextTimer = 0;
+var levelText; // Level notification text
var missedFruits = 0; // Counter for missed fruits
var missedText; // Text to display missed count
var highScore = storage.highScore || 0; // Get high score from storage or default to 0
var highScoreText; // Text to display high score
@@ -597,9 +614,9 @@
}
// Create blade
blade = game.addChild(new Blade());
// Create boss but don't activate it yet
- boss = game.addChild(new Boss());
+ boss = game.addChild(new Boss(currentLevel));
// Set up score display
scoreTxt = new Text2('0', {
size: 100,
fill: 0xFFFFFF
@@ -615,8 +632,18 @@
comboTxt.anchor.set(0.5, 0);
comboTxt.y = 140;
comboTxt.alpha = 0;
LK.gui.top.addChild(comboTxt);
+ // Set up level text display
+ levelText = new Text2('Level 1', {
+ size: 120,
+ fill: 0xFFFFFF
+ });
+ levelText.anchor.set(0.5, 0.5);
+ levelText.x = GAME_WIDTH / 2;
+ levelText.y = GAME_HEIGHT / 2;
+ levelText.alpha = 0;
+ game.addChild(levelText);
// Set up missed fruits display
missedText = new Text2('Missed: 0/10', {
size: 60,
fill: 0xFF0000
@@ -651,16 +678,38 @@
LK.playMusic('gameMusic');
// Reset level tracking
currentLevel = 1;
bossActivated = false;
+ nextLevelNotified = false;
LK.setScore(0);
missedFruits = 0;
+ // Show level 1 text at start
+ showLevelText(1);
}
+// Function to display level text
+function showLevelText(level) {
+ levelText.setText('Level ' + level);
+ levelText.alpha = 0;
+ showingLevelText = true;
+ // Animate the level text
+ tween(levelText, {
+ alpha: 1
+ }, {
+ duration: 500,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ // Hold the text visible for a moment
+ levelTextTimer = Date.now() + 2000;
+ }
+ });
+}
function spawnFruits() {
var count = Math.floor(Math.random() * (SPAWN_COUNT_MAX - SPAWN_COUNT_MIN + 1)) + SPAWN_COUNT_MIN;
+ // Get appropriate fruit types for current level
+ var availableFruits = LEVEL_FRUITS[currentLevel - 1] || ['strawberry'];
for (var i = 0; i < count; i++) {
var isBomb = Math.random() < BOMB_PROBABILITY;
- var type = isBomb ? 'bomb' : FRUIT_TYPES[Math.floor(Math.random() * FRUIT_TYPES.length)];
+ var type = isBomb ? 'bomb' : availableFruits[Math.floor(Math.random() * availableFruits.length)];
var fruit = new Fruit(type);
// Determine flight pattern
var pattern = Math.random();
if (pattern < 0.5) {
@@ -810,20 +859,37 @@
}
;
// Game update function
game.update = function () {
+ var currentTime = Date.now();
+ // Handle level text animation
+ if (showingLevelText && currentTime > levelTextTimer && levelText.alpha > 0) {
+ tween(levelText, {
+ alpha: 0
+ }, {
+ duration: 500,
+ easing: tween.easeIn,
+ onFinish: function onFinish() {
+ showingLevelText = false;
+ }
+ });
+ }
// Check if we should activate the boss fight based on score
- if (currentLevel === 1 && LK.getScore() >= levelThreshold && !bossActivated) {
+ if (currentLevel <= 4 && LK.getScore() >= LEVEL_THRESHOLDS[currentLevel - 1] && !bossActivated && !nextLevelNotified) {
bossActivated = true;
+ // Create a new boss for the current level
+ if (boss) {
+ boss.destroy();
+ }
+ boss = game.addChild(new Boss(currentLevel));
boss.activate();
// Clear existing fruits during boss transition
for (var i = fruits.length - 1; i >= 0; i--) {
fruits[i].destroy();
fruits.splice(i, 1);
}
}
// Only spawn normal fruits if we're not in a boss fight
- var currentTime = Date.now();
if (currentTime >= nextSpawnTime && (!bossActivated || !boss.active)) {
spawnFruits();
}
// Update all fruits
@@ -867,11 +933,30 @@
}
// If boss was defeated, move to next level
if (bossActivated && boss && !boss.active) {
bossActivated = false;
- currentLevel++;
- // Increase level threshold for next boss
- levelThreshold = levelThreshold + 50;
+ nextLevelNotified = false;
+ // Move to next level if we haven't reached level 4 yet
+ if (currentLevel < 4) {
+ currentLevel++;
+ // Show level notification
+ showLevelText(currentLevel);
+ } else if (currentLevel === 4) {
+ // Player has beaten all levels
+ LK.effects.flashScreen(0x00FF00, 800);
+ // Show "You Win" screen after completing all levels
+ if (LK.getScore() > highScore) {
+ highScore = LK.getScore();
+ storage.highScore = highScore;
+ }
+ // Add score to global leaderboard
+ addScoreToLeaderboard(LK.getScore());
+ // Show you win screen
+ LK.showYouWin({
+ score: LK.getScore(),
+ highScore: highScore
+ });
+ }
}
// Check combo timer
if (comboCount > 0 && Date.now() > comboTimer) {
updateCombo();
red bomb. In-Game asset. 2d. High contrast. No shadows
Head of pepe meme. each face shaped as a marble shaped face made in blender 3D. In-Game asset. 2d. High contrast. No shadows
Head of doge meme. face shaped as a marble shaped face made in blender 3D. In-Game asset. 2d. High contrast. No shadows
Head of troll face meme. face shaped as a marble shaped face made in blender 3D. In-Game asset. 2d. High contrast. No shadows
Head of think smart guy meme. face shaped as a marble shaped face made in blender 3D. In-Game asset. 2d. High contrast. No shadows
Head of white y u no meme. face shaped as a marble shaped face made in blender 3D. In-Game asset. 2d. High contrast. No shadows
Explosion. In-Game asset. 2d. High contrast. No shadows
Clock. In-Game asset. 3d. High contrast. No shadows
Red Heart. In-Game asset. 3d. High contrast. No shadows
gattling gun. In-Game asset. 2d. High contrast. No shadows