User prompt
has que todos los bloques de colores cuenten como uno solo
User prompt
optimizalo
User prompt
que los cuadros sean mas grandes y sean solamente colores primarios y que cubran todo lo de arriba de la pantalla y que la pelota aparezca arriba del cuadro blanco
User prompt
bien crea cuadrados chiquitos de colores que desaparezcan cuando la pelota los toque y asu vez rebote
User prompt
que el cuadro siga el raton
User prompt
ahora que tenga colision con la pelota y que el cuadro siga el raton
User prompt
haz un cuadro largo y grueso que no pueda traspasar las paredes
User prompt
elimina la guitarra y hazlo como el cuadro anterior
User prompt
un poco menos larga
User prompt
has que la guitarra este un poco mas larga
User prompt
cuando la pelota pegue con la zona de abajo salga "game over" y que tenga algo de mas velocidad
User prompt
bueno que el cuadro sea algo mas chico y que la pelota no pueda traspasar las paredes
User prompt
que el cuadro no pueda salir de la pantalla y que la pelota si pero la pelota aparezca del otro lado y viseverza y que la pelota sea mas pequeña
User prompt
no grande si no que largo y que el cuadro sig estatico pero que siga al raton
User prompt
haz a que el cuadrado sea mas grande y quede estatico en la zona abajo de la pantalla
Code edit (1 edits merged)
Please save this source code
User prompt
Bounce Box
Initial prompt
añade un cuadro blanco y un circulo y que el cuadro se pueda mover y el circulo rebote con los cuadros
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var BlueBlock = Container.expand(function () { var self = Container.call(this); var blockGraphics = self.attachAsset('blueBlock', { anchorX: 0.5, anchorY: 0.5 }); return self; }); var BouncingCircle = Container.expand(function () { var self = Container.call(this); var circleGraphics = self.attachAsset('bouncingCircle', { anchorX: 0.5, anchorY: 0.5 }); // Velocity properties self.velocityX = 15; self.velocityY = 13; self.update = function () { // Move the circle self.x += self.velocityX; self.y += self.velocityY; // Check collision with blue blocks for (var i = blocks.length - 1; i >= 0; i--) { var block = blocks[i]; var ballHit = false; // Check collision with all bouncing circles for (var circleIndex = 0; circleIndex < bouncingCircles.length; circleIndex++) { var circle = bouncingCircles[circleIndex]; if (circle.intersects(block)) { ballHit = true; break; } } if (ballHit) { // Play blue block sound and additional sounds LK.getSound('sonidodebloqueazul').play(); var additionalSounds = ['q', 'w', 'e', 'r', 't']; var randomAdditionalSound = additionalSounds[Math.floor(Math.random() * additionalSounds.length)]; LK.getSound(randomAdditionalSound).play(); // Block destroyed // Increment score score += 10; scoreTxt.setText('Score: ' + score); // Add expansion animation to bouncing circle tween(self, { scaleX: 1.5, scaleY: 1.5 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeIn }); } }); // Spawn red block at random position with minimum distance from other blocks var newRedBlock = game.addChild(new RedBlock()); var validPosition = false; var attempts = 0; while (!validPosition && attempts < 50) { newRedBlock.x = Math.random() * (2048 - 120) + 60; // Random X within screen bounds newRedBlock.y = Math.random() * 800 + 200; // Random Y in upper part of screen validPosition = true; // Check distance from all existing blue blocks for (var b = 0; b < blocks.length; b++) { var existingBlock = blocks[b]; var dx = newRedBlock.x - existingBlock.x; var dy = newRedBlock.y - existingBlock.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 200) { // Minimum distance of 200 pixels validPosition = false; break; } } // Check distance from all existing red blocks for (var r = 0; r < redBlocks.length; r++) { var existingRedBlock = redBlocks[r]; var dx = newRedBlock.x - existingRedBlock.x; var dy = newRedBlock.y - existingRedBlock.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 200) { // Minimum distance of 200 pixels validPosition = false; break; } } // Check distance from all existing green blocks for (var g = 0; g < greenBlocks.length; g++) { var existingGreenBlock = greenBlocks[g]; var dx = newRedBlock.x - existingGreenBlock.x; var dy = newRedBlock.y - existingGreenBlock.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 200) { // Minimum distance of 200 pixels validPosition = false; break; } } // Check distance from all existing purple blocks for (var p = 0; p < purpleBlocks.length; p++) { var existingPurpleBlock = purpleBlocks[p]; var dx = newRedBlock.x - existingPurpleBlock.x; var dy = newRedBlock.y - existingPurpleBlock.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 200) { // Minimum distance of 200 pixels validPosition = false; break; } } attempts++; } redBlocks.push(newRedBlock); // 20% chance to spawn power orb if (Math.random() < 0.2) { var powerOrb = game.addChild(new PowerOrb()); powerOrb.x = block.x; powerOrb.y = block.y; powerOrbs.push(powerOrb); } // 20% chance to spawn double ball orb if (Math.random() < 0.2) { var doubleBallOrb = game.addChild(new DoubleBallOrb()); doubleBallOrb.x = block.x; doubleBallOrb.y = block.y; doubleBallOrbs.push(doubleBallOrb); } // 20% chance to spawn slow ball orb if (Math.random() < 0.2) { var slowBallOrb = game.addChild(new SlowBallOrb()); slowBallOrb.x = block.x; slowBallOrb.y = block.y; slowBallOrbs.push(slowBallOrb); } // 20% chance to spawn enlarge paddle orb if (Math.random() < 0.2) { var enlargePaddleOrb = game.addChild(new EnlargePaddleOrb()); enlargePaddleOrb.x = block.x; enlargePaddleOrb.y = block.y; enlargePaddleOrbs.push(enlargePaddleOrb); } // Destroy the block block.destroy(); blocks.splice(i, 1); // Reverse ball Y velocity self.velocityY = -self.velocityY; break; // Only hit one block per frame } } // Check collision with red blocks for (var j = redBlocks.length - 1; j >= 0; j--) { var redBlock = redBlocks[j]; if (self.intersects(redBlock)) { // Play red block sound and additional sounds LK.getSound('sonidodebloquerojo').play(); var additionalSounds = ['q', 'w', 'e', 'r', 't']; var randomAdditionalSound = additionalSounds[Math.floor(Math.random() * additionalSounds.length)]; LK.getSound(randomAdditionalSound).play(); // Block destroyed // Increment score score += 15; scoreTxt.setText('Score: ' + score); // Add expansion animation to bouncing circle tween(self, { scaleX: 1.5, scaleY: 1.5 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeIn }); } }); // Spawn green block at random position with minimum distance from other blocks var newGreenBlock = game.addChild(new GreenBlock()); var validPosition = false; var attempts = 0; while (!validPosition && attempts < 50) { newGreenBlock.x = Math.random() * (2048 - 120) + 60; // Random X within screen bounds newGreenBlock.y = Math.random() * 800 + 200; // Random Y in upper part of screen validPosition = true; // Check distance from all existing blue blocks for (var b = 0; b < blocks.length; b++) { var existingBlock = blocks[b]; var dx = newGreenBlock.x - existingBlock.x; var dy = newGreenBlock.y - existingBlock.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 200) { // Minimum distance of 200 pixels validPosition = false; break; } } // Check distance from all existing red blocks for (var r = 0; r < redBlocks.length; r++) { var existingRedBlock = redBlocks[r]; var dx = newGreenBlock.x - existingRedBlock.x; var dy = newGreenBlock.y - existingRedBlock.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 200) { // Minimum distance of 200 pixels validPosition = false; break; } } // Check distance from all existing green blocks for (var g = 0; g < greenBlocks.length; g++) { var existingGreenBlock = greenBlocks[g]; var dx = newGreenBlock.x - existingGreenBlock.x; var dy = newGreenBlock.y - existingGreenBlock.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 200) { // Minimum distance of 200 pixels validPosition = false; break; } } // Check distance from all existing purple blocks for (var p = 0; p < purpleBlocks.length; p++) { var existingPurpleBlock = purpleBlocks[p]; var dx = newGreenBlock.x - existingPurpleBlock.x; var dy = newGreenBlock.y - existingPurpleBlock.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 200) { // Minimum distance of 200 pixels validPosition = false; break; } } attempts++; } greenBlocks.push(newGreenBlock); // 20% chance to spawn power orb if (Math.random() < 0.2) { var powerOrb = game.addChild(new PowerOrb()); powerOrb.x = redBlock.x; powerOrb.y = redBlock.y; powerOrbs.push(powerOrb); } // 20% chance to spawn double ball orb if (Math.random() < 0.2) { var doubleBallOrb = game.addChild(new DoubleBallOrb()); doubleBallOrb.x = redBlock.x; doubleBallOrb.y = redBlock.y; doubleBallOrbs.push(doubleBallOrb); } // 20% chance to spawn slow ball orb if (Math.random() < 0.2) { var slowBallOrb = game.addChild(new SlowBallOrb()); slowBallOrb.x = redBlock.x; slowBallOrb.y = redBlock.y; slowBallOrbs.push(slowBallOrb); } // 20% chance to spawn enlarge paddle orb if (Math.random() < 0.2) { var enlargePaddleOrb = game.addChild(new EnlargePaddleOrb()); enlargePaddleOrb.x = redBlock.x; enlargePaddleOrb.y = redBlock.y; enlargePaddleOrbs.push(enlargePaddleOrb); } // Destroy the red block redBlock.destroy(); redBlocks.splice(j, 1); // Reverse ball Y velocity self.velocityY = -self.velocityY; break; // Only hit one block per frame } } // Check collision with green blocks for (var k = greenBlocks.length - 1; k >= 0; k--) { var greenBlock = greenBlocks[k]; if (self.intersects(greenBlock)) { // Play green block sound and additional sounds LK.getSound('sonidodebloquerojo').play(); var additionalSounds = ['q', 'w', 'e', 'r', 't']; var randomAdditionalSound = additionalSounds[Math.floor(Math.random() * additionalSounds.length)]; LK.getSound(randomAdditionalSound).play(); // Block destroyed // Increment score score += 20; scoreTxt.setText('Score: ' + score); // Add expansion animation to bouncing circle tween(self, { scaleX: 1.5, scaleY: 1.5 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeIn }); } }); // Spawn purple block at random position with minimum distance from other blocks var newPurpleBlock = game.addChild(new PurpleBlock()); var validPosition = false; var attempts = 0; while (!validPosition && attempts < 50) { newPurpleBlock.x = Math.random() * (2048 - 120) + 60; // Random X within screen bounds newPurpleBlock.y = Math.random() * 800 + 200; // Random Y in upper part of screen validPosition = true; // Check distance from all existing blue blocks for (var b = 0; b < blocks.length; b++) { var existingBlock = blocks[b]; var dx = newPurpleBlock.x - existingBlock.x; var dy = newPurpleBlock.y - existingBlock.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 200) { // Minimum distance of 200 pixels validPosition = false; break; } } // Check distance from all existing red blocks for (var r = 0; r < redBlocks.length; r++) { var existingRedBlock = redBlocks[r]; var dx = newPurpleBlock.x - existingRedBlock.x; var dy = newPurpleBlock.y - existingRedBlock.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 200) { // Minimum distance of 200 pixels validPosition = false; break; } } // Check distance from all existing green blocks for (var g = 0; g < greenBlocks.length; g++) { var existingGreenBlock = greenBlocks[g]; var dx = newPurpleBlock.x - existingGreenBlock.x; var dy = newPurpleBlock.y - existingGreenBlock.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 200) { // Minimum distance of 200 pixels validPosition = false; break; } } // Check distance from all existing purple blocks for (var p = 0; p < purpleBlocks.length; p++) { var existingPurpleBlock = purpleBlocks[p]; var dx = newPurpleBlock.x - existingPurpleBlock.x; var dy = newPurpleBlock.y - existingPurpleBlock.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 200) { // Minimum distance of 200 pixels validPosition = false; break; } } attempts++; } purpleBlocks.push(newPurpleBlock); // 20% chance to spawn power orb if (Math.random() < 0.2) { var powerOrb = game.addChild(new PowerOrb()); powerOrb.x = greenBlock.x; powerOrb.y = greenBlock.y; powerOrbs.push(powerOrb); } // 20% chance to spawn double ball orb if (Math.random() < 0.2) { var doubleBallOrb = game.addChild(new DoubleBallOrb()); doubleBallOrb.x = greenBlock.x; doubleBallOrb.y = greenBlock.y; doubleBallOrbs.push(doubleBallOrb); } // 20% chance to spawn slow ball orb if (Math.random() < 0.2) { var slowBallOrb = game.addChild(new SlowBallOrb()); slowBallOrb.x = greenBlock.x; slowBallOrb.y = greenBlock.y; slowBallOrbs.push(slowBallOrb); } // 20% chance to spawn enlarge paddle orb if (Math.random() < 0.2) { var enlargePaddleOrb = game.addChild(new EnlargePaddleOrb()); enlargePaddleOrb.x = greenBlock.x; enlargePaddleOrb.y = greenBlock.y; enlargePaddleOrbs.push(enlargePaddleOrb); } // Destroy the green block greenBlock.destroy(); greenBlocks.splice(k, 1); // Reverse ball Y velocity self.velocityY = -self.velocityY; break; // Only hit one block per frame } } // Check collision with purple blocks for (var l = purpleBlocks.length - 1; l >= 0; l--) { var purpleBlock = purpleBlocks[l]; if (self.intersects(purpleBlock)) { // Play purple block sound and additional sounds LK.getSound('sonidodebloquerojo').play(); var additionalSounds = ['q', 'w', 'e', 'r', 't']; var randomAdditionalSound = additionalSounds[Math.floor(Math.random() * additionalSounds.length)]; LK.getSound(randomAdditionalSound).play(); // Block destroyed // Increment score score += 25; scoreTxt.setText('Score: ' + score); // Add expansion animation to bouncing circle tween(self, { scaleX: 1.5, scaleY: 1.5 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeIn }); } }); // 20% chance to spawn power orb if (Math.random() < 0.2) { var powerOrb = game.addChild(new PowerOrb()); powerOrb.x = purpleBlock.x; powerOrb.y = purpleBlock.y; powerOrbs.push(powerOrb); } // 20% chance to spawn double ball orb if (Math.random() < 0.2) { var doubleBallOrb = game.addChild(new DoubleBallOrb()); doubleBallOrb.x = purpleBlock.x; doubleBallOrb.y = purpleBlock.y; doubleBallOrbs.push(doubleBallOrb); } // 20% chance to spawn slow ball orb if (Math.random() < 0.2) { var slowBallOrb = game.addChild(new SlowBallOrb()); slowBallOrb.x = purpleBlock.x; slowBallOrb.y = purpleBlock.y; slowBallOrbs.push(slowBallOrb); } // 20% chance to spawn enlarge paddle orb if (Math.random() < 0.2) { var enlargePaddleOrb = game.addChild(new EnlargePaddleOrb()); enlargePaddleOrb.x = purpleBlock.x; enlargePaddleOrb.y = purpleBlock.y; enlargePaddleOrbs.push(enlargePaddleOrb); } // Destroy the purple block purpleBlock.destroy(); purpleBlocks.splice(l, 1); // Reverse ball Y velocity self.velocityY = -self.velocityY; break; // Only hit one block per frame } } // Bounce off screen edges if (self.x <= 25) { self.x = 25; self.velocityX = -self.velocityX; } if (self.x >= 2048 - 25) { self.x = 2048 - 25; self.velocityX = -self.velocityX; } if (self.y <= 25) { self.y = 25; self.velocityY = -self.velocityY; } if (self.y >= 2732 - 25) { self.y = 2732 - 25; self.velocityY = -self.velocityY; } }; return self; }); var CornerBlock = Container.expand(function () { var self = Container.call(this); var blockGraphics = self.attachAsset('cornerBlock', { anchorX: 0.5, anchorY: 0.5, tint: 0x000000 }); // Track collision state for sound triggering self.lastIntersecting = false; self.update = function () { // Check collision with bouncing circle var currentIntersecting = self.intersects(bouncingCircle); if (!self.lastIntersecting && currentIntersecting) { // Collision just started - play random sound (C, A, or G) var sounds = ['c', 'a', 'g']; var randomSound = sounds[Math.floor(Math.random() * sounds.length)]; LK.getSound(randomSound).play(); var additionalSounds = ['q', 'w', 'e', 'r', 't']; var randomAdditionalSound = additionalSounds[Math.floor(Math.random() * additionalSounds.length)]; LK.getSound(randomAdditionalSound).play(); // Add expansion animation to bouncing circle tween(bouncingCircle, { scaleX: 1.5, scaleY: 1.5 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(bouncingCircle, { scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeIn }); } }); } self.lastIntersecting = currentIntersecting; }; return self; }); var CornerBlockRight = Container.expand(function () { var self = Container.call(this); var blockGraphics = self.attachAsset('cornerBlockRight', { anchorX: 0.5, anchorY: 0.5, tint: 0x000000 }); // Track collision state for sound triggering self.lastIntersecting = false; self.update = function () { // Check collision with bouncing circle var currentIntersecting = self.intersects(bouncingCircle); if (!self.lastIntersecting && currentIntersecting) { // Collision just started - play random sound (C, A, or G) var sounds = ['c', 'a', 'g']; var randomSound = sounds[Math.floor(Math.random() * sounds.length)]; LK.getSound(randomSound).play(); var additionalSounds = ['q', 'w', 'e', 'r', 't']; var randomAdditionalSound = additionalSounds[Math.floor(Math.random() * additionalSounds.length)]; LK.getSound(randomAdditionalSound).play(); // Add expansion animation to bouncing circle tween(bouncingCircle, { scaleX: 1.5, scaleY: 1.5 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(bouncingCircle, { scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeIn }); } }); } self.lastIntersecting = currentIntersecting; }; return self; }); var CornerBlockTop = Container.expand(function () { var self = Container.call(this); var blockGraphics = self.attachAsset('cornerBlockTop', { anchorX: 0.5, anchorY: 0.5, tint: 0x000000 }); // Track collision state for sound triggering self.lastIntersecting = false; self.update = function () { // Check collision with bouncing circle var currentIntersecting = self.intersects(bouncingCircle); if (!self.lastIntersecting && currentIntersecting) { // Collision just started - play random sound (C, A, or G) var sounds = ['c', 'a', 'g']; var randomSound = sounds[Math.floor(Math.random() * sounds.length)]; LK.getSound(randomSound).play(); var additionalSounds = ['q', 'w', 'e', 'r', 't']; var randomAdditionalSound = additionalSounds[Math.floor(Math.random() * additionalSounds.length)]; LK.getSound(randomAdditionalSound).play(); // Add expansion animation to bouncing circle tween(bouncingCircle, { scaleX: 1.5, scaleY: 1.5 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(bouncingCircle, { scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeIn }); } }); } self.lastIntersecting = currentIntersecting; }; return self; }); var DoubleBallOrb = Container.expand(function () { var self = Container.call(this); var orbGraphics = self.attachAsset('doubleBallOrb', { anchorX: 0.5, anchorY: 0.5, tint: 0x00ffff }); // Fall downward self.velocityY = 8; self.update = function () { self.y += self.velocityY; // Remove if goes off screen if (self.y > 2800) { self.destroy(); // Remove from doubleBallOrbs array for (var i = doubleBallOrbs.length - 1; i >= 0; i--) { if (doubleBallOrbs[i] === self) { doubleBallOrbs.splice(i, 1); break; } } } }; return self; }); var EnlargePaddleOrb = Container.expand(function () { var self = Container.call(this); var orbGraphics = self.attachAsset('enlargePaddleOrb', { anchorX: 0.5, anchorY: 0.5, tint: 0xff00ff }); // Fall downward self.velocityY = 8; self.update = function () { self.y += self.velocityY; // Remove if goes off screen if (self.y > 2800) { self.destroy(); // Remove from enlargePaddleOrbs array for (var i = enlargePaddleOrbs.length - 1; i >= 0; i--) { if (enlargePaddleOrbs[i] === self) { enlargePaddleOrbs.splice(i, 1); break; } } } }; return self; }); var GreenBlock = Container.expand(function () { var self = Container.call(this); var blockGraphics = self.attachAsset('greenBlock', { anchorX: 0.5, anchorY: 0.5 }); return self; }); // Cache paddle constants var Paddle = Container.expand(function () { var self = Container.call(this); var paddleGraphics = self.attachAsset('paddle', { anchorX: 0.5, anchorY: 0.5 }); self.update = function () { // Prevent paddle from going through left wall if (self.x < PADDLE_HALF_WIDTH) { self.x = PADDLE_HALF_WIDTH; } // Prevent paddle from going through right wall if (self.x > SCREEN_WIDTH - PADDLE_HALF_WIDTH) { self.x = SCREEN_WIDTH - PADDLE_HALF_WIDTH; } }; return self; }); var PowerOrb = Container.expand(function () { var self = Container.call(this); var orbGraphics = self.attachAsset('powerOrb', { anchorX: 0.5, anchorY: 0.5, tint: 0xffff00 }); // Fall downward self.velocityY = 8; self.update = function () { self.y += self.velocityY; // Remove if goes off screen if (self.y > 2800) { self.destroy(); // Remove from powerOrbs array for (var i = powerOrbs.length - 1; i >= 0; i--) { if (powerOrbs[i] === self) { powerOrbs.splice(i, 1); break; } } } }; return self; }); var PurpleBlock = Container.expand(function () { var self = Container.call(this); var blockGraphics = self.attachAsset('purpleBlock', { anchorX: 0.5, anchorY: 0.5 }); return self; }); var RedBlock = Container.expand(function () { var self = Container.call(this); var blockGraphics = self.attachAsset('redBlock', { anchorX: 0.5, anchorY: 0.5 }); return self; }); var SlowBallOrb = Container.expand(function () { var self = Container.call(this); var orbGraphics = self.attachAsset('slowBallOrb', { anchorX: 0.5, anchorY: 0.5, tint: 0xff0000 }); // Fall downward self.velocityY = 8; self.update = function () { self.y += self.velocityY; // Remove if goes off screen if (self.y > 2800) { self.destroy(); // Remove from slowBallOrbs array for (var i = slowBallOrbs.length - 1; i >= 0; i--) { if (slowBallOrbs[i] === self) { slowBallOrbs.splice(i, 1); break; } } } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Add scattered musical wave symbols across the background var musicalWaves = []; for (var i = 0; i < 20; i++) { var waveType = 'musicalWave' + (Math.floor(Math.random() * 4) + 1); var wave = game.addChild(LK.getAsset(waveType, { anchorX: 0.5, anchorY: 0.5, x: Math.random() * 2048, y: Math.random() * 2732, alpha: 0.3, rotation: Math.random() * Math.PI * 2 })); musicalWaves.push(wave); } // Add scattered musical notes across the background var musicalNotes = []; for (var i = 0; i < 15; i++) { var noteType = 'musicalNote' + (Math.floor(Math.random() * 3) + 1); var note = game.addChild(LK.getAsset(noteType, { anchorX: 0.5, anchorY: 0.5, x: Math.random() * 2048, y: Math.random() * 2732, alpha: 0.25, rotation: Math.random() * Math.PI * 2 })); musicalNotes.push(note); } // Add staff lines across the background var staffLines = []; for (var i = 0; i < 12; i++) { var staffType = 'staffLine' + (Math.floor(Math.random() * 3) + 1); var staff = game.addChild(LK.getAsset(staffType, { anchorX: 0.5, anchorY: 0.5, x: Math.random() * 2048, y: Math.random() * 2732, alpha: 0.2, rotation: Math.random() * Math.PI * 0.5 })); staffLines.push(staff); } // Add treble clefs scattered in the background var trebleClefs = []; for (var i = 0; i < 8; i++) { var clef = game.addChild(LK.getAsset('trebleClef', { anchorX: 0.5, anchorY: 0.5, x: Math.random() * 2048, y: Math.random() * 2732, alpha: 0.15, rotation: Math.random() * Math.PI * 2 })); trebleClefs.push(clef); } // Add scattered background circles var backgroundCircles = []; for (var i = 0; i < 40; i++) { var circleType = 'backgroundCircle' + (Math.floor(Math.random() * 6) + 1); var circle = game.addChild(LK.getAsset(circleType, { anchorX: 0.5, anchorY: 0.5, x: Math.random() * 2048, y: Math.random() * 2732, alpha: 0.1 })); backgroundCircles.push(circle); } // Cache paddle constants var PADDLE_HALF_WIDTH = 150; var SCREEN_WIDTH = 2048; var blocks = []; var redBlocks = []; var greenBlocks = []; var purpleBlocks = []; var powerOrbs = []; var doubleBallOrbs = []; var slowBallOrbs = []; var enlargePaddleOrbs = []; var bouncingCircles = []; var paddleCollisions = 0; var score = 0; var bouncingCircle = game.addChild(new BouncingCircle()); bouncingCircle.x = 1024; bouncingCircle.y = 2550; // Position above paddle bouncingCircle.lastIntersecting = false; bouncingCircles.push(bouncingCircle); var paddle = game.addChild(new Paddle()); paddle.x = 1024; paddle.y = 2600; var scoreTxt = new Text2('Score: 0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); game.move = function (x, y, obj) { paddle.x = x; }; // Add corner block covering entire left side of screen var cornerBlock = game.addChild(new CornerBlock()); cornerBlock.x = 10; // Position at left edge cornerBlock.y = 1366; // Center vertically (half of 2732) // Add corner block covering entire right side of screen var cornerBlockRight = game.addChild(new CornerBlockRight()); cornerBlockRight.x = 2038; // Position at right edge cornerBlockRight.y = 1366; // Center vertically (half of 2732) // Add corner block covering entire top side of screen var cornerBlockTop = game.addChild(new CornerBlockTop()); cornerBlockTop.x = 1024; // Center horizontally (half of 2048) cornerBlockTop.y = 10; // Position at top edge // Play background music LK.playMusic('musica'); game.update = function () { // Track ball-paddle collision state transitions var currentIntersecting = bouncingCircle.intersects(paddle); if (!bouncingCircle.lastIntersecting && currentIntersecting) { // Collision just started - push ball above paddle and reverse Y velocity bouncingCircle.y = paddle.y - 20 - 25; bouncingCircle.velocityY = -Math.abs(bouncingCircle.velocityY); // Increment paddle collision counter paddleCollisions++; // Play random sound (C, A, or G) var sounds = ['c', 'a', 'g']; var randomSound = sounds[Math.floor(Math.random() * sounds.length)]; LK.getSound(randomSound).play(); var additionalSounds = ['q', 'w', 'e', 'r', 't']; var randomAdditionalSound = additionalSounds[Math.floor(Math.random() * additionalSounds.length)]; LK.getSound(randomAdditionalSound).play(); // Add expansion animation to bouncing circle tween(bouncingCircle, { scaleX: 1.5, scaleY: 1.5 }, { duration: 200, easing: tween.easeOut, onFinish: function onFinish() { tween(bouncingCircle, { scaleX: 1, scaleY: 1 }, { duration: 200, easing: tween.easeIn }); } }); // Add shake animation to paddle var shakeDistance = 10; var originalX = paddle.x; tween(paddle, { x: originalX - shakeDistance }, { duration: 50, easing: tween.easeOut, onFinish: function onFinish() { tween(paddle, { x: originalX + shakeDistance }, { duration: 50, easing: tween.easeInOut, onFinish: function onFinish() { tween(paddle, { x: originalX - shakeDistance * 0.5 }, { duration: 40, easing: tween.easeInOut, onFinish: function onFinish() { tween(paddle, { x: originalX + shakeDistance * 0.5 }, { duration: 40, easing: tween.easeInOut, onFinish: function onFinish() { tween(paddle, { x: originalX }, { duration: 30, easing: tween.easeIn }); } }); } }); } }); } }); // Spawn new blue block at random position with minimum distance from other blocks var newBlock = game.addChild(new BlueBlock()); var validPosition = false; var attempts = 0; while (!validPosition && attempts < 50) { newBlock.x = Math.random() * (2048 - 120) + 60; // Random X within screen bounds newBlock.y = Math.random() * 800 + 200; // Random Y in upper part of screen validPosition = true; // Check distance from all existing blue blocks for (var b = 0; b < blocks.length; b++) { var existingBlock = blocks[b]; var dx = newBlock.x - existingBlock.x; var dy = newBlock.y - existingBlock.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 200) { // Minimum distance of 200 pixels validPosition = false; break; } } // Check distance from all existing red blocks for (var r = 0; r < redBlocks.length; r++) { var existingRedBlock = redBlocks[r]; var dx = newBlock.x - existingRedBlock.x; var dy = newBlock.y - existingRedBlock.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 200) { // Minimum distance of 200 pixels validPosition = false; break; } } // Check distance from all existing green blocks for (var g = 0; g < greenBlocks.length; g++) { var existingGreenBlock = greenBlocks[g]; var dx = newBlock.x - existingGreenBlock.x; var dy = newBlock.y - existingGreenBlock.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 200) { // Minimum distance of 200 pixels validPosition = false; break; } } // Check distance from all existing purple blocks for (var p = 0; p < purpleBlocks.length; p++) { var existingPurpleBlock = purpleBlocks[p]; var dx = newBlock.x - existingPurpleBlock.x; var dy = newBlock.y - existingPurpleBlock.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 200) { // Minimum distance of 200 pixels validPosition = false; break; } } attempts++; } blocks.push(newBlock); } bouncingCircle.lastIntersecting = currentIntersecting; // Check power orb collisions with paddle for (var k = powerOrbs.length - 1; k >= 0; k--) { var powerOrb = powerOrbs[k]; if (powerOrb.intersects(paddle)) { // Increase ball speed for all balls var speedMultiplier = 1.5; for (var circleIndex = 0; circleIndex < bouncingCircles.length; circleIndex++) { var circle = bouncingCircles[circleIndex]; circle.velocityX *= speedMultiplier; circle.velocityY *= speedMultiplier; // Visual feedback - flash ball green tween(circle, { tint: 0x00ff00 }, { duration: 200, onFinish: function onFinish() { tween(circle, { tint: 0xffffff }, { duration: 200 }); } }); } // Remove power orb powerOrb.destroy(); powerOrbs.splice(k, 1); } } // Check double ball orb collisions with paddle for (var d = doubleBallOrbs.length - 1; d >= 0; d--) { var doubleBallOrb = doubleBallOrbs[d]; if (doubleBallOrb.intersects(paddle)) { // Create new bouncing ball var newBall = game.addChild(new BouncingCircle()); newBall.x = bouncingCircle.x + 50; newBall.y = bouncingCircle.y; newBall.velocityX = -bouncingCircle.velocityX; newBall.velocityY = bouncingCircle.velocityY; newBall.lastIntersecting = false; bouncingCircles.push(newBall); // Visual feedback - flash original ball green tween(bouncingCircle, { tint: 0x00ff00 }, { duration: 200, onFinish: function onFinish() { tween(bouncingCircle, { tint: 0xffffff }, { duration: 200 }); } }); // Remove double ball orb doubleBallOrb.destroy(); doubleBallOrbs.splice(d, 1); } } // Check slow ball orb collisions with paddle for (var s = slowBallOrbs.length - 1; s >= 0; s--) { var slowBallOrb = slowBallOrbs[s]; if (slowBallOrb.intersects(paddle)) { // Slow down all balls var slowMultiplier = 0.7; for (var circleIndex = 0; circleIndex < bouncingCircles.length; circleIndex++) { var circle = bouncingCircles[circleIndex]; circle.velocityX *= slowMultiplier; circle.velocityY *= slowMultiplier; // Visual feedback - flash ball orange tween(circle, { tint: 0xff6600 }, { duration: 200, onFinish: function onFinish() { tween(circle, { tint: 0xffffff }, { duration: 200 }); } }); } // Remove slow ball orb slowBallOrb.destroy(); slowBallOrbs.splice(s, 1); } } // Check enlarge paddle orb collisions with paddle for (var e = enlargePaddleOrbs.length - 1; e >= 0; e--) { var enlargePaddleOrb = enlargePaddleOrbs[e]; if (enlargePaddleOrb.intersects(paddle)) { // Enlarge paddle tween(paddle, { scaleX: 1.5 }, { duration: 300, easing: tween.easeOut }); // Visual feedback - flash paddle blue tween(paddle, { tint: 0x0066ff }, { duration: 200, onFinish: function onFinish() { tween(paddle, { tint: 0xffffff }, { duration: 200 }); } }); // Remove enlarge paddle orb enlargePaddleOrb.destroy(); enlargePaddleOrbs.splice(e, 1); } } // Check if any ball hits bottom area and remove it for (var circleIndex = bouncingCircles.length - 1; circleIndex >= 0; circleIndex--) { var circle = bouncingCircles[circleIndex]; if (circle.y >= 2700) { circle.destroy(); bouncingCircles.splice(circleIndex, 1); } } // Game over if no balls left if (bouncingCircles.length === 0) { LK.showGameOver(); return; } };
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var BlueBlock = Container.expand(function () {
var self = Container.call(this);
var blockGraphics = self.attachAsset('blueBlock', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var BouncingCircle = Container.expand(function () {
var self = Container.call(this);
var circleGraphics = self.attachAsset('bouncingCircle', {
anchorX: 0.5,
anchorY: 0.5
});
// Velocity properties
self.velocityX = 15;
self.velocityY = 13;
self.update = function () {
// Move the circle
self.x += self.velocityX;
self.y += self.velocityY;
// Check collision with blue blocks
for (var i = blocks.length - 1; i >= 0; i--) {
var block = blocks[i];
var ballHit = false;
// Check collision with all bouncing circles
for (var circleIndex = 0; circleIndex < bouncingCircles.length; circleIndex++) {
var circle = bouncingCircles[circleIndex];
if (circle.intersects(block)) {
ballHit = true;
break;
}
}
if (ballHit) {
// Play blue block sound and additional sounds
LK.getSound('sonidodebloqueazul').play();
var additionalSounds = ['q', 'w', 'e', 'r', 't'];
var randomAdditionalSound = additionalSounds[Math.floor(Math.random() * additionalSounds.length)];
LK.getSound(randomAdditionalSound).play();
// Block destroyed
// Increment score
score += 10;
scoreTxt.setText('Score: ' + score);
// Add expansion animation to bouncing circle
tween(self, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeIn
});
}
});
// Spawn red block at random position with minimum distance from other blocks
var newRedBlock = game.addChild(new RedBlock());
var validPosition = false;
var attempts = 0;
while (!validPosition && attempts < 50) {
newRedBlock.x = Math.random() * (2048 - 120) + 60; // Random X within screen bounds
newRedBlock.y = Math.random() * 800 + 200; // Random Y in upper part of screen
validPosition = true;
// Check distance from all existing blue blocks
for (var b = 0; b < blocks.length; b++) {
var existingBlock = blocks[b];
var dx = newRedBlock.x - existingBlock.x;
var dy = newRedBlock.y - existingBlock.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 200) {
// Minimum distance of 200 pixels
validPosition = false;
break;
}
}
// Check distance from all existing red blocks
for (var r = 0; r < redBlocks.length; r++) {
var existingRedBlock = redBlocks[r];
var dx = newRedBlock.x - existingRedBlock.x;
var dy = newRedBlock.y - existingRedBlock.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 200) {
// Minimum distance of 200 pixels
validPosition = false;
break;
}
}
// Check distance from all existing green blocks
for (var g = 0; g < greenBlocks.length; g++) {
var existingGreenBlock = greenBlocks[g];
var dx = newRedBlock.x - existingGreenBlock.x;
var dy = newRedBlock.y - existingGreenBlock.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 200) {
// Minimum distance of 200 pixels
validPosition = false;
break;
}
}
// Check distance from all existing purple blocks
for (var p = 0; p < purpleBlocks.length; p++) {
var existingPurpleBlock = purpleBlocks[p];
var dx = newRedBlock.x - existingPurpleBlock.x;
var dy = newRedBlock.y - existingPurpleBlock.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 200) {
// Minimum distance of 200 pixels
validPosition = false;
break;
}
}
attempts++;
}
redBlocks.push(newRedBlock);
// 20% chance to spawn power orb
if (Math.random() < 0.2) {
var powerOrb = game.addChild(new PowerOrb());
powerOrb.x = block.x;
powerOrb.y = block.y;
powerOrbs.push(powerOrb);
}
// 20% chance to spawn double ball orb
if (Math.random() < 0.2) {
var doubleBallOrb = game.addChild(new DoubleBallOrb());
doubleBallOrb.x = block.x;
doubleBallOrb.y = block.y;
doubleBallOrbs.push(doubleBallOrb);
}
// 20% chance to spawn slow ball orb
if (Math.random() < 0.2) {
var slowBallOrb = game.addChild(new SlowBallOrb());
slowBallOrb.x = block.x;
slowBallOrb.y = block.y;
slowBallOrbs.push(slowBallOrb);
}
// 20% chance to spawn enlarge paddle orb
if (Math.random() < 0.2) {
var enlargePaddleOrb = game.addChild(new EnlargePaddleOrb());
enlargePaddleOrb.x = block.x;
enlargePaddleOrb.y = block.y;
enlargePaddleOrbs.push(enlargePaddleOrb);
}
// Destroy the block
block.destroy();
blocks.splice(i, 1);
// Reverse ball Y velocity
self.velocityY = -self.velocityY;
break; // Only hit one block per frame
}
}
// Check collision with red blocks
for (var j = redBlocks.length - 1; j >= 0; j--) {
var redBlock = redBlocks[j];
if (self.intersects(redBlock)) {
// Play red block sound and additional sounds
LK.getSound('sonidodebloquerojo').play();
var additionalSounds = ['q', 'w', 'e', 'r', 't'];
var randomAdditionalSound = additionalSounds[Math.floor(Math.random() * additionalSounds.length)];
LK.getSound(randomAdditionalSound).play();
// Block destroyed
// Increment score
score += 15;
scoreTxt.setText('Score: ' + score);
// Add expansion animation to bouncing circle
tween(self, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeIn
});
}
});
// Spawn green block at random position with minimum distance from other blocks
var newGreenBlock = game.addChild(new GreenBlock());
var validPosition = false;
var attempts = 0;
while (!validPosition && attempts < 50) {
newGreenBlock.x = Math.random() * (2048 - 120) + 60; // Random X within screen bounds
newGreenBlock.y = Math.random() * 800 + 200; // Random Y in upper part of screen
validPosition = true;
// Check distance from all existing blue blocks
for (var b = 0; b < blocks.length; b++) {
var existingBlock = blocks[b];
var dx = newGreenBlock.x - existingBlock.x;
var dy = newGreenBlock.y - existingBlock.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 200) {
// Minimum distance of 200 pixels
validPosition = false;
break;
}
}
// Check distance from all existing red blocks
for (var r = 0; r < redBlocks.length; r++) {
var existingRedBlock = redBlocks[r];
var dx = newGreenBlock.x - existingRedBlock.x;
var dy = newGreenBlock.y - existingRedBlock.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 200) {
// Minimum distance of 200 pixels
validPosition = false;
break;
}
}
// Check distance from all existing green blocks
for (var g = 0; g < greenBlocks.length; g++) {
var existingGreenBlock = greenBlocks[g];
var dx = newGreenBlock.x - existingGreenBlock.x;
var dy = newGreenBlock.y - existingGreenBlock.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 200) {
// Minimum distance of 200 pixels
validPosition = false;
break;
}
}
// Check distance from all existing purple blocks
for (var p = 0; p < purpleBlocks.length; p++) {
var existingPurpleBlock = purpleBlocks[p];
var dx = newGreenBlock.x - existingPurpleBlock.x;
var dy = newGreenBlock.y - existingPurpleBlock.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 200) {
// Minimum distance of 200 pixels
validPosition = false;
break;
}
}
attempts++;
}
greenBlocks.push(newGreenBlock);
// 20% chance to spawn power orb
if (Math.random() < 0.2) {
var powerOrb = game.addChild(new PowerOrb());
powerOrb.x = redBlock.x;
powerOrb.y = redBlock.y;
powerOrbs.push(powerOrb);
}
// 20% chance to spawn double ball orb
if (Math.random() < 0.2) {
var doubleBallOrb = game.addChild(new DoubleBallOrb());
doubleBallOrb.x = redBlock.x;
doubleBallOrb.y = redBlock.y;
doubleBallOrbs.push(doubleBallOrb);
}
// 20% chance to spawn slow ball orb
if (Math.random() < 0.2) {
var slowBallOrb = game.addChild(new SlowBallOrb());
slowBallOrb.x = redBlock.x;
slowBallOrb.y = redBlock.y;
slowBallOrbs.push(slowBallOrb);
}
// 20% chance to spawn enlarge paddle orb
if (Math.random() < 0.2) {
var enlargePaddleOrb = game.addChild(new EnlargePaddleOrb());
enlargePaddleOrb.x = redBlock.x;
enlargePaddleOrb.y = redBlock.y;
enlargePaddleOrbs.push(enlargePaddleOrb);
}
// Destroy the red block
redBlock.destroy();
redBlocks.splice(j, 1);
// Reverse ball Y velocity
self.velocityY = -self.velocityY;
break; // Only hit one block per frame
}
}
// Check collision with green blocks
for (var k = greenBlocks.length - 1; k >= 0; k--) {
var greenBlock = greenBlocks[k];
if (self.intersects(greenBlock)) {
// Play green block sound and additional sounds
LK.getSound('sonidodebloquerojo').play();
var additionalSounds = ['q', 'w', 'e', 'r', 't'];
var randomAdditionalSound = additionalSounds[Math.floor(Math.random() * additionalSounds.length)];
LK.getSound(randomAdditionalSound).play();
// Block destroyed
// Increment score
score += 20;
scoreTxt.setText('Score: ' + score);
// Add expansion animation to bouncing circle
tween(self, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeIn
});
}
});
// Spawn purple block at random position with minimum distance from other blocks
var newPurpleBlock = game.addChild(new PurpleBlock());
var validPosition = false;
var attempts = 0;
while (!validPosition && attempts < 50) {
newPurpleBlock.x = Math.random() * (2048 - 120) + 60; // Random X within screen bounds
newPurpleBlock.y = Math.random() * 800 + 200; // Random Y in upper part of screen
validPosition = true;
// Check distance from all existing blue blocks
for (var b = 0; b < blocks.length; b++) {
var existingBlock = blocks[b];
var dx = newPurpleBlock.x - existingBlock.x;
var dy = newPurpleBlock.y - existingBlock.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 200) {
// Minimum distance of 200 pixels
validPosition = false;
break;
}
}
// Check distance from all existing red blocks
for (var r = 0; r < redBlocks.length; r++) {
var existingRedBlock = redBlocks[r];
var dx = newPurpleBlock.x - existingRedBlock.x;
var dy = newPurpleBlock.y - existingRedBlock.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 200) {
// Minimum distance of 200 pixels
validPosition = false;
break;
}
}
// Check distance from all existing green blocks
for (var g = 0; g < greenBlocks.length; g++) {
var existingGreenBlock = greenBlocks[g];
var dx = newPurpleBlock.x - existingGreenBlock.x;
var dy = newPurpleBlock.y - existingGreenBlock.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 200) {
// Minimum distance of 200 pixels
validPosition = false;
break;
}
}
// Check distance from all existing purple blocks
for (var p = 0; p < purpleBlocks.length; p++) {
var existingPurpleBlock = purpleBlocks[p];
var dx = newPurpleBlock.x - existingPurpleBlock.x;
var dy = newPurpleBlock.y - existingPurpleBlock.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 200) {
// Minimum distance of 200 pixels
validPosition = false;
break;
}
}
attempts++;
}
purpleBlocks.push(newPurpleBlock);
// 20% chance to spawn power orb
if (Math.random() < 0.2) {
var powerOrb = game.addChild(new PowerOrb());
powerOrb.x = greenBlock.x;
powerOrb.y = greenBlock.y;
powerOrbs.push(powerOrb);
}
// 20% chance to spawn double ball orb
if (Math.random() < 0.2) {
var doubleBallOrb = game.addChild(new DoubleBallOrb());
doubleBallOrb.x = greenBlock.x;
doubleBallOrb.y = greenBlock.y;
doubleBallOrbs.push(doubleBallOrb);
}
// 20% chance to spawn slow ball orb
if (Math.random() < 0.2) {
var slowBallOrb = game.addChild(new SlowBallOrb());
slowBallOrb.x = greenBlock.x;
slowBallOrb.y = greenBlock.y;
slowBallOrbs.push(slowBallOrb);
}
// 20% chance to spawn enlarge paddle orb
if (Math.random() < 0.2) {
var enlargePaddleOrb = game.addChild(new EnlargePaddleOrb());
enlargePaddleOrb.x = greenBlock.x;
enlargePaddleOrb.y = greenBlock.y;
enlargePaddleOrbs.push(enlargePaddleOrb);
}
// Destroy the green block
greenBlock.destroy();
greenBlocks.splice(k, 1);
// Reverse ball Y velocity
self.velocityY = -self.velocityY;
break; // Only hit one block per frame
}
}
// Check collision with purple blocks
for (var l = purpleBlocks.length - 1; l >= 0; l--) {
var purpleBlock = purpleBlocks[l];
if (self.intersects(purpleBlock)) {
// Play purple block sound and additional sounds
LK.getSound('sonidodebloquerojo').play();
var additionalSounds = ['q', 'w', 'e', 'r', 't'];
var randomAdditionalSound = additionalSounds[Math.floor(Math.random() * additionalSounds.length)];
LK.getSound(randomAdditionalSound).play();
// Block destroyed
// Increment score
score += 25;
scoreTxt.setText('Score: ' + score);
// Add expansion animation to bouncing circle
tween(self, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeIn
});
}
});
// 20% chance to spawn power orb
if (Math.random() < 0.2) {
var powerOrb = game.addChild(new PowerOrb());
powerOrb.x = purpleBlock.x;
powerOrb.y = purpleBlock.y;
powerOrbs.push(powerOrb);
}
// 20% chance to spawn double ball orb
if (Math.random() < 0.2) {
var doubleBallOrb = game.addChild(new DoubleBallOrb());
doubleBallOrb.x = purpleBlock.x;
doubleBallOrb.y = purpleBlock.y;
doubleBallOrbs.push(doubleBallOrb);
}
// 20% chance to spawn slow ball orb
if (Math.random() < 0.2) {
var slowBallOrb = game.addChild(new SlowBallOrb());
slowBallOrb.x = purpleBlock.x;
slowBallOrb.y = purpleBlock.y;
slowBallOrbs.push(slowBallOrb);
}
// 20% chance to spawn enlarge paddle orb
if (Math.random() < 0.2) {
var enlargePaddleOrb = game.addChild(new EnlargePaddleOrb());
enlargePaddleOrb.x = purpleBlock.x;
enlargePaddleOrb.y = purpleBlock.y;
enlargePaddleOrbs.push(enlargePaddleOrb);
}
// Destroy the purple block
purpleBlock.destroy();
purpleBlocks.splice(l, 1);
// Reverse ball Y velocity
self.velocityY = -self.velocityY;
break; // Only hit one block per frame
}
}
// Bounce off screen edges
if (self.x <= 25) {
self.x = 25;
self.velocityX = -self.velocityX;
}
if (self.x >= 2048 - 25) {
self.x = 2048 - 25;
self.velocityX = -self.velocityX;
}
if (self.y <= 25) {
self.y = 25;
self.velocityY = -self.velocityY;
}
if (self.y >= 2732 - 25) {
self.y = 2732 - 25;
self.velocityY = -self.velocityY;
}
};
return self;
});
var CornerBlock = Container.expand(function () {
var self = Container.call(this);
var blockGraphics = self.attachAsset('cornerBlock', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x000000
});
// Track collision state for sound triggering
self.lastIntersecting = false;
self.update = function () {
// Check collision with bouncing circle
var currentIntersecting = self.intersects(bouncingCircle);
if (!self.lastIntersecting && currentIntersecting) {
// Collision just started - play random sound (C, A, or G)
var sounds = ['c', 'a', 'g'];
var randomSound = sounds[Math.floor(Math.random() * sounds.length)];
LK.getSound(randomSound).play();
var additionalSounds = ['q', 'w', 'e', 'r', 't'];
var randomAdditionalSound = additionalSounds[Math.floor(Math.random() * additionalSounds.length)];
LK.getSound(randomAdditionalSound).play();
// Add expansion animation to bouncing circle
tween(bouncingCircle, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(bouncingCircle, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeIn
});
}
});
}
self.lastIntersecting = currentIntersecting;
};
return self;
});
var CornerBlockRight = Container.expand(function () {
var self = Container.call(this);
var blockGraphics = self.attachAsset('cornerBlockRight', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x000000
});
// Track collision state for sound triggering
self.lastIntersecting = false;
self.update = function () {
// Check collision with bouncing circle
var currentIntersecting = self.intersects(bouncingCircle);
if (!self.lastIntersecting && currentIntersecting) {
// Collision just started - play random sound (C, A, or G)
var sounds = ['c', 'a', 'g'];
var randomSound = sounds[Math.floor(Math.random() * sounds.length)];
LK.getSound(randomSound).play();
var additionalSounds = ['q', 'w', 'e', 'r', 't'];
var randomAdditionalSound = additionalSounds[Math.floor(Math.random() * additionalSounds.length)];
LK.getSound(randomAdditionalSound).play();
// Add expansion animation to bouncing circle
tween(bouncingCircle, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(bouncingCircle, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeIn
});
}
});
}
self.lastIntersecting = currentIntersecting;
};
return self;
});
var CornerBlockTop = Container.expand(function () {
var self = Container.call(this);
var blockGraphics = self.attachAsset('cornerBlockTop', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x000000
});
// Track collision state for sound triggering
self.lastIntersecting = false;
self.update = function () {
// Check collision with bouncing circle
var currentIntersecting = self.intersects(bouncingCircle);
if (!self.lastIntersecting && currentIntersecting) {
// Collision just started - play random sound (C, A, or G)
var sounds = ['c', 'a', 'g'];
var randomSound = sounds[Math.floor(Math.random() * sounds.length)];
LK.getSound(randomSound).play();
var additionalSounds = ['q', 'w', 'e', 'r', 't'];
var randomAdditionalSound = additionalSounds[Math.floor(Math.random() * additionalSounds.length)];
LK.getSound(randomAdditionalSound).play();
// Add expansion animation to bouncing circle
tween(bouncingCircle, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(bouncingCircle, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeIn
});
}
});
}
self.lastIntersecting = currentIntersecting;
};
return self;
});
var DoubleBallOrb = Container.expand(function () {
var self = Container.call(this);
var orbGraphics = self.attachAsset('doubleBallOrb', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0x00ffff
});
// Fall downward
self.velocityY = 8;
self.update = function () {
self.y += self.velocityY;
// Remove if goes off screen
if (self.y > 2800) {
self.destroy();
// Remove from doubleBallOrbs array
for (var i = doubleBallOrbs.length - 1; i >= 0; i--) {
if (doubleBallOrbs[i] === self) {
doubleBallOrbs.splice(i, 1);
break;
}
}
}
};
return self;
});
var EnlargePaddleOrb = Container.expand(function () {
var self = Container.call(this);
var orbGraphics = self.attachAsset('enlargePaddleOrb', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xff00ff
});
// Fall downward
self.velocityY = 8;
self.update = function () {
self.y += self.velocityY;
// Remove if goes off screen
if (self.y > 2800) {
self.destroy();
// Remove from enlargePaddleOrbs array
for (var i = enlargePaddleOrbs.length - 1; i >= 0; i--) {
if (enlargePaddleOrbs[i] === self) {
enlargePaddleOrbs.splice(i, 1);
break;
}
}
}
};
return self;
});
var GreenBlock = Container.expand(function () {
var self = Container.call(this);
var blockGraphics = self.attachAsset('greenBlock', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
// Cache paddle constants
var Paddle = Container.expand(function () {
var self = Container.call(this);
var paddleGraphics = self.attachAsset('paddle', {
anchorX: 0.5,
anchorY: 0.5
});
self.update = function () {
// Prevent paddle from going through left wall
if (self.x < PADDLE_HALF_WIDTH) {
self.x = PADDLE_HALF_WIDTH;
}
// Prevent paddle from going through right wall
if (self.x > SCREEN_WIDTH - PADDLE_HALF_WIDTH) {
self.x = SCREEN_WIDTH - PADDLE_HALF_WIDTH;
}
};
return self;
});
var PowerOrb = Container.expand(function () {
var self = Container.call(this);
var orbGraphics = self.attachAsset('powerOrb', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xffff00
});
// Fall downward
self.velocityY = 8;
self.update = function () {
self.y += self.velocityY;
// Remove if goes off screen
if (self.y > 2800) {
self.destroy();
// Remove from powerOrbs array
for (var i = powerOrbs.length - 1; i >= 0; i--) {
if (powerOrbs[i] === self) {
powerOrbs.splice(i, 1);
break;
}
}
}
};
return self;
});
var PurpleBlock = Container.expand(function () {
var self = Container.call(this);
var blockGraphics = self.attachAsset('purpleBlock', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var RedBlock = Container.expand(function () {
var self = Container.call(this);
var blockGraphics = self.attachAsset('redBlock', {
anchorX: 0.5,
anchorY: 0.5
});
return self;
});
var SlowBallOrb = Container.expand(function () {
var self = Container.call(this);
var orbGraphics = self.attachAsset('slowBallOrb', {
anchorX: 0.5,
anchorY: 0.5,
tint: 0xff0000
});
// Fall downward
self.velocityY = 8;
self.update = function () {
self.y += self.velocityY;
// Remove if goes off screen
if (self.y > 2800) {
self.destroy();
// Remove from slowBallOrbs array
for (var i = slowBallOrbs.length - 1; i >= 0; i--) {
if (slowBallOrbs[i] === self) {
slowBallOrbs.splice(i, 1);
break;
}
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Add scattered musical wave symbols across the background
var musicalWaves = [];
for (var i = 0; i < 20; i++) {
var waveType = 'musicalWave' + (Math.floor(Math.random() * 4) + 1);
var wave = game.addChild(LK.getAsset(waveType, {
anchorX: 0.5,
anchorY: 0.5,
x: Math.random() * 2048,
y: Math.random() * 2732,
alpha: 0.3,
rotation: Math.random() * Math.PI * 2
}));
musicalWaves.push(wave);
}
// Add scattered musical notes across the background
var musicalNotes = [];
for (var i = 0; i < 15; i++) {
var noteType = 'musicalNote' + (Math.floor(Math.random() * 3) + 1);
var note = game.addChild(LK.getAsset(noteType, {
anchorX: 0.5,
anchorY: 0.5,
x: Math.random() * 2048,
y: Math.random() * 2732,
alpha: 0.25,
rotation: Math.random() * Math.PI * 2
}));
musicalNotes.push(note);
}
// Add staff lines across the background
var staffLines = [];
for (var i = 0; i < 12; i++) {
var staffType = 'staffLine' + (Math.floor(Math.random() * 3) + 1);
var staff = game.addChild(LK.getAsset(staffType, {
anchorX: 0.5,
anchorY: 0.5,
x: Math.random() * 2048,
y: Math.random() * 2732,
alpha: 0.2,
rotation: Math.random() * Math.PI * 0.5
}));
staffLines.push(staff);
}
// Add treble clefs scattered in the background
var trebleClefs = [];
for (var i = 0; i < 8; i++) {
var clef = game.addChild(LK.getAsset('trebleClef', {
anchorX: 0.5,
anchorY: 0.5,
x: Math.random() * 2048,
y: Math.random() * 2732,
alpha: 0.15,
rotation: Math.random() * Math.PI * 2
}));
trebleClefs.push(clef);
}
// Add scattered background circles
var backgroundCircles = [];
for (var i = 0; i < 40; i++) {
var circleType = 'backgroundCircle' + (Math.floor(Math.random() * 6) + 1);
var circle = game.addChild(LK.getAsset(circleType, {
anchorX: 0.5,
anchorY: 0.5,
x: Math.random() * 2048,
y: Math.random() * 2732,
alpha: 0.1
}));
backgroundCircles.push(circle);
}
// Cache paddle constants
var PADDLE_HALF_WIDTH = 150;
var SCREEN_WIDTH = 2048;
var blocks = [];
var redBlocks = [];
var greenBlocks = [];
var purpleBlocks = [];
var powerOrbs = [];
var doubleBallOrbs = [];
var slowBallOrbs = [];
var enlargePaddleOrbs = [];
var bouncingCircles = [];
var paddleCollisions = 0;
var score = 0;
var bouncingCircle = game.addChild(new BouncingCircle());
bouncingCircle.x = 1024;
bouncingCircle.y = 2550; // Position above paddle
bouncingCircle.lastIntersecting = false;
bouncingCircles.push(bouncingCircle);
var paddle = game.addChild(new Paddle());
paddle.x = 1024;
paddle.y = 2600;
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
game.move = function (x, y, obj) {
paddle.x = x;
};
// Add corner block covering entire left side of screen
var cornerBlock = game.addChild(new CornerBlock());
cornerBlock.x = 10; // Position at left edge
cornerBlock.y = 1366; // Center vertically (half of 2732)
// Add corner block covering entire right side of screen
var cornerBlockRight = game.addChild(new CornerBlockRight());
cornerBlockRight.x = 2038; // Position at right edge
cornerBlockRight.y = 1366; // Center vertically (half of 2732)
// Add corner block covering entire top side of screen
var cornerBlockTop = game.addChild(new CornerBlockTop());
cornerBlockTop.x = 1024; // Center horizontally (half of 2048)
cornerBlockTop.y = 10; // Position at top edge
// Play background music
LK.playMusic('musica');
game.update = function () {
// Track ball-paddle collision state transitions
var currentIntersecting = bouncingCircle.intersects(paddle);
if (!bouncingCircle.lastIntersecting && currentIntersecting) {
// Collision just started - push ball above paddle and reverse Y velocity
bouncingCircle.y = paddle.y - 20 - 25;
bouncingCircle.velocityY = -Math.abs(bouncingCircle.velocityY);
// Increment paddle collision counter
paddleCollisions++;
// Play random sound (C, A, or G)
var sounds = ['c', 'a', 'g'];
var randomSound = sounds[Math.floor(Math.random() * sounds.length)];
LK.getSound(randomSound).play();
var additionalSounds = ['q', 'w', 'e', 'r', 't'];
var randomAdditionalSound = additionalSounds[Math.floor(Math.random() * additionalSounds.length)];
LK.getSound(randomAdditionalSound).play();
// Add expansion animation to bouncing circle
tween(bouncingCircle, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(bouncingCircle, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.easeIn
});
}
});
// Add shake animation to paddle
var shakeDistance = 10;
var originalX = paddle.x;
tween(paddle, {
x: originalX - shakeDistance
}, {
duration: 50,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(paddle, {
x: originalX + shakeDistance
}, {
duration: 50,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(paddle, {
x: originalX - shakeDistance * 0.5
}, {
duration: 40,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(paddle, {
x: originalX + shakeDistance * 0.5
}, {
duration: 40,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(paddle, {
x: originalX
}, {
duration: 30,
easing: tween.easeIn
});
}
});
}
});
}
});
}
});
// Spawn new blue block at random position with minimum distance from other blocks
var newBlock = game.addChild(new BlueBlock());
var validPosition = false;
var attempts = 0;
while (!validPosition && attempts < 50) {
newBlock.x = Math.random() * (2048 - 120) + 60; // Random X within screen bounds
newBlock.y = Math.random() * 800 + 200; // Random Y in upper part of screen
validPosition = true;
// Check distance from all existing blue blocks
for (var b = 0; b < blocks.length; b++) {
var existingBlock = blocks[b];
var dx = newBlock.x - existingBlock.x;
var dy = newBlock.y - existingBlock.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 200) {
// Minimum distance of 200 pixels
validPosition = false;
break;
}
}
// Check distance from all existing red blocks
for (var r = 0; r < redBlocks.length; r++) {
var existingRedBlock = redBlocks[r];
var dx = newBlock.x - existingRedBlock.x;
var dy = newBlock.y - existingRedBlock.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 200) {
// Minimum distance of 200 pixels
validPosition = false;
break;
}
}
// Check distance from all existing green blocks
for (var g = 0; g < greenBlocks.length; g++) {
var existingGreenBlock = greenBlocks[g];
var dx = newBlock.x - existingGreenBlock.x;
var dy = newBlock.y - existingGreenBlock.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 200) {
// Minimum distance of 200 pixels
validPosition = false;
break;
}
}
// Check distance from all existing purple blocks
for (var p = 0; p < purpleBlocks.length; p++) {
var existingPurpleBlock = purpleBlocks[p];
var dx = newBlock.x - existingPurpleBlock.x;
var dy = newBlock.y - existingPurpleBlock.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 200) {
// Minimum distance of 200 pixels
validPosition = false;
break;
}
}
attempts++;
}
blocks.push(newBlock);
}
bouncingCircle.lastIntersecting = currentIntersecting;
// Check power orb collisions with paddle
for (var k = powerOrbs.length - 1; k >= 0; k--) {
var powerOrb = powerOrbs[k];
if (powerOrb.intersects(paddle)) {
// Increase ball speed for all balls
var speedMultiplier = 1.5;
for (var circleIndex = 0; circleIndex < bouncingCircles.length; circleIndex++) {
var circle = bouncingCircles[circleIndex];
circle.velocityX *= speedMultiplier;
circle.velocityY *= speedMultiplier;
// Visual feedback - flash ball green
tween(circle, {
tint: 0x00ff00
}, {
duration: 200,
onFinish: function onFinish() {
tween(circle, {
tint: 0xffffff
}, {
duration: 200
});
}
});
}
// Remove power orb
powerOrb.destroy();
powerOrbs.splice(k, 1);
}
}
// Check double ball orb collisions with paddle
for (var d = doubleBallOrbs.length - 1; d >= 0; d--) {
var doubleBallOrb = doubleBallOrbs[d];
if (doubleBallOrb.intersects(paddle)) {
// Create new bouncing ball
var newBall = game.addChild(new BouncingCircle());
newBall.x = bouncingCircle.x + 50;
newBall.y = bouncingCircle.y;
newBall.velocityX = -bouncingCircle.velocityX;
newBall.velocityY = bouncingCircle.velocityY;
newBall.lastIntersecting = false;
bouncingCircles.push(newBall);
// Visual feedback - flash original ball green
tween(bouncingCircle, {
tint: 0x00ff00
}, {
duration: 200,
onFinish: function onFinish() {
tween(bouncingCircle, {
tint: 0xffffff
}, {
duration: 200
});
}
});
// Remove double ball orb
doubleBallOrb.destroy();
doubleBallOrbs.splice(d, 1);
}
}
// Check slow ball orb collisions with paddle
for (var s = slowBallOrbs.length - 1; s >= 0; s--) {
var slowBallOrb = slowBallOrbs[s];
if (slowBallOrb.intersects(paddle)) {
// Slow down all balls
var slowMultiplier = 0.7;
for (var circleIndex = 0; circleIndex < bouncingCircles.length; circleIndex++) {
var circle = bouncingCircles[circleIndex];
circle.velocityX *= slowMultiplier;
circle.velocityY *= slowMultiplier;
// Visual feedback - flash ball orange
tween(circle, {
tint: 0xff6600
}, {
duration: 200,
onFinish: function onFinish() {
tween(circle, {
tint: 0xffffff
}, {
duration: 200
});
}
});
}
// Remove slow ball orb
slowBallOrb.destroy();
slowBallOrbs.splice(s, 1);
}
}
// Check enlarge paddle orb collisions with paddle
for (var e = enlargePaddleOrbs.length - 1; e >= 0; e--) {
var enlargePaddleOrb = enlargePaddleOrbs[e];
if (enlargePaddleOrb.intersects(paddle)) {
// Enlarge paddle
tween(paddle, {
scaleX: 1.5
}, {
duration: 300,
easing: tween.easeOut
});
// Visual feedback - flash paddle blue
tween(paddle, {
tint: 0x0066ff
}, {
duration: 200,
onFinish: function onFinish() {
tween(paddle, {
tint: 0xffffff
}, {
duration: 200
});
}
});
// Remove enlarge paddle orb
enlargePaddleOrb.destroy();
enlargePaddleOrbs.splice(e, 1);
}
}
// Check if any ball hits bottom area and remove it
for (var circleIndex = bouncingCircles.length - 1; circleIndex >= 0; circleIndex--) {
var circle = bouncingCircles[circleIndex];
if (circle.y >= 2700) {
circle.destroy();
bouncingCircles.splice(circleIndex, 1);
}
}
// Game over if no balls left
if (bouncingCircles.length === 0) {
LK.showGameOver();
return;
}
};