User prompt
Add explosion effect when the ball hits the power ups
User prompt
create a background asset and assign it to the game
User prompt
create an asset for combobreak and beatmiss and assign that sound effects to the game
User prompt
now sound effects assets and assign it to the game as well
User prompt
remove beatmiss and combobreak related in the code
User prompt
remove beatmiss and combobreak and beathit and powerupcollect in the code
User prompt
when ball touches beattile create and set some sound effect to play
Code edit (1 edits merged)
Please save this source code
User prompt
Music Bounce: Rhythm Runner
Initial prompt
Music Bounce 🎵⚡ A fun rhythm-based game where players control a bouncing ball that moves to the beat of the music. The goal is to land on special tiles in sync with the rhythm to keep the beat going and score points! 🎮 Gameplay Mechanics: The ball bounces automatically to the rhythm. Players tap/click to move left or right to land on the correct beat tiles. Missing a tile breaks the combo; hitting multiple in a row increases the score. Power-ups include: Speed Boost 🚀 – Makes the ball faster for a short time. Double Score ⭐ – Doubles points for a limited duration. Slow Motion ⏳ – Slows time, making it easier to hit tiles. The level gets harder as the music speeds up! 🎶 Game Features: Different music genres (pop, techno, classical, lo-fi, etc.). Unlockable backgrounds & ball skins. Procedural level generation based on music beats. High-score leaderboard & combo streak challenges! 🎨 Art & Style Ideas: Vibrant neon backgrounds that react to the beat. Minimalist glowing tiles that pulse with the music. Ball animation (color changes based on the beat streak).
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0, bestCombo: 0 }); /**** * Classes ****/ var Ball = Container.expand(function () { var self = Container.call(this); var ballGraphics = self.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1 }); self.currentLane = 1; // 0=left, 1=center, 2=right self.targetY = 0; self.bounceHeight = 60; self.bounceSpeed = 0.05; self.bounceTime = 0; self.hasSpeedBoost = false; self.hasSlowMotion = false; self.doubleScoreActive = false; self.effectTimer = 0; self.moveTo = function (laneIndex) { if (laneIndex < 0 || laneIndex > 2) { return; } // Don't move if already in this lane if (self.currentLane === laneIndex) { return; } self.currentLane = laneIndex; var targetX = lanePositions[laneIndex]; // Animate the movement tween(self, { x: targetX }, { duration: 150, easing: tween.easeOut }); }; self.activatePowerup = function (type) { switch (type) { case 'speed': self.hasSpeedBoost = true; self.effectTimer = 300; // 5 seconds at 60fps tween(ballGraphics, { tint: 0xFFFF00 }, { duration: 200 }); break; case 'double': self.doubleScoreActive = true; self.effectTimer = 300; tween(ballGraphics, { tint: 0x00FF00 }, { duration: 200 }); break; case 'slow': self.hasSlowMotion = true; self.effectTimer = 300; tween(ballGraphics, { tint: 0x9900FF }, { duration: 200 }); break; } }; self.update = function () { // Update bounce animation self.bounceTime += self.bounceSpeed * (self.hasSpeedBoost ? 1.5 : self.hasSlowMotion ? 0.5 : 1); var bounceOffset = Math.sin(self.bounceTime) * self.bounceHeight; self.y = self.targetY - bounceOffset; // Update powerup timers if (self.effectTimer > 0) { self.effectTimer--; if (self.effectTimer === 0) { // Reset effects self.hasSpeedBoost = false; self.hasSlowMotion = false; self.doubleScoreActive = false; tween(ballGraphics, { tint: 0xFFFFFF }, { duration: 200 }); } } }; return self; }); var BeatTile = Container.expand(function () { var self = Container.call(this); var tileGraphics = self.attachAsset('beatTile', { anchorX: 0.5, anchorY: 0.5 }); self.lane = 0; self.active = true; self.speed = 5; self.hit = false; self.update = function () { if (!self.active) { return; } self.y += self.speed * (ball.hasSpeedBoost ? 1.5 : ball.hasSlowMotion ? 0.5 : 1); // Check if the tile has gone too far off-screen if (self.y > 2732 + tileGraphics.height) { self.active = false; } }; self.checkHit = function () { if (!self.active || self.hit) { return false; } // Check if ball is in the same lane and close enough in Y position if (self.lane === ball.currentLane) { var distance = Math.abs(self.y - ball.y); if (distance < 80) { self.hit = true; self.active = false; // Animate hit tween(tileGraphics, { alpha: 0, scaleX: 1.5, scaleY: 1.5 }, { duration: 300, easing: tween.easeOut }); return true; } } return false; }; self.showMissedIndicator = function () { var missedIndicator = LK.getAsset('missedTile', { anchorX: 0.5, anchorY: 0.5, x: self.x, y: self.y, alpha: 0.7 }); game.addChild(missedIndicator); tween(missedIndicator, { alpha: 0, scaleX: 1.3, scaleY: 1.3 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { missedIndicator.destroy(); } }); }; return self; }); var Powerup = Container.expand(function () { var self = Container.call(this); self.type = 'speed'; self.active = true; self.speed = 5; self.lane = 0; self.initialize = function (powerupType) { self.type = powerupType; // Different asset based on type var assetId; switch (powerupType) { case 'speed': assetId = 'powerupSpeed'; break; case 'double': assetId = 'powerupDouble'; break; case 'slow': assetId = 'powerupSlow'; break; default: assetId = 'powerupSpeed'; } self.graphic = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); }; self.update = function () { if (!self.active) { return; } self.y += self.speed * (ball.hasSpeedBoost ? 1.5 : ball.hasSlowMotion ? 0.5 : 1); self.rotation += 0.03; // Check if collected if (self.lane === ball.currentLane && Math.abs(self.y - ball.y) < 70) { self.collect(); return; } // Check if gone off-screen if (self.y > 2732 + 60) { self.active = false; } }; self.collect = function () { self.active = false; // Animate collection tween(self, { alpha: 0, scaleX: 1.5, scaleY: 1.5 }, { duration: 300, easing: tween.easeOut }); // Play powerup collect sound LK.getSound('powerupCollect').play(); // Create explosion effect var explosion = LK.getAsset('explosion', { anchorX: 0.5, anchorY: 0.5, x: self.x, y: self.y }); game.addChild(explosion); tween(explosion, { alpha: 0, scaleX: 2, scaleY: 2 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { explosion.destroy(); } }); // Apply effect ball.activatePowerup(self.type); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x111133 }); /**** * Game Code ****/ // Game constants // Add background image asset var GAME_WIDTH = 2048; var GAME_HEIGHT = 2732; var lanePositions = [GAME_WIDTH / 4, GAME_WIDTH / 2, 3 * GAME_WIDTH / 4]; var beatGenerationSpeed = 90; // frames between beat tiles var powerupChance = 0.15; // probability of a powerup spawning var difficultyIncreaseRate = 0.0001; // how fast the game speeds up // Game state var beatTimer = 0; var score = 0; var combo = 0; var highestCombo = 0; var gameSpeed = 1; var tiles = []; var powerups = []; var ball; var scoreText; var comboText; var highScoreText; // Set up game background var background = LK.getAsset('background', { anchorX: 0.5, anchorY: 0.5, x: GAME_WIDTH / 2, y: GAME_HEIGHT / 2 }); game.addChild(background); // Create lane indicators for (var i = 0; i < 3; i++) { var lane = LK.getAsset('lane', { anchorX: 0.5, anchorY: 0, x: lanePositions[i], y: 0, alpha: 0.3 }); game.addChild(lane); } // Set up game UI scoreText = new Text2('Score: 0', { size: 80, fill: 0xFFFFFF }); scoreText.anchor.set(0, 0); LK.gui.topLeft.addChild(scoreText); scoreText.x = 120; // Avoid the top-left 100x100 area scoreText.y = 20; comboText = new Text2('Combo: 0', { size: 80, fill: 0xFFFFFF }); comboText.anchor.set(0, 0); LK.gui.topLeft.addChild(comboText); comboText.x = 120; comboText.y = 110; // High score display highScoreText = new Text2('High Score: ' + storage.highScore, { size: 60, fill: 0xFFCC00 }); highScoreText.anchor.set(1, 0); LK.gui.topRight.addChild(highScoreText); highScoreText.x = -20; highScoreText.y = 20; // Create player ball ball = new Ball(); ball.x = lanePositions[1]; // Start in middle lane ball.y = GAME_HEIGHT - 400; // Position near bottom ball.targetY = ball.y; game.addChild(ball); // Start with some beat tiles generateInitialTiles(); // Start music LK.playMusic('gameMusic', { fade: { start: 0, end: 0.8, duration: 1000 } }); // Touch controls function handleTouch(x, y) { // Determine which third of the screen was tapped if (x < GAME_WIDTH / 3) { ball.moveTo(0); // Left lane } else if (x < 2 * GAME_WIDTH / 3) { ball.moveTo(1); // Middle lane } else { ball.moveTo(2); // Right lane } } game.down = function (x, y, obj) { handleTouch(x, y); }; function generateBeatTile() { var lane = Math.floor(Math.random() * 3); var tile = new BeatTile(); tile.x = lanePositions[lane]; tile.y = -100; // Start above the screen tile.lane = lane; tile.speed *= gameSpeed; game.addChild(tile); tiles.push(tile); // Sometimes spawn a powerup if (Math.random() < powerupChance) { generatePowerup(lane); } } function generatePowerup(lane) { var powerupTypes = ['speed', 'double', 'slow']; var type = powerupTypes[Math.floor(Math.random() * powerupTypes.length)]; var powerup = new Powerup(); powerup.initialize(type); powerup.x = lanePositions[lane]; powerup.y = -200; // Start above the screen powerup.lane = lane; powerup.speed *= gameSpeed; game.addChild(powerup); powerups.push(powerup); } function generateInitialTiles() { // Create a few initial tiles to get started for (var i = 0; i < 5; i++) { var lane = Math.floor(Math.random() * 3); var tile = new BeatTile(); tile.x = lanePositions[lane]; tile.y = -100 - i * 400; // Stagger them tile.lane = lane; tile.speed *= gameSpeed; game.addChild(tile); tiles.push(tile); } } function updateScore(points) { var pointsToAdd = points; // Apply combo multiplier (starting from 1) if (combo > 0) { pointsToAdd = Math.floor(points * (1 + combo * 0.1)); } // Apply double score powerup if (ball.doubleScoreActive) { pointsToAdd *= 2; } score += pointsToAdd; scoreText.setText('Score: ' + score); // Show score popup var scorePopup = new Text2('+' + pointsToAdd, { size: 70, fill: 0xFFFF00 }); scorePopup.anchor.set(0.5, 0.5); scorePopup.x = ball.x; scorePopup.y = ball.y - 100; game.addChild(scorePopup); tween(scorePopup, { alpha: 0, y: scorePopup.y - 100 }, { duration: 800, easing: tween.easeOut, onFinish: function onFinish() { scorePopup.destroy(); } }); } game.update = function () { // Update game speed gameSpeed += difficultyIncreaseRate; // Generate new beat tiles beatTimer++; if (beatTimer >= beatGenerationSpeed) { beatTimer = 0; generateBeatTile(); // Slightly decrease time between beats as game progresses beatGenerationSpeed = Math.max(40, beatGenerationSpeed - 0.1); } // Update all game objects for (var i = tiles.length - 1; i >= 0; i--) { var tile = tiles[i]; tile.update(); // Check for hits if (tile.active && !tile.hit && tile.checkHit()) { // Increase combo combo++; if (combo > highestCombo) { highestCombo = combo; } comboText.setText("Combo: " + combo); // Play tile hit sound LK.getSound('tileHit').play(); // Update score updateScore(10); } // Clean up inactive tiles if (!tile.active) { tiles.splice(i, 1); } } // Update powerups for (var j = powerups.length - 1; j >= 0; j--) { var powerup = powerups[j]; powerup.update(); if (!powerup.active) { powerups.splice(j, 1); } } // Update player ball.update(); // Check for game over if (score > 1000) { // Save high score if (score > storage.highScore) { storage.highScore = score; } // Save best combo if (highestCombo > storage.bestCombo) { storage.bestCombo = highestCombo; } LK.showYouWin(); } // Play comboBreak sound if combo is reset if (combo === 0 && highestCombo > 0) { LK.getSound('comboBreak').play(); } // Play beatMiss sound if a tile is missed for (var i = tiles.length - 1; i >= 0; i--) { var tile = tiles[i]; if (!tile.active && !tile.hit) { LK.getSound('beatMiss').play(); } } }; // Clean up function if game is destroyed game.destroy = function () { // Stop any tweens for (var i = 0; i < tiles.length; i++) { tween.stop(tiles[i]); } for (var j = 0; j < powerups.length; j++) { tween.stop(powerups[j]); } tween.stop(ball); // Stop music LK.stopMusic(); };
===================================================================
--- original.js
+++ change.js
@@ -222,8 +222,27 @@
easing: tween.easeOut
});
// Play powerup collect sound
LK.getSound('powerupCollect').play();
+ // Create explosion effect
+ var explosion = LK.getAsset('explosion', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: self.x,
+ y: self.y
+ });
+ game.addChild(explosion);
+ tween(explosion, {
+ alpha: 0,
+ scaleX: 2,
+ scaleY: 2
+ }, {
+ duration: 500,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ explosion.destroy();
+ }
+ });
// Apply effect
ball.activatePowerup(self.type);
};
return self;
@@ -238,10 +257,10 @@
/****
* Game Code
****/
-// Add background image asset
// Game constants
+// Add background image asset
var GAME_WIDTH = 2048;
var GAME_HEIGHT = 2732;
var lanePositions = [GAME_WIDTH / 4, GAME_WIDTH / 2, 3 * GAME_WIDTH / 4];
var beatGenerationSpeed = 90; // frames between beat tiles
Design: Square or circular glowing pads that react when hit. Effect: A pulse effect when the ball lands perfectly. Variations: Different colors per beat type (e.g., blue for normal, red for speed boosts).. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Design: A faded-out or cracked tile to indicate a miss. Effect: A quick screen shake or particle effect when touched.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Design: A dynamic, glowing path that scrolls forward. Style Options: Cyberpunk neon rails Floating musical staff lines A galaxy wave track. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
PowerUpDouble ⭐ Golden glow tile Score x2 for 5 sec. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
PowerUpSlow ⏳ Blue time freeze tile Slows music briefly. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
PowerUpSpeed ⚡ Red speed trail tile Speeds up for bonus. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
🔹 Floating low-poly islands or platforms in a futuristic city. 🔹 Horizon with a sun reflecting off water for a peaceful but futuristic look. 🔹 Colors: Sunset orange, deep blue, and glowing city lights.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows