User prompt
Make title screen and all UI 3x bigger and make it so the death message does pop up ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Make a logo that I can customize and the death messages don’t show up when I lose
User prompt
Make the death screen be able to say about 100 different and funny death messages such as “you died, oh wait, noooooo :(“
User prompt
Add a pause screen with the option of going back to the main menu
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'LK.effects.flashObject(turret, 0xffffff, 200);' Line Number: 1023
User prompt
Fix everything related to bullet amount
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'var velocity = turret.getShootVelocity();' Line Number: 986
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'bullet.x = turret.x;' Line Number: 976
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'shotsTxt.setText('Shots: ' + shotsRemaining);' Line Number: 968
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'shotsTxt.setText('Shots: ' + shotsRemaining);' Line Number: 965
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'shotsTxt.setText('Shots: ' + shotsRemaining);' Line Number: 965
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'shotsTxt.setText('Shots: ' + shotsRemaining);' Line Number: 963
User prompt
Make baby mod literally impossible to lose and another difficulty called impossible mode where it is impossible to win do whatever in impossible. Also in baby if you lose make it say “aww you lost, that’s cute” and make it give you another life. Also add death screens and a title screen with a logo.
User prompt
Create baby mode which make the targets 5x larger and adds a bunch of powerups. Also code in a bunch of powerups and a lucky block that if you shoot it could give you a random one ↪💡 Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'var power = Math.min(turret.maxPower, dragDistance / 50);' Line Number: 608
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'turret.updateRotation(angle);' Line Number: 588
User prompt
Please fix the bug: 'Script error.' in or related to this line: 'var dx = x - turret.x;' Line Number: 557
User prompt
Please fix the bug: 'storage.getItem is not a function. (In 'storage.getItem('bulletBounce_difficulty')', 'storage.getItem' is undefined)' in or related to this line: 'var savedDifficulty = storage.getItem('bulletBounce_difficulty');' Line Number: 565 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Difficulty selection
User prompt
Make levels random and make the ball bigger
User prompt
Replace the ball with https://upit.com/#
Code edit (1 edits merged)
Please save this source code
User prompt
Bullet Bounce
Initial prompt
Gun. Do whatever you want with that.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1"); /**** * Classes ****/ var AimLine = Container.expand(function () { var self = Container.call(this); var line = self.attachAsset('aimLine', { anchorX: 0.5, anchorY: 0 }); self.update = function (angle, length) { line.rotation = angle; line.height = length; }; return self; }); var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('ball', { anchorX: 0.5, anchorY: 0.5, rotation: 0 }); self.speedX = 0; self.speedY = 0; self.bounces = 0; self.isExplosive = false; // Special effect for explosive bullets if (typeof activePowerUps !== 'undefined' && activePowerUps.explosive) { bulletGraphics.tint = 0xFF0000; } // Set max bounces based on game difficulty if (typeof gameDifficulty !== 'undefined') { switch (gameDifficulty) { case "easy": self.maxBounces = 10; // More bounces for easy mode break; case "normal": self.maxBounces = 8; break; case "hard": self.maxBounces = 5; // Fewer bounces for hard mode break; default: self.maxBounces = 8; } } else { self.maxBounces = 8; // Default value } self.isActive = true; self.update = function () { if (!self.isActive) { return; } // Apply velocity self.x += self.speedX; self.y += self.speedY; // Apply a small rotation for visual effect bulletGraphics.rotation += 0.05; // Check for wall collisions if (self.x < 30 || self.x > 2018) { self.speedX *= -0.9; // Lose some energy on bounce if (self.x < 30) { self.x = 30; } if (self.x > 2018) { self.x = 2018; } self.bounces++; LK.getSound('bounce').play(); } if (self.y < 30 || self.y > 2702) { self.speedY *= -0.9; // Lose some energy on bounce if (self.y < 30) { self.y = 30; } if (self.y > 2702) { self.y = 2702; } self.bounces++; LK.getSound('bounce').play(); } // Check if bullet should be removed if (self.bounces >= self.maxBounces || Math.abs(self.speedX) < 0.5 && Math.abs(self.speedY) < 0.5) { self.isActive = false; } }; return self; }); var Difficulty = Container.expand(function () { var self = Container.call(this); // Button base size and spacing var buttonWidth = 300; var buttonHeight = 100; var spacing = 30; // Create title var titleText = new Text2('SELECT DIFFICULTY', { size: 80, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0); titleText.y = -200; self.addChild(titleText); // Create difficulty buttons var easyButton = createButton('EASY', -buttonWidth - spacing, -50, 0x44AA44); var normalButton = createButton('NORMAL', 0, -50, 0x4477AA); var hardButton = createButton('HARD', buttonWidth + spacing, -50, 0xAA4444); var babyButton = createButton('BABY', 0, 100, 0xFF55FF); self.addChild(easyButton); self.addChild(normalButton); self.addChild(hardButton); self.addChild(babyButton); function createButton(text, xPos, yPos, color) { var button = new Container(); // Button background var bg = button.attachAsset('powerMeter', { anchorX: 0.5, anchorY: 0.5, width: buttonWidth, height: buttonHeight, tint: color }); // Button text var txt = new Text2(text, { size: 50, fill: 0xFFFFFF }); txt.anchor.set(0.5, 0.5); button.addChild(txt); // Position button button.x = xPos; button.y = yPos; // Add interaction button.down = function () { selectDifficulty(text.toLowerCase()); }; return button; } function selectDifficulty(level) { // Set difficulty and hide selector gameDifficulty = level; self.visible = false; // Set baby mode isBabyMode = level === "baby"; // Save selected difficulty storage.bulletBounce_difficulty = level; // Start the game with selected difficulty initGame(); } return self; }); var LuckyBlock = Container.expand(function () { var self = Container.call(this); var blockGraphics = self.attachAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, width: 80, height: 80, tint: 0xFFD700 // Gold color }); // Question mark text var questionMark = new Text2("?", { size: 50, fill: 0x000000 }); questionMark.anchor.set(0.5, 0.5); self.addChild(questionMark); self.isHit = false; // Add visual effect - rotating self.update = function () { questionMark.rotation = Math.sin(LK.ticks * 0.05) * 0.2; blockGraphics.rotation = Math.sin(LK.ticks * 0.03) * 0.1; }; self.hit = function () { if (self.isHit) { return; } self.isHit = true; LK.effects.flashObject(self, 0xffffff, 300); // Animation for breaking tween(blockGraphics, { alpha: 0, scaleX: 1.5, scaleY: 1.5 }, { duration: 500, easing: tween.easeOut }); tween(questionMark, { alpha: 0, scaleX: 0.2, scaleY: 0.2 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { // Spawn random powerup spawnRandomPowerUp(self.x, self.y); self.visible = false; } }); }; return self; }); var PowerMeter = Container.expand(function () { var self = Container.call(this); var meterBg = self.attachAsset('powerMeter', { anchorX: 0, anchorY: 0.5, tint: 0x444444 }); var meterFill = self.attachAsset('powerMeter', { anchorX: 0, anchorY: 0.5, scaleX: 0.5 }); self.setPower = function (power, maxPower) { meterFill.scaleX = power / maxPower; }; return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); self.type = ""; self.isCollected = false; // Define powerup sizes and colors var types = { "multishot": { color: 0xff5500, text: "3x" }, "bigball": { color: 0x00aaff, text: "BIG" }, "slowmotion": { color: 0xaa00ff, text: "SLOW" }, "extralife": { color: 0xff0055, text: "LIFE" }, "explosive": { color: 0xff0000, text: "BOOM" } }; // Background circle var bg = self.attachAsset('centerCircle', { anchorX: 0.5, anchorY: 0.5, width: 60, height: 60 }); // Text label var label = new Text2("", { size: 25, fill: 0xFFFFFF }); label.anchor.set(0.5, 0.5); self.addChild(label); self.setType = function (powerupType) { self.type = powerupType; bg.tint = types[powerupType].color; label.setText(types[powerupType].text); // Add visual effect - pulsing self.update = function () { var pulse = Math.sin(LK.ticks * 0.05) * 0.1 + 1; bg.scale.set(pulse, pulse); }; }; self.collect = function () { if (self.isCollected) { return; } self.isCollected = true; LK.effects.flashObject(self, 0xffffff, 300); // Animation for collection tween(self, { alpha: 0, scaleX: 0.2, scaleY: 0.2 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { self.visible = false; } }); // Apply powerup effect based on type applyPowerUpEffect(self.type); }; self.down = function () { // Allow clicking on powerups too (mobile friendly) self.collect(); }; return self; }); var Target = Container.expand(function () { var self = Container.call(this); var targetGraphics = self.attachAsset('target', { anchorX: 0.5, anchorY: 0.5 }); // Make targets 5x larger in baby mode if (typeof isBabyMode !== 'undefined' && isBabyMode) { targetGraphics.scale.set(5, 5); } self.isHit = false; self.hit = function () { if (self.isHit) { return; } self.isHit = true; LK.getSound('targetHit').play(); LK.effects.flashObject(self, 0xffffff, 300); tween(targetGraphics, { alpha: 0, scaleX: 0.2, scaleY: 0.2 }, { duration: 500, easing: tween.easeOut, onFinish: function onFinish() { targetGraphics.visible = false; } }); // Increment score LK.setScore(LK.getScore() + 100); }; return self; }); var Turret = Container.expand(function () { var self = Container.call(this); var base = self.attachAsset('turret', { anchorX: 0.5, anchorY: 0.5 }); var barrel = self.attachAsset('turretBarrel', { anchorX: 0, anchorY: 0.5, x: 0, y: 0 }); self.angle = 0; self.power = 10; self.maxPower = 20; self.isDragging = false; self.updateRotation = function (angle) { self.angle = angle; barrel.rotation = angle; }; self.setPower = function (power) { self.power = Math.max(5, Math.min(self.maxPower, power)); }; self.getShootVelocity = function () { return { x: Math.cos(self.angle) * self.power, y: Math.sin(self.angle) * self.power }; }; return self; }); var Wall = Container.expand(function () { var self = Container.call(this); var wallGraphics = self.attachAsset('wall', { anchorX: 0.5, anchorY: 0.5 }); return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x222222 }); /**** * Game Code ****/ // Game variables var turret; var bullets = []; var targets = []; var walls = []; var powerups = []; var luckyBlocks = []; var powerMeter; var aimLine; var isDragging = false; var dragStartX, dragStartY; var currentLevel = 1; var shotsRemaining = 5; var totalTargets = 0; var targetsHit = 0; var difficultySelector; var gameDifficulty = "normal"; // Default difficulty var isBabyMode = false; var activePowerUps = { multishot: false, bigball: false, slowmotion: false, explosive: false }; var powerUpTimers = {}; // Function to apply powerup effects function applyPowerUpEffect(type) { switch (type) { case "multishot": activePowerUps.multishot = true; powerUpTimers.multishot = LK.setTimeout(function () { activePowerUps.multishot = false; }, 15000); // 15 seconds break; case "bigball": activePowerUps.bigball = true; powerUpTimers.bigball = LK.setTimeout(function () { activePowerUps.bigball = false; }, 20000); // 20 seconds break; case "slowmotion": activePowerUps.slowmotion = true; powerUpTimers.slowmotion = LK.setTimeout(function () { activePowerUps.slowmotion = false; }, 10000); // 10 seconds break; case "extralife": shotsRemaining += 3; shotsTxt.setText('Shots: ' + shotsRemaining); break; case "explosive": activePowerUps.explosive = true; powerUpTimers.explosive = LK.setTimeout(function () { activePowerUps.explosive = false; }, 12000); // 12 seconds break; } } // Function to create a random powerup function createPowerUp(x, y, type) { var powerup = new PowerUp(); powerup.x = x; powerup.y = y; powerup.setType(type || getRandomPowerUpType()); game.addChild(powerup); powerups.push(powerup); return powerup; } // Function to create a lucky block function createLuckyBlock(x, y) { var luckyBlock = new LuckyBlock(); luckyBlock.x = x; luckyBlock.y = y; game.addChild(luckyBlock); luckyBlocks.push(luckyBlock); return luckyBlock; } // Function to get random powerup type function getRandomPowerUpType() { var types = ["multishot", "bigball", "slowmotion", "extralife", "explosive"]; return types[Math.floor(Math.random() * types.length)]; } // Function to spawn random powerup at position function spawnRandomPowerUp(x, y) { createPowerUp(x, y); } // UI elements var shotsTxt; var levelTxt; function initGame() { // Check if game is starting fresh or resuming from difficulty selection if (!difficultySelector || !difficultySelector.visible) { // Create turret turret = new Turret(); turret.x = 100; turret.y = 2732 - 100; game.addChild(turret); // Create aim line aimLine = new AimLine(); aimLine.x = turret.x; aimLine.y = turret.y; game.addChild(aimLine); // Create power meter powerMeter = new PowerMeter(); powerMeter.x = 50; powerMeter.y = 2732 - 200; game.addChild(powerMeter); powerMeter.setPower(turret.power, turret.maxPower); // Setup UI shotsTxt = new Text2('Shots: ' + shotsRemaining, { size: 50, fill: 0xFFFFFF }); shotsTxt.anchor.set(0, 0); LK.gui.topRight.addChild(shotsTxt); levelTxt = new Text2('Level: ' + currentLevel, { size: 50, fill: 0xFFFFFF }); levelTxt.anchor.set(0, 0); LK.gui.top.addChild(levelTxt); // Score text var scoreTxt = new Text2('Score: 0', { size: 50, fill: 0xFFFFFF }); scoreTxt.anchor.set(1, 0); LK.gui.topRight.addChild(scoreTxt); // Update score display LK.setInterval(function () { scoreTxt.setText('Score: ' + LK.getScore()); }, 100); // Load level with current difficulty loadLevel(currentLevel); // Play background music LK.playMusic('gameMusic'); } } function loadLevel(level) { // Clear any existing level elements clearLevel(); // Update level display levelTxt.setText('Level: ' + level); // Reset shots based on difficulty switch (gameDifficulty) { case "baby": shotsRemaining = 10 + level; break; case "easy": shotsRemaining = 5 + level; break; case "normal": shotsRemaining = 3 + level; break; case "hard": shotsRemaining = 2 + Math.floor(level / 2); break; default: shotsRemaining = 3 + level; } shotsTxt.setText('Shots: ' + shotsRemaining); // Clear powerups and lucky blocks for (var i = powerups.length - 1; i >= 0; i--) { game.removeChild(powerups[i]); powerups.splice(i, 1); } for (var i = luckyBlocks.length - 1; i >= 0; i--) { game.removeChild(luckyBlocks[i]); luckyBlocks.splice(i, 1); } // Reset active powerups for (var key in activePowerUps) { activePowerUps[key] = false; } for (var key in powerUpTimers) { LK.clearTimeout(powerUpTimers[key]); } // Different level layouts switch (level) { case 1: // Basic level with random targets var targetCount = 3; for (var i = 0; i < targetCount; i++) { createTarget(500 + Math.random() * 1000, 300 + Math.random() * 800); } // Add random walls createWall(500 + Math.random() * 200, 500 + Math.random() * 200, Math.random() * Math.PI / 2); createWall(1300 + Math.random() * 200, 900 + Math.random() * 200, Math.random() * Math.PI / 2); break; case 2: // More complex level with random elements var targetCount = 5; for (var i = 0; i < targetCount; i++) { createTarget(400 + Math.random() * 1200, 400 + Math.random() * 1100); } // Add random walls createWall(400 + Math.random() * 100, 800 + Math.random() * 100, Math.random() * Math.PI / 4); createWall(1500 + Math.random() * 100, 800 + Math.random() * 100, Math.random() * Math.PI / 4); createWall(900 + Math.random() * 200, 300 + Math.random() * 100, Math.PI / 2 + Math.random() * 0.3); createWall(900 + Math.random() * 200, 1400 + Math.random() * 100, Math.PI / 2 + Math.random() * 0.3); break; case 3: // Advanced level with random elements var targetCount = 7; for (var i = 0; i < targetCount; i++) { // Create targets in different quadrants of the screen if (i < 2) { createTarget(300 + Math.random() * 400, 300 + Math.random() * 400); } else if (i < 4) { createTarget(1300 + Math.random() * 400, 300 + Math.random() * 400); } else if (i < 6) { createTarget(300 + Math.random() * 400, 1100 + Math.random() * 400); } else { createTarget(1300 + Math.random() * 400, 1100 + Math.random() * 400); } } // Add walls in a maze-like structure with some randomness createWall(600 + Math.random() * 100, 600 + Math.random() * 100, Math.random() * 0.2); createWall(1300 + Math.random() * 100, 600 + Math.random() * 100, Math.random() * 0.2); createWall(600 + Math.random() * 100, 1200 + Math.random() * 100, Math.random() * 0.2); createWall(1300 + Math.random() * 100, 1200 + Math.random() * 100, Math.random() * 0.2); createWall(1000 + Math.random() * 100, 600 + Math.random() * 100, Math.PI / 2 + Math.random() * 0.2); createWall(1000 + Math.random() * 100, 1200 + Math.random() * 100, Math.PI / 2 + Math.random() * 0.2); break; default: // For levels beyond 3, create a fully random level with more targets and walls // Adjust difficulty based on selected mode var difficultyMultiplier; switch (gameDifficulty) { case "baby": difficultyMultiplier = 0.5; // Even fewer targets and walls for baby mode break; case "easy": difficultyMultiplier = 0.7; // Fewer targets and walls break; case "normal": difficultyMultiplier = 1.0; // Normal difficulty break; case "hard": difficultyMultiplier = 1.5; // More targets and walls break; default: difficultyMultiplier = 1.0; } // Generate random number of targets based on level and difficulty var numTargets = Math.max(2, Math.floor((3 + Math.random() * level * 2) * difficultyMultiplier)); for (var i = 0; i < numTargets; i++) { createTarget(300 + Math.random() * 1400, 300 + Math.random() * 1500); } // Generate random number of walls based on level and difficulty var numWalls = Math.max(2, Math.floor(Math.random() * level * 1.5 * difficultyMultiplier)); for (var i = 0; i < numWalls; i++) { createWall(300 + Math.random() * 1400, 300 + Math.random() * 1500, Math.random() * Math.PI); } // Add powerups - more in baby mode var numPowerups = isBabyMode ? 3 + Math.floor(level / 2) : 1 + Math.floor(level / 3); for (var i = 0; i < numPowerups; i++) { createPowerUp(300 + Math.random() * 1400, 300 + Math.random() * 1500); } // Add lucky blocks var numLuckyBlocks = isBabyMode ? 2 + Math.floor(level / 2) : 1 + Math.floor(level / 4); for (var i = 0; i < numLuckyBlocks; i++) { createLuckyBlock(300 + Math.random() * 1400, 300 + Math.random() * 1500); } break; } // Track targets for win condition totalTargets = targets.length; targetsHit = 0; } function clearLevel() { // Remove all bullets for (var i = bullets.length - 1; i >= 0; i--) { game.removeChild(bullets[i]); bullets.splice(i, 1); } // Remove all targets for (var i = targets.length - 1; i >= 0; i--) { game.removeChild(targets[i]); targets.splice(i, 1); } // Remove all walls for (var i = walls.length - 1; i >= 0; i--) { game.removeChild(walls[i]); walls.splice(i, 1); } } function createTarget(x, y) { var target = new Target(); target.x = x; target.y = y; game.addChild(target); targets.push(target); return target; } function createWall(x, y, rotation) { var wall = new Wall(); wall.x = x; wall.y = y; wall.rotation = rotation; game.addChild(wall); walls.push(wall); return wall; } function fireBullet() { if (shotsRemaining <= 0) { return; } // Decrease shots remaining shotsRemaining--; shotsTxt.setText('Shots: ' + shotsRemaining); // Determine how many bullets to fire based on powerups var bulletCount = activePowerUps.multishot ? 3 : 1; for (var i = 0; i < bulletCount; i++) { // Create new bullet var bullet = new Bullet(); bullet.x = turret.x; bullet.y = turret.y; // Get velocity from turret angle and power var velocity = turret.getShootVelocity(); // If multishot, spread the bullets if (activePowerUps.multishot && bulletCount > 1) { var spreadAngle = (i - 1) * 0.2; // -0.2, 0, 0.2 radians spread var newAngle = Math.atan2(velocity.y, velocity.x) + spreadAngle; var speed = Math.sqrt(velocity.x * velocity.x + velocity.y * velocity.y); bullet.speedX = Math.cos(newAngle) * speed; bullet.speedY = Math.sin(newAngle) * speed; } else { bullet.speedX = velocity.x; bullet.speedY = velocity.y; } // Apply slowmotion powerup if (activePowerUps.slowmotion) { bullet.speedX *= 0.6; bullet.speedY *= 0.6; } // Apply big ball powerup if (activePowerUps.bigball) { bullet.scale.set(2.5, 2.5); } // Apply explosive powerup if needed if (activePowerUps.explosive) { bullet.isExplosive = true; } // Add to game game.addChild(bullet); bullets.push(bullet); } // Play sound LK.getSound('shoot').play(); // Flash turret LK.effects.flashObject(turret, 0xffffff, 200); } function checkCollisions() { // Check all active bullets for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; if (!bullet.isActive) { // Remove inactive bullets game.removeChild(bullet); bullets.splice(i, 1); continue; } // Check for wall collisions for (var j = 0; j < walls.length; j++) { var wall = walls[j]; if (bullet.intersects(wall)) { // Calculate bounce direction based on wall angle var wallAngle = wall.rotation; var normalAngle = wallAngle + Math.PI / 2; // Reflect velocity based on wall normal var speed = Math.sqrt(bullet.speedX * bullet.speedX + bullet.speedY * bullet.speedY); var bulletAngle = Math.atan2(bullet.speedY, bullet.speedX); var reflectionAngle = 2 * normalAngle - bulletAngle; bullet.speedX = Math.cos(reflectionAngle) * speed * 0.8; // Lose some energy bullet.speedY = Math.sin(reflectionAngle) * speed * 0.8; // Move bullet slightly away from wall to prevent multiple collisions bullet.x += bullet.speedX; bullet.y += bullet.speedY; bullet.bounces++; LK.getSound('bounce').play(); } } // Check for target collisions for (var j = 0; j < targets.length; j++) { var target = targets[j]; if (!target.isHit && bullet.intersects(target)) { target.hit(); targetsHit++; // If explosive bullet, create explosion effect if (bullet.isExplosive) { // Hit nearby targets within radius var explosionRadius = 250; for (var k = 0; k < targets.length; k++) { if (j !== k && !targets[k].isHit) { var dx = targets[k].x - target.x; var dy = targets[k].y - target.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < explosionRadius) { targets[k].hit(); targetsHit++; } } } // Visual explosion effect LK.effects.flashScreen(0xFF5500, 200); } // Check if level complete if (targetsHit >= totalTargets) { levelComplete(); } } } // Check for lucky block collisions for (var j = luckyBlocks.length - 1; j >= 0; j--) { var luckyBlock = luckyBlocks[j]; if (!luckyBlock.isHit && bullet.intersects(luckyBlock)) { luckyBlock.hit(); luckyBlocks.splice(j, 1); } } // Check for powerup collisions for (var j = powerups.length - 1; j >= 0; j--) { var powerup = powerups[j]; if (!powerup.isCollected && bullet.intersects(powerup)) { powerup.collect(); powerups.splice(j, 1); } } } } function levelComplete() { LK.setTimeout(function () { // Advance to next level currentLevel++; loadLevel(currentLevel); }, 1000); } function checkGameOver() { // Game over conditions if (shotsRemaining <= 0 && bullets.length === 0) { // Check if any targets left var anyTargetsLeft = false; for (var i = 0; i < targets.length; i++) { if (!targets[i].isHit) { anyTargetsLeft = true; break; } } if (anyTargetsLeft) { // Player has lost LK.setTimeout(function () { LK.showGameOver(); }, 1000); } } } function calculateAimAngle(x, y) { // Calculate angle from turret to mouse/touch point // Check if turret exists before accessing its properties if (!turret) { return 0; // Return default angle if turret doesn't exist yet } var dx = x - turret.x; var dy = y - turret.y; return Math.atan2(dy, dx); } function updateAimLine() { if (turret && aimLine) { aimLine.update(turret.angle, 200); } } // Load previously selected difficulty if available var savedDifficulty = storage.bulletBounce_difficulty; if (savedDifficulty) { gameDifficulty = savedDifficulty; } // Create difficulty selector difficultySelector = new Difficulty(); difficultySelector.x = 2048 / 2; difficultySelector.y = 2732 / 2; game.addChild(difficultySelector); // If we just want to start the game directly with saved difficulty, uncomment this: // difficultySelector.visible = false; // initGame(); // Event handlers game.down = function (x, y, obj) { isDragging = true; dragStartX = x; dragStartY = y; // Set initial angle var angle = calculateAimAngle(x, y); if (turret) { // Add null check to ensure turret exists turret.updateRotation(angle); } updateAimLine(); }; game.move = function (x, y, obj) { if (isDragging) { // Update turret angle var angle = calculateAimAngle(x, y); if (turret) { // Add null check to ensure turret exists turret.updateRotation(angle); } // Calculate power based on drag distance var dx = x - dragStartX; var dy = y - dragStartY; var dragDistance = Math.sqrt(dx * dx + dy * dy); if (turret) { var power = Math.min(turret.maxPower, dragDistance / 50); turret.setPower(power); // Update power meter powerMeter.setPower(turret.power, turret.maxPower); } // Update aim line updateAimLine(); } }; game.up = function (x, y, obj) { if (isDragging) { isDragging = false; fireBullet(); } }; // Game update loop game.update = function () { // Update all bullets for (var i = 0; i < bullets.length; i++) { bullets[i].update(); } // Check for collisions checkCollisions(); // Check for game over checkGameOver(); };
===================================================================
--- original.js
+++ change.js
@@ -28,8 +28,13 @@
});
self.speedX = 0;
self.speedY = 0;
self.bounces = 0;
+ self.isExplosive = false;
+ // Special effect for explosive bullets
+ if (typeof activePowerUps !== 'undefined' && activePowerUps.explosive) {
+ bulletGraphics.tint = 0xFF0000;
+ }
// Set max bounces based on game difficulty
if (typeof gameDifficulty !== 'undefined') {
switch (gameDifficulty) {
case "easy":
@@ -101,14 +106,16 @@
titleText.anchor.set(0.5, 0);
titleText.y = -200;
self.addChild(titleText);
// Create difficulty buttons
- var easyButton = createButton('EASY', -buttonWidth - spacing / 2, 0, 0x44AA44);
- var normalButton = createButton('NORMAL', 0, 0, 0x4477AA);
- var hardButton = createButton('HARD', buttonWidth + spacing / 2, 0, 0xAA4444);
+ var easyButton = createButton('EASY', -buttonWidth - spacing, -50, 0x44AA44);
+ var normalButton = createButton('NORMAL', 0, -50, 0x4477AA);
+ var hardButton = createButton('HARD', buttonWidth + spacing, -50, 0xAA4444);
+ var babyButton = createButton('BABY', 0, 100, 0xFF55FF);
self.addChild(easyButton);
self.addChild(normalButton);
self.addChild(hardButton);
+ self.addChild(babyButton);
function createButton(text, xPos, yPos, color) {
var button = new Container();
// Button background
var bg = button.attachAsset('powerMeter', {
@@ -137,15 +144,70 @@
function selectDifficulty(level) {
// Set difficulty and hide selector
gameDifficulty = level;
self.visible = false;
+ // Set baby mode
+ isBabyMode = level === "baby";
// Save selected difficulty
storage.bulletBounce_difficulty = level;
// Start the game with selected difficulty
initGame();
}
return self;
});
+var LuckyBlock = Container.expand(function () {
+ var self = Container.call(this);
+ var blockGraphics = self.attachAsset('centerCircle', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: 80,
+ height: 80,
+ tint: 0xFFD700 // Gold color
+ });
+ // Question mark text
+ var questionMark = new Text2("?", {
+ size: 50,
+ fill: 0x000000
+ });
+ questionMark.anchor.set(0.5, 0.5);
+ self.addChild(questionMark);
+ self.isHit = false;
+ // Add visual effect - rotating
+ self.update = function () {
+ questionMark.rotation = Math.sin(LK.ticks * 0.05) * 0.2;
+ blockGraphics.rotation = Math.sin(LK.ticks * 0.03) * 0.1;
+ };
+ self.hit = function () {
+ if (self.isHit) {
+ return;
+ }
+ self.isHit = true;
+ LK.effects.flashObject(self, 0xffffff, 300);
+ // Animation for breaking
+ tween(blockGraphics, {
+ alpha: 0,
+ scaleX: 1.5,
+ scaleY: 1.5
+ }, {
+ duration: 500,
+ easing: tween.easeOut
+ });
+ tween(questionMark, {
+ alpha: 0,
+ scaleX: 0.2,
+ scaleY: 0.2
+ }, {
+ duration: 500,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ // Spawn random powerup
+ spawnRandomPowerUp(self.x, self.y);
+ self.visible = false;
+ }
+ });
+ };
+ return self;
+});
var PowerMeter = Container.expand(function () {
var self = Container.call(this);
var meterBg = self.attachAsset('powerMeter', {
anchorX: 0,
@@ -161,14 +223,96 @@
meterFill.scaleX = power / maxPower;
};
return self;
});
+var PowerUp = Container.expand(function () {
+ var self = Container.call(this);
+ self.type = "";
+ self.isCollected = false;
+ // Define powerup sizes and colors
+ var types = {
+ "multishot": {
+ color: 0xff5500,
+ text: "3x"
+ },
+ "bigball": {
+ color: 0x00aaff,
+ text: "BIG"
+ },
+ "slowmotion": {
+ color: 0xaa00ff,
+ text: "SLOW"
+ },
+ "extralife": {
+ color: 0xff0055,
+ text: "LIFE"
+ },
+ "explosive": {
+ color: 0xff0000,
+ text: "BOOM"
+ }
+ };
+ // Background circle
+ var bg = self.attachAsset('centerCircle', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ width: 60,
+ height: 60
+ });
+ // Text label
+ var label = new Text2("", {
+ size: 25,
+ fill: 0xFFFFFF
+ });
+ label.anchor.set(0.5, 0.5);
+ self.addChild(label);
+ self.setType = function (powerupType) {
+ self.type = powerupType;
+ bg.tint = types[powerupType].color;
+ label.setText(types[powerupType].text);
+ // Add visual effect - pulsing
+ self.update = function () {
+ var pulse = Math.sin(LK.ticks * 0.05) * 0.1 + 1;
+ bg.scale.set(pulse, pulse);
+ };
+ };
+ self.collect = function () {
+ if (self.isCollected) {
+ return;
+ }
+ self.isCollected = true;
+ LK.effects.flashObject(self, 0xffffff, 300);
+ // Animation for collection
+ tween(self, {
+ alpha: 0,
+ scaleX: 0.2,
+ scaleY: 0.2
+ }, {
+ duration: 500,
+ easing: tween.easeOut,
+ onFinish: function onFinish() {
+ self.visible = false;
+ }
+ });
+ // Apply powerup effect based on type
+ applyPowerUpEffect(self.type);
+ };
+ self.down = function () {
+ // Allow clicking on powerups too (mobile friendly)
+ self.collect();
+ };
+ return self;
+});
var Target = Container.expand(function () {
var self = Container.call(this);
var targetGraphics = self.attachAsset('target', {
anchorX: 0.5,
anchorY: 0.5
});
+ // Make targets 5x larger in baby mode
+ if (typeof isBabyMode !== 'undefined' && isBabyMode) {
+ targetGraphics.scale.set(5, 5);
+ }
self.isHit = false;
self.hit = function () {
if (self.isHit) {
return;
@@ -246,8 +390,10 @@
var turret;
var bullets = [];
var targets = [];
var walls = [];
+var powerups = [];
+var luckyBlocks = [];
var powerMeter;
var aimLine;
var isDragging = false;
var dragStartX, dragStartY;
@@ -256,8 +402,77 @@
var totalTargets = 0;
var targetsHit = 0;
var difficultySelector;
var gameDifficulty = "normal"; // Default difficulty
+var isBabyMode = false;
+var activePowerUps = {
+ multishot: false,
+ bigball: false,
+ slowmotion: false,
+ explosive: false
+};
+var powerUpTimers = {};
+// Function to apply powerup effects
+function applyPowerUpEffect(type) {
+ switch (type) {
+ case "multishot":
+ activePowerUps.multishot = true;
+ powerUpTimers.multishot = LK.setTimeout(function () {
+ activePowerUps.multishot = false;
+ }, 15000); // 15 seconds
+ break;
+ case "bigball":
+ activePowerUps.bigball = true;
+ powerUpTimers.bigball = LK.setTimeout(function () {
+ activePowerUps.bigball = false;
+ }, 20000); // 20 seconds
+ break;
+ case "slowmotion":
+ activePowerUps.slowmotion = true;
+ powerUpTimers.slowmotion = LK.setTimeout(function () {
+ activePowerUps.slowmotion = false;
+ }, 10000); // 10 seconds
+ break;
+ case "extralife":
+ shotsRemaining += 3;
+ shotsTxt.setText('Shots: ' + shotsRemaining);
+ break;
+ case "explosive":
+ activePowerUps.explosive = true;
+ powerUpTimers.explosive = LK.setTimeout(function () {
+ activePowerUps.explosive = false;
+ }, 12000); // 12 seconds
+ break;
+ }
+}
+// Function to create a random powerup
+function createPowerUp(x, y, type) {
+ var powerup = new PowerUp();
+ powerup.x = x;
+ powerup.y = y;
+ powerup.setType(type || getRandomPowerUpType());
+ game.addChild(powerup);
+ powerups.push(powerup);
+ return powerup;
+}
+// Function to create a lucky block
+function createLuckyBlock(x, y) {
+ var luckyBlock = new LuckyBlock();
+ luckyBlock.x = x;
+ luckyBlock.y = y;
+ game.addChild(luckyBlock);
+ luckyBlocks.push(luckyBlock);
+ return luckyBlock;
+}
+// Function to get random powerup type
+function getRandomPowerUpType() {
+ var types = ["multishot", "bigball", "slowmotion", "extralife", "explosive"];
+ return types[Math.floor(Math.random() * types.length)];
+}
+// Function to spawn random powerup at position
+function spawnRandomPowerUp(x, y) {
+ createPowerUp(x, y);
+}
// UI elements
var shotsTxt;
var levelTxt;
function initGame() {
@@ -315,8 +530,11 @@
// Update level display
levelTxt.setText('Level: ' + level);
// Reset shots based on difficulty
switch (gameDifficulty) {
+ case "baby":
+ shotsRemaining = 10 + level;
+ break;
case "easy":
shotsRemaining = 5 + level;
break;
case "normal":
@@ -328,8 +546,24 @@
default:
shotsRemaining = 3 + level;
}
shotsTxt.setText('Shots: ' + shotsRemaining);
+ // Clear powerups and lucky blocks
+ for (var i = powerups.length - 1; i >= 0; i--) {
+ game.removeChild(powerups[i]);
+ powerups.splice(i, 1);
+ }
+ for (var i = luckyBlocks.length - 1; i >= 0; i--) {
+ game.removeChild(luckyBlocks[i]);
+ luckyBlocks.splice(i, 1);
+ }
+ // Reset active powerups
+ for (var key in activePowerUps) {
+ activePowerUps[key] = false;
+ }
+ for (var key in powerUpTimers) {
+ LK.clearTimeout(powerUpTimers[key]);
+ }
// Different level layouts
switch (level) {
case 1:
// Basic level with random targets
@@ -380,8 +614,11 @@
// For levels beyond 3, create a fully random level with more targets and walls
// Adjust difficulty based on selected mode
var difficultyMultiplier;
switch (gameDifficulty) {
+ case "baby":
+ difficultyMultiplier = 0.5; // Even fewer targets and walls for baby mode
+ break;
case "easy":
difficultyMultiplier = 0.7; // Fewer targets and walls
break;
case "normal":
@@ -402,8 +639,18 @@
var numWalls = Math.max(2, Math.floor(Math.random() * level * 1.5 * difficultyMultiplier));
for (var i = 0; i < numWalls; i++) {
createWall(300 + Math.random() * 1400, 300 + Math.random() * 1500, Math.random() * Math.PI);
}
+ // Add powerups - more in baby mode
+ var numPowerups = isBabyMode ? 3 + Math.floor(level / 2) : 1 + Math.floor(level / 3);
+ for (var i = 0; i < numPowerups; i++) {
+ createPowerUp(300 + Math.random() * 1400, 300 + Math.random() * 1500);
+ }
+ // Add lucky blocks
+ var numLuckyBlocks = isBabyMode ? 2 + Math.floor(level / 2) : 1 + Math.floor(level / 4);
+ for (var i = 0; i < numLuckyBlocks; i++) {
+ createLuckyBlock(300 + Math.random() * 1400, 300 + Math.random() * 1500);
+ }
break;
}
// Track targets for win condition
totalTargets = targets.length;
@@ -449,19 +696,45 @@
}
// Decrease shots remaining
shotsRemaining--;
shotsTxt.setText('Shots: ' + shotsRemaining);
- // Create new bullet
- var bullet = new Bullet();
- bullet.x = turret.x;
- bullet.y = turret.y;
- // Get velocity from turret angle and power
- var velocity = turret.getShootVelocity();
- bullet.speedX = velocity.x;
- bullet.speedY = velocity.y;
- // Add to game
- game.addChild(bullet);
- bullets.push(bullet);
+ // Determine how many bullets to fire based on powerups
+ var bulletCount = activePowerUps.multishot ? 3 : 1;
+ for (var i = 0; i < bulletCount; i++) {
+ // Create new bullet
+ var bullet = new Bullet();
+ bullet.x = turret.x;
+ bullet.y = turret.y;
+ // Get velocity from turret angle and power
+ var velocity = turret.getShootVelocity();
+ // If multishot, spread the bullets
+ if (activePowerUps.multishot && bulletCount > 1) {
+ var spreadAngle = (i - 1) * 0.2; // -0.2, 0, 0.2 radians spread
+ var newAngle = Math.atan2(velocity.y, velocity.x) + spreadAngle;
+ var speed = Math.sqrt(velocity.x * velocity.x + velocity.y * velocity.y);
+ bullet.speedX = Math.cos(newAngle) * speed;
+ bullet.speedY = Math.sin(newAngle) * speed;
+ } else {
+ bullet.speedX = velocity.x;
+ bullet.speedY = velocity.y;
+ }
+ // Apply slowmotion powerup
+ if (activePowerUps.slowmotion) {
+ bullet.speedX *= 0.6;
+ bullet.speedY *= 0.6;
+ }
+ // Apply big ball powerup
+ if (activePowerUps.bigball) {
+ bullet.scale.set(2.5, 2.5);
+ }
+ // Apply explosive powerup if needed
+ if (activePowerUps.explosive) {
+ bullet.isExplosive = true;
+ }
+ // Add to game
+ game.addChild(bullet);
+ bullets.push(bullet);
+ }
// Play sound
LK.getSound('shoot').play();
// Flash turret
LK.effects.flashObject(turret, 0xffffff, 200);
@@ -501,14 +774,48 @@
var target = targets[j];
if (!target.isHit && bullet.intersects(target)) {
target.hit();
targetsHit++;
+ // If explosive bullet, create explosion effect
+ if (bullet.isExplosive) {
+ // Hit nearby targets within radius
+ var explosionRadius = 250;
+ for (var k = 0; k < targets.length; k++) {
+ if (j !== k && !targets[k].isHit) {
+ var dx = targets[k].x - target.x;
+ var dy = targets[k].y - target.y;
+ var distance = Math.sqrt(dx * dx + dy * dy);
+ if (distance < explosionRadius) {
+ targets[k].hit();
+ targetsHit++;
+ }
+ }
+ }
+ // Visual explosion effect
+ LK.effects.flashScreen(0xFF5500, 200);
+ }
// Check if level complete
if (targetsHit >= totalTargets) {
levelComplete();
}
}
}
+ // Check for lucky block collisions
+ for (var j = luckyBlocks.length - 1; j >= 0; j--) {
+ var luckyBlock = luckyBlocks[j];
+ if (!luckyBlock.isHit && bullet.intersects(luckyBlock)) {
+ luckyBlock.hit();
+ luckyBlocks.splice(j, 1);
+ }
+ }
+ // Check for powerup collisions
+ for (var j = powerups.length - 1; j >= 0; j--) {
+ var powerup = powerups[j];
+ if (!powerup.isCollected && bullet.intersects(powerup)) {
+ powerup.collect();
+ powerups.splice(j, 1);
+ }
+ }
}
}
function levelComplete() {
LK.setTimeout(function () {
A ball with fire launching to the left with white painted text that says “BULLET BOUNCE!” At an angle on the ball. Single Game Texture. In-Game asset. 2d. No background. High contrast. No shadows
Metal bar. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Yellow bar. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows