User prompt
Please fix the bug: 'frvr.Sound is not a constructor' in or related to this line: 'this.gunshotSound = new frvr.Sound("gunshot.mp3");' Line Number: 155
User prompt
Please fix the bug: 'frvr.Text is not a constructor' in or related to this line: 'this.scoreText = new frvr.Text("Score: 0", {' Line Number: 148
User prompt
Please fix the bug: 'this.addChild is not a function' in or related to this line: 'this.addChild(this.background);' Line Number: 138
User prompt
Please fix the bug: 'frvr.Sprite is not a constructor' in or related to this line: 'this.background = new frvr.Sprite("background.jpg");' Line Number: 124
User prompt
Please fix the bug: 'frvr.startGame is not a function' in or related to this line: 'frvr.startGame(BalloonShooterGame);' Line Number: 261
User prompt
Please fix the bug: 'TypeError is not a constructor' in or related to this line: 'throw new TypeError("Super expression must either be null or a function");' Line Number: 87
User prompt
Please fix the bug: 'frvr is not defined' in or related to this line: 'var BalloonShooterGame = /*#__PURE__*/function (_frvr$Game) {' Line Number: 104
Code edit (1 edits merged)
Please save this source code
User prompt
Balloon Shooter
Initial prompt
Title: Balloon Shooter Description: Step into the ultimate beachside fun with Balloon Shooter! 🎈🔫 Pop colorful balloons floating in the air using your trusty beach gun. Aim, shoot, and score points as balloons drift across the sky. Watch out for special power-ups and obstacles like seagulls and strong winds! Can you become the top balloon shooter on the beach? 🏖️ Features: ✅ Smooth shooting mechanics ✅ Colorful balloons with different point values ✅ Power-ups and obstacles for extra challenge ✅ Fun sound effects and beach-themed background music Ready to test your aim? Play now and pop your way to victory! 🎯🔥
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0 }); /**** * Classes ****/ var Balloon = Container.expand(function (type) { var self = Container.call(this); // Define balloon types and properties var types = { 'red': { color: 'balloon_red', points: 10, speed: 2 }, 'blue': { color: 'balloon_blue', points: 20, speed: 3 }, 'yellow': { color: 'balloon_yellow', points: 30, speed: 4 }, 'green': { color: 'balloon_green', points: 50, speed: 5 }, 'spiky': { color: 'spiky_balloon', points: -10, speed: 6 }, 'purple': { color: 'balloon_purple', points: 40, speed: 4.5 } }; var balloonType = types[type] || types['red']; self.type = type; self.points = balloonType.points; self.baseSpeed = balloonType.speed; self.speed = self.baseSpeed; self.active = true; // Create balloon body var balloonBody = self.attachAsset(balloonType.color, { anchorX: 0.5, anchorY: 0.5 }); // Create balloon string var balloonString = self.attachAsset('balloon_string', { anchorX: 0.5, anchorY: 0, y: balloonBody.height / 2 }); // Add a small random horizontal drift self.driftSpeed = (Math.random() * 2 - 1) * 0.5; self.update = function () { if (self.active) { self.y -= self.speed; self.x += self.driftSpeed; // Check if balloon is off-screen if (self.y < -200) { self.active = false; } } }; self.pop = function () { if (self.active) { self.active = false; LK.getSound('pop').play(); // Visual pop effect tween(balloonBody, { scaleX: 1.5, scaleY: 1.5, alpha: 0 }, { duration: 300, easing: tween.easeOut, onFinish: function onFinish() { // Nothing needed here as cleanup happens in game loop } }); // Make string fall tween(balloonString, { rotation: Math.PI / 4, alpha: 0 }, { duration: 500, easing: tween.easeIn }); // Additional blast effect for spiky balloon if (self.type === 'spiky') { tween(balloonBody, { scaleX: 2.5, // Increase scale for more dramatic effect scaleY: 2.5, // Increase scale for more dramatic effect alpha: 0 }, { duration: 700, // Increase duration for a slower blast easing: tween.elasticOut, onFinish: function onFinish() { // Additional effect or cleanup if needed balloonBody.destroy(); // Ensure the balloon body is removed after the effect } }); } return self.points; } return 0; }; return self; }); var Cloud = Container.expand(function () { var self = Container.call(this); var cloudGraphics = self.attachAsset('cloud', { anchorX: 0.5, anchorY: 0.5, alpha: 0.8 }); self.speed = 0.3 + Math.random() * 0.3; self.active = true; // Make clouds different sizes var scale = 0.8 + Math.random() * 1.2; cloudGraphics.scaleX = scale; cloudGraphics.scaleY = scale * 0.7; self.update = function () { if (self.active) { self.x += self.speed; // Loop cloud back to left side when it goes off screen if (self.x > 2200) { self.x = -200; self.y = 200 + Math.random() * 300; } } }; return self; }); var PowerUp = Container.expand(function () { var self = Container.call(this); var powerupGraphics = self.attachAsset('powerup', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 2; self.active = true; self.type = Math.random() > 0.5 ? 'rapid' : 'spread'; // Set different color based on powerup type if (self.type === 'rapid') { powerupGraphics.tint = 0xff0000; } else { powerupGraphics.tint = 0x00ff00; } // Animate the powerup tween(powerupGraphics, { rotation: Math.PI * 2 }, { duration: 3000, easing: tween.linear }); self.update = function () { if (self.active) { self.y -= self.speed; // Check if powerup is off-screen if (self.y < -100) { self.active = false; } } }; self.collect = function () { if (self.active) { self.active = false; LK.getSound('powerup_collect').play(); // Visual collect effect tween(powerupGraphics, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: 300, easing: tween.easeOut }); return self.type; } return null; }; return self; }); var Seagull = Container.expand(function () { var self = Container.call(this); var seagullGraphics = self.attachAsset('seagull', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 4 + Math.random() * 2; self.active = true; self.direction = Math.random() > 0.5 ? 1 : -1; // Set initial direction if (self.direction < 0) { seagullGraphics.scaleX = -1; } self.update = function () { if (self.active) { self.x += self.speed * self.direction; // Ensure wing flapping animation is applied if (!self.flapping) { self.flapping = true; tween(seagullGraphics, { scaleY: 0.8 }, { duration: 200, yoyo: true, repeat: Infinity, easing: tween.easeInOut }); } // Check if seagull is off-screen if (self.direction > 0 && self.x > 2100 || self.direction < 0 && self.x < -50) { self.active = false; } } }; return self; }); var Seagull2 = Container.expand(function () { var self = Container.call(this); var seagullGraphics = self.attachAsset('seagull2', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 4 + Math.random() * 2; self.active = true; self.direction = Math.random() > 0.5 ? 1 : -1; // Set initial direction if (self.direction < 0) { seagullGraphics.scaleX = -1; } self.update = function () { if (self.active) { self.x += self.speed * self.direction; // Ensure wing flapping animation is applied if (!self.flapping) { self.flapping = true; tween(seagullGraphics, { scaleY: 0.8 }, { duration: 200, yoyo: true, repeat: Infinity, easing: tween.easeInOut }); } // Check if seagull is off-screen if (self.direction > 0 && self.x > 2100 || self.direction < 0 && self.x < -50) { self.active = false; } } }; return self; }); var WaterBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.speed = -15; self.active = true; self.update = function () { if (self.active) { self.y += self.speed; // Check if bullet is off-screen if (self.y < -50) { self.active = false; } } }; return self; }); var WaterGun = Container.expand(function () { var self = Container.call(this); var gunGraphics = self.attachAsset('watergun', { anchorX: 0.5, anchorY: 0.5 }); self.canShoot = true; self.cooldown = 500; // ms between shots self.powerupActive = false; self.powerupType = null; self.powerupTimer = null; self.shoot = function () { if (!self.canShoot) { return null; } LK.getSound('shoot').play(); var bullets = []; // Create main bullet var bullet = new WaterBullet(); bullet.x = self.x; bullet.y = self.y - 30; bullets.push(bullet); // If spread powerup is active, create side bullets if (self.powerupActive && self.powerupType === 'spread') { var bulletLeft = new WaterBullet(); bulletLeft.x = self.x - 30; bulletLeft.y = self.y - 20; bullets.push(bulletLeft); var bulletRight = new WaterBullet(); bulletRight.x = self.x + 30; bulletRight.y = self.y - 20; bullets.push(bulletRight); } // Set cooldown unless rapid fire powerup is active if (!(self.powerupActive && self.powerupType === 'rapid')) { self.canShoot = false; LK.setTimeout(function () { self.canShoot = true; }, self.cooldown); } return bullets; }; self.activatePowerup = function (type) { // Clear existing powerup if any if (self.powerupTimer) { LK.clearTimeout(self.powerupTimer); } self.powerupActive = true; self.powerupType = type; // Visual feedback tween(gunGraphics, { tint: type === 'rapid' ? 0xff0000 : 0x00ff00 }, { duration: 300, easing: tween.easeOut }); // Set powerup duration self.powerupTimer = LK.setTimeout(function () { self.powerupActive = false; self.powerupType = null; // Reset gun appearance tween(gunGraphics, { tint: 0x2299cc }, { duration: 300, easing: tween.easeIn }); }, 8000); // 8 seconds }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x99ddff }); /**** * Game Code ****/ function createSeagull2() { var seagull2 = new Seagull2(); // Start from either left or right edge based on direction seagull2.x = seagull2.direction > 0 ? -50 : 2100; seagull2.y = 400 + Math.random() * 600; seagulls.push(seagull2); game.addChild(seagull2); } // Game variables var score = 0; var waterGun; var bullets = []; var balloons = []; var seagulls = []; var powerups = []; var clouds = []; var windEffect = 0; var gameActive = true; var lastBalloonSpawn = 0; var lastSeagullSpawn = 0; var lastPowerupSpawn = 0; var balloonSpawnRate = 1500; // ms var seagullSpawnRate = 5000; // ms var powerupSpawnRate = 10000; // ms var touchPoint = null; // Background elements var skyBackground = game.addChild(LK.getAsset('background', { anchorX: 0, anchorY: 0, x: 0, y: 0 })); // Add some clouds for (var i = 0; i < 5; i++) { var cloud = new Cloud(); cloud.x = Math.random() * 2048; cloud.y = 200 + Math.random() * 300; clouds.push(cloud); game.addChild(cloud); } // Water var water = game.addChild(LK.getAsset('water', { anchorX: 0, anchorY: 1, x: 0, y: 2732 })); // Sand var sand = game.addChild(LK.getAsset('sand', { anchorX: 0, anchorY: 0, x: 0, y: 2732 - water.height })); // Create water gun waterGun = new WaterGun(); waterGun.x = 1024; waterGun.y = 2732 - 200; // Position above the sand game.addChild(waterGun); // UI elements var scoreTxt = new Text2('Score: 0', { size: 50, fill: 0xFFFFFF }); scoreTxt.anchor.set(0, 0); LK.gui.topRight.addChild(scoreTxt); scoreTxt.x = -200; // Offset from right edge var highScoreTxt = new Text2('High Score: ' + storage.highScore, { size: 40, fill: 0xFFFFFF }); highScoreTxt.anchor.set(0, 0); LK.gui.topRight.addChild(highScoreTxt); highScoreTxt.x = -200; highScoreTxt.y = 60; // Wind indicator var windTxt = new Text2('Wind: 0', { size: 40, fill: 0xFFFFFF }); windTxt.anchor.set(0, 0); LK.gui.top.addChild(windTxt); windTxt.y = 60; // Game functions function createBalloon() { var types = ['red', 'blue', 'yellow', 'green', 'spiky', 'purple']; // Weight probabilities toward easier balloons var type = types[Math.floor(Math.pow(Math.random(), 1.5) * types.length)]; var balloon = new Balloon(type); balloon.x = 200 + Math.random() * (2048 - 400); balloon.y = 2732 + 100; // Apply wind effect to drift speed balloon.driftSpeed += windEffect; balloons.push(balloon); game.addChild(balloon); } function createSeagull() { var seagull = new Seagull(); // Start from either left or right edge based on direction seagull.x = seagull.direction > 0 ? -50 : 2100; seagull.y = 400 + Math.random() * 600; seagulls.push(seagull); game.addChild(seagull); } function createPowerup() { var powerup = new PowerUp(); powerup.x = 200 + Math.random() * (2048 - 400); powerup.y = 2732 + 50; powerups.push(powerup); game.addChild(powerup); } function checkCollisions() { // Check bullet-balloon collisions for (var i = bullets.length - 1; i >= 0; i--) { var bullet = bullets[i]; if (!bullet.active) { continue; } for (var j = balloons.length - 1; j >= 0; j--) { var balloon = balloons[j]; if (!balloon.active) { continue; } if (bullet.intersects(balloon)) { if (bullet.intersects(powerup)) { powerup.collect(); // Collect the powerup // Burst multiple nearby balloons for (var n = balloons.length - 1; n >= 0; n--) { var nearbyBalloon = balloons[n]; if (nearbyBalloon.active && Math.abs(nearbyBalloon.x - bullet.x) < 200 && Math.abs(nearbyBalloon.y - bullet.y) < 200) { nearbyBalloon.pop(); score += nearbyBalloon.points; scoreTxt.setText('Score: ' + score); if (score > storage.highScore) { storage.highScore = score; highScoreTxt.setText('High Score: ' + storage.highScore); } } } } if (balloon.type === 'spiky') { gameActive = false; LK.showGameOver(); return; } // Score points for popping balloon var points = balloon.pop(); score += points; scoreTxt.setText('Score: ' + score); // Update high score if needed if (score > storage.highScore) { storage.highScore = score; highScoreTxt.setText('High Score: ' + storage.highScore); } // Deactivate bullet bullet.active = false; break; } } // Check bullet-seagull collisions (no points, but deactivates bullet) for (var k = seagulls.length - 1; k >= 0; k--) { var seagull = seagulls[k]; if (!seagull.active || !bullet.active) { continue; } if (bullet.intersects(seagull)) { // Trigger game over gameActive = false; LK.showGameOver(); return; } } } // Check watergun-powerup collisions for (var m = powerups.length - 1; m >= 0; m--) { var powerup = powerups[m]; if (!powerup.active) { continue; } if (waterGun.intersects(powerup)) { var powerupType = powerup.collect(); if (powerupType) { waterGun.activatePowerup(powerupType); } } } } function updateWind() { // Change wind every 10 seconds if (LK.ticks % 600 === 0) { windEffect = (Math.random() * 2 - 1) * 1.5; windTxt.setText('Wind: ' + (windEffect > 0 ? '→' : '←').repeat(Math.abs(Math.round(windEffect)))); } } function cleanupInactiveObjects() { // Clean up inactive bullets for (var i = bullets.length - 1; i >= 0; i--) { if (!bullets[i].active) { bullets[i].destroy(); bullets.splice(i, 1); } } // Clean up inactive balloons for (var j = balloons.length - 1; j >= 0; j--) { if (!balloons[j].active) { balloons[j].destroy(); balloons.splice(j, 1); } } // Clean up inactive seagulls for (var k = seagulls.length - 1; k >= 0; k--) { if (!seagulls[k].active) { seagulls[k].destroy(); seagulls.splice(k, 1); } } // Clean up inactive powerups for (var m = powerups.length - 1; m >= 0; m--) { if (!powerups[m].active) { powerups[m].destroy(); powerups.splice(m, 1); } } } function handleTouch(x, y) { // Move water gun to touch position (with limits) waterGun.x = Math.max(100, Math.min(2048 - 100, x)); // Shoot water var newBullets = waterGun.shoot(); if (newBullets) { for (var i = 0; i < newBullets.length; i++) { game.addChild(newBullets[i]); bullets.push(newBullets[i]); } } } // Touch events game.down = function (x, y) { touchPoint = { x: x, y: y }; handleTouch(x, y); }; game.move = function (x, y) { if (touchPoint) { touchPoint = { x: x, y: y }; handleTouch(x, y); } }; game.up = function () { touchPoint = null; }; // Main game loop game.update = function () { if (!gameActive) { return; } // Spawn objects based on time var currentTime = LK.ticks * (1000 / 60); // Convert ticks to milliseconds // Spawn balloons if (currentTime - lastBalloonSpawn > balloonSpawnRate) { createBalloon(); lastBalloonSpawn = currentTime; // Gradually increase balloon spawn rate balloonSpawnRate = Math.max(700, balloonSpawnRate - 10); } // Spawn seagulls if (currentTime - lastSeagullSpawn > seagullSpawnRate) { createSeagull(); createSeagull2(); // Add seagull2 spawning lastSeagullSpawn = currentTime; } // Spawn powerups if (currentTime - lastPowerupSpawn > powerupSpawnRate) { createPowerup(); lastPowerupSpawn = currentTime; } // Update wind updateWind(); // Check for collisions checkCollisions(); // Clean up inactive objects cleanupInactiveObjects(); // Shooting if touch is held if (touchPoint && LK.ticks % 10 === 0 && waterGun.powerupActive && waterGun.powerupType === 'rapid') { handleTouch(touchPoint.x, touchPoint.y); } // Game over condition: If too many balloons escape // Count escaped balloons (moved off the top of the screen) var escapedCount = 0; for (var i = 0; i < balloons.length; i++) { if (!balloons[i].active && balloons[i].y < 0) { escapedCount++; } } // If score reaches 500, player wins if (score >= 500) { gameActive = false; LK.showYouWin(); } }; // Start background music LK.playMusic('beach_music');
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0
});
/****
* Classes
****/
var Balloon = Container.expand(function (type) {
var self = Container.call(this);
// Define balloon types and properties
var types = {
'red': {
color: 'balloon_red',
points: 10,
speed: 2
},
'blue': {
color: 'balloon_blue',
points: 20,
speed: 3
},
'yellow': {
color: 'balloon_yellow',
points: 30,
speed: 4
},
'green': {
color: 'balloon_green',
points: 50,
speed: 5
},
'spiky': {
color: 'spiky_balloon',
points: -10,
speed: 6
},
'purple': {
color: 'balloon_purple',
points: 40,
speed: 4.5
}
};
var balloonType = types[type] || types['red'];
self.type = type;
self.points = balloonType.points;
self.baseSpeed = balloonType.speed;
self.speed = self.baseSpeed;
self.active = true;
// Create balloon body
var balloonBody = self.attachAsset(balloonType.color, {
anchorX: 0.5,
anchorY: 0.5
});
// Create balloon string
var balloonString = self.attachAsset('balloon_string', {
anchorX: 0.5,
anchorY: 0,
y: balloonBody.height / 2
});
// Add a small random horizontal drift
self.driftSpeed = (Math.random() * 2 - 1) * 0.5;
self.update = function () {
if (self.active) {
self.y -= self.speed;
self.x += self.driftSpeed;
// Check if balloon is off-screen
if (self.y < -200) {
self.active = false;
}
}
};
self.pop = function () {
if (self.active) {
self.active = false;
LK.getSound('pop').play();
// Visual pop effect
tween(balloonBody, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0
}, {
duration: 300,
easing: tween.easeOut,
onFinish: function onFinish() {
// Nothing needed here as cleanup happens in game loop
}
});
// Make string fall
tween(balloonString, {
rotation: Math.PI / 4,
alpha: 0
}, {
duration: 500,
easing: tween.easeIn
});
// Additional blast effect for spiky balloon
if (self.type === 'spiky') {
tween(balloonBody, {
scaleX: 2.5,
// Increase scale for more dramatic effect
scaleY: 2.5,
// Increase scale for more dramatic effect
alpha: 0
}, {
duration: 700,
// Increase duration for a slower blast
easing: tween.elasticOut,
onFinish: function onFinish() {
// Additional effect or cleanup if needed
balloonBody.destroy(); // Ensure the balloon body is removed after the effect
}
});
}
return self.points;
}
return 0;
};
return self;
});
var Cloud = Container.expand(function () {
var self = Container.call(this);
var cloudGraphics = self.attachAsset('cloud', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.8
});
self.speed = 0.3 + Math.random() * 0.3;
self.active = true;
// Make clouds different sizes
var scale = 0.8 + Math.random() * 1.2;
cloudGraphics.scaleX = scale;
cloudGraphics.scaleY = scale * 0.7;
self.update = function () {
if (self.active) {
self.x += self.speed;
// Loop cloud back to left side when it goes off screen
if (self.x > 2200) {
self.x = -200;
self.y = 200 + Math.random() * 300;
}
}
};
return self;
});
var PowerUp = Container.expand(function () {
var self = Container.call(this);
var powerupGraphics = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.active = true;
self.type = Math.random() > 0.5 ? 'rapid' : 'spread';
// Set different color based on powerup type
if (self.type === 'rapid') {
powerupGraphics.tint = 0xff0000;
} else {
powerupGraphics.tint = 0x00ff00;
}
// Animate the powerup
tween(powerupGraphics, {
rotation: Math.PI * 2
}, {
duration: 3000,
easing: tween.linear
});
self.update = function () {
if (self.active) {
self.y -= self.speed;
// Check if powerup is off-screen
if (self.y < -100) {
self.active = false;
}
}
};
self.collect = function () {
if (self.active) {
self.active = false;
LK.getSound('powerup_collect').play();
// Visual collect effect
tween(powerupGraphics, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 300,
easing: tween.easeOut
});
return self.type;
}
return null;
};
return self;
});
var Seagull = Container.expand(function () {
var self = Container.call(this);
var seagullGraphics = self.attachAsset('seagull', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4 + Math.random() * 2;
self.active = true;
self.direction = Math.random() > 0.5 ? 1 : -1;
// Set initial direction
if (self.direction < 0) {
seagullGraphics.scaleX = -1;
}
self.update = function () {
if (self.active) {
self.x += self.speed * self.direction;
// Ensure wing flapping animation is applied
if (!self.flapping) {
self.flapping = true;
tween(seagullGraphics, {
scaleY: 0.8
}, {
duration: 200,
yoyo: true,
repeat: Infinity,
easing: tween.easeInOut
});
}
// Check if seagull is off-screen
if (self.direction > 0 && self.x > 2100 || self.direction < 0 && self.x < -50) {
self.active = false;
}
}
};
return self;
});
var Seagull2 = Container.expand(function () {
var self = Container.call(this);
var seagullGraphics = self.attachAsset('seagull2', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 4 + Math.random() * 2;
self.active = true;
self.direction = Math.random() > 0.5 ? 1 : -1;
// Set initial direction
if (self.direction < 0) {
seagullGraphics.scaleX = -1;
}
self.update = function () {
if (self.active) {
self.x += self.speed * self.direction;
// Ensure wing flapping animation is applied
if (!self.flapping) {
self.flapping = true;
tween(seagullGraphics, {
scaleY: 0.8
}, {
duration: 200,
yoyo: true,
repeat: Infinity,
easing: tween.easeInOut
});
}
// Check if seagull is off-screen
if (self.direction > 0 && self.x > 2100 || self.direction < 0 && self.x < -50) {
self.active = false;
}
}
};
return self;
});
var WaterBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -15;
self.active = true;
self.update = function () {
if (self.active) {
self.y += self.speed;
// Check if bullet is off-screen
if (self.y < -50) {
self.active = false;
}
}
};
return self;
});
var WaterGun = Container.expand(function () {
var self = Container.call(this);
var gunGraphics = self.attachAsset('watergun', {
anchorX: 0.5,
anchorY: 0.5
});
self.canShoot = true;
self.cooldown = 500; // ms between shots
self.powerupActive = false;
self.powerupType = null;
self.powerupTimer = null;
self.shoot = function () {
if (!self.canShoot) {
return null;
}
LK.getSound('shoot').play();
var bullets = [];
// Create main bullet
var bullet = new WaterBullet();
bullet.x = self.x;
bullet.y = self.y - 30;
bullets.push(bullet);
// If spread powerup is active, create side bullets
if (self.powerupActive && self.powerupType === 'spread') {
var bulletLeft = new WaterBullet();
bulletLeft.x = self.x - 30;
bulletLeft.y = self.y - 20;
bullets.push(bulletLeft);
var bulletRight = new WaterBullet();
bulletRight.x = self.x + 30;
bulletRight.y = self.y - 20;
bullets.push(bulletRight);
}
// Set cooldown unless rapid fire powerup is active
if (!(self.powerupActive && self.powerupType === 'rapid')) {
self.canShoot = false;
LK.setTimeout(function () {
self.canShoot = true;
}, self.cooldown);
}
return bullets;
};
self.activatePowerup = function (type) {
// Clear existing powerup if any
if (self.powerupTimer) {
LK.clearTimeout(self.powerupTimer);
}
self.powerupActive = true;
self.powerupType = type;
// Visual feedback
tween(gunGraphics, {
tint: type === 'rapid' ? 0xff0000 : 0x00ff00
}, {
duration: 300,
easing: tween.easeOut
});
// Set powerup duration
self.powerupTimer = LK.setTimeout(function () {
self.powerupActive = false;
self.powerupType = null;
// Reset gun appearance
tween(gunGraphics, {
tint: 0x2299cc
}, {
duration: 300,
easing: tween.easeIn
});
}, 8000); // 8 seconds
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x99ddff
});
/****
* Game Code
****/
function createSeagull2() {
var seagull2 = new Seagull2();
// Start from either left or right edge based on direction
seagull2.x = seagull2.direction > 0 ? -50 : 2100;
seagull2.y = 400 + Math.random() * 600;
seagulls.push(seagull2);
game.addChild(seagull2);
}
// Game variables
var score = 0;
var waterGun;
var bullets = [];
var balloons = [];
var seagulls = [];
var powerups = [];
var clouds = [];
var windEffect = 0;
var gameActive = true;
var lastBalloonSpawn = 0;
var lastSeagullSpawn = 0;
var lastPowerupSpawn = 0;
var balloonSpawnRate = 1500; // ms
var seagullSpawnRate = 5000; // ms
var powerupSpawnRate = 10000; // ms
var touchPoint = null;
// Background elements
var skyBackground = game.addChild(LK.getAsset('background', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
}));
// Add some clouds
for (var i = 0; i < 5; i++) {
var cloud = new Cloud();
cloud.x = Math.random() * 2048;
cloud.y = 200 + Math.random() * 300;
clouds.push(cloud);
game.addChild(cloud);
}
// Water
var water = game.addChild(LK.getAsset('water', {
anchorX: 0,
anchorY: 1,
x: 0,
y: 2732
}));
// Sand
var sand = game.addChild(LK.getAsset('sand', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 2732 - water.height
}));
// Create water gun
waterGun = new WaterGun();
waterGun.x = 1024;
waterGun.y = 2732 - 200; // Position above the sand
game.addChild(waterGun);
// UI elements
var scoreTxt = new Text2('Score: 0', {
size: 50,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreTxt);
scoreTxt.x = -200; // Offset from right edge
var highScoreTxt = new Text2('High Score: ' + storage.highScore, {
size: 40,
fill: 0xFFFFFF
});
highScoreTxt.anchor.set(0, 0);
LK.gui.topRight.addChild(highScoreTxt);
highScoreTxt.x = -200;
highScoreTxt.y = 60;
// Wind indicator
var windTxt = new Text2('Wind: 0', {
size: 40,
fill: 0xFFFFFF
});
windTxt.anchor.set(0, 0);
LK.gui.top.addChild(windTxt);
windTxt.y = 60;
// Game functions
function createBalloon() {
var types = ['red', 'blue', 'yellow', 'green', 'spiky', 'purple'];
// Weight probabilities toward easier balloons
var type = types[Math.floor(Math.pow(Math.random(), 1.5) * types.length)];
var balloon = new Balloon(type);
balloon.x = 200 + Math.random() * (2048 - 400);
balloon.y = 2732 + 100;
// Apply wind effect to drift speed
balloon.driftSpeed += windEffect;
balloons.push(balloon);
game.addChild(balloon);
}
function createSeagull() {
var seagull = new Seagull();
// Start from either left or right edge based on direction
seagull.x = seagull.direction > 0 ? -50 : 2100;
seagull.y = 400 + Math.random() * 600;
seagulls.push(seagull);
game.addChild(seagull);
}
function createPowerup() {
var powerup = new PowerUp();
powerup.x = 200 + Math.random() * (2048 - 400);
powerup.y = 2732 + 50;
powerups.push(powerup);
game.addChild(powerup);
}
function checkCollisions() {
// Check bullet-balloon collisions
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
if (!bullet.active) {
continue;
}
for (var j = balloons.length - 1; j >= 0; j--) {
var balloon = balloons[j];
if (!balloon.active) {
continue;
}
if (bullet.intersects(balloon)) {
if (bullet.intersects(powerup)) {
powerup.collect(); // Collect the powerup
// Burst multiple nearby balloons
for (var n = balloons.length - 1; n >= 0; n--) {
var nearbyBalloon = balloons[n];
if (nearbyBalloon.active && Math.abs(nearbyBalloon.x - bullet.x) < 200 && Math.abs(nearbyBalloon.y - bullet.y) < 200) {
nearbyBalloon.pop();
score += nearbyBalloon.points;
scoreTxt.setText('Score: ' + score);
if (score > storage.highScore) {
storage.highScore = score;
highScoreTxt.setText('High Score: ' + storage.highScore);
}
}
}
}
if (balloon.type === 'spiky') {
gameActive = false;
LK.showGameOver();
return;
}
// Score points for popping balloon
var points = balloon.pop();
score += points;
scoreTxt.setText('Score: ' + score);
// Update high score if needed
if (score > storage.highScore) {
storage.highScore = score;
highScoreTxt.setText('High Score: ' + storage.highScore);
}
// Deactivate bullet
bullet.active = false;
break;
}
}
// Check bullet-seagull collisions (no points, but deactivates bullet)
for (var k = seagulls.length - 1; k >= 0; k--) {
var seagull = seagulls[k];
if (!seagull.active || !bullet.active) {
continue;
}
if (bullet.intersects(seagull)) {
// Trigger game over
gameActive = false;
LK.showGameOver();
return;
}
}
}
// Check watergun-powerup collisions
for (var m = powerups.length - 1; m >= 0; m--) {
var powerup = powerups[m];
if (!powerup.active) {
continue;
}
if (waterGun.intersects(powerup)) {
var powerupType = powerup.collect();
if (powerupType) {
waterGun.activatePowerup(powerupType);
}
}
}
}
function updateWind() {
// Change wind every 10 seconds
if (LK.ticks % 600 === 0) {
windEffect = (Math.random() * 2 - 1) * 1.5;
windTxt.setText('Wind: ' + (windEffect > 0 ? '→' : '←').repeat(Math.abs(Math.round(windEffect))));
}
}
function cleanupInactiveObjects() {
// Clean up inactive bullets
for (var i = bullets.length - 1; i >= 0; i--) {
if (!bullets[i].active) {
bullets[i].destroy();
bullets.splice(i, 1);
}
}
// Clean up inactive balloons
for (var j = balloons.length - 1; j >= 0; j--) {
if (!balloons[j].active) {
balloons[j].destroy();
balloons.splice(j, 1);
}
}
// Clean up inactive seagulls
for (var k = seagulls.length - 1; k >= 0; k--) {
if (!seagulls[k].active) {
seagulls[k].destroy();
seagulls.splice(k, 1);
}
}
// Clean up inactive powerups
for (var m = powerups.length - 1; m >= 0; m--) {
if (!powerups[m].active) {
powerups[m].destroy();
powerups.splice(m, 1);
}
}
}
function handleTouch(x, y) {
// Move water gun to touch position (with limits)
waterGun.x = Math.max(100, Math.min(2048 - 100, x));
// Shoot water
var newBullets = waterGun.shoot();
if (newBullets) {
for (var i = 0; i < newBullets.length; i++) {
game.addChild(newBullets[i]);
bullets.push(newBullets[i]);
}
}
}
// Touch events
game.down = function (x, y) {
touchPoint = {
x: x,
y: y
};
handleTouch(x, y);
};
game.move = function (x, y) {
if (touchPoint) {
touchPoint = {
x: x,
y: y
};
handleTouch(x, y);
}
};
game.up = function () {
touchPoint = null;
};
// Main game loop
game.update = function () {
if (!gameActive) {
return;
}
// Spawn objects based on time
var currentTime = LK.ticks * (1000 / 60); // Convert ticks to milliseconds
// Spawn balloons
if (currentTime - lastBalloonSpawn > balloonSpawnRate) {
createBalloon();
lastBalloonSpawn = currentTime;
// Gradually increase balloon spawn rate
balloonSpawnRate = Math.max(700, balloonSpawnRate - 10);
}
// Spawn seagulls
if (currentTime - lastSeagullSpawn > seagullSpawnRate) {
createSeagull();
createSeagull2(); // Add seagull2 spawning
lastSeagullSpawn = currentTime;
}
// Spawn powerups
if (currentTime - lastPowerupSpawn > powerupSpawnRate) {
createPowerup();
lastPowerupSpawn = currentTime;
}
// Update wind
updateWind();
// Check for collisions
checkCollisions();
// Clean up inactive objects
cleanupInactiveObjects();
// Shooting if touch is held
if (touchPoint && LK.ticks % 10 === 0 && waterGun.powerupActive && waterGun.powerupType === 'rapid') {
handleTouch(touchPoint.x, touchPoint.y);
}
// Game over condition: If too many balloons escape
// Count escaped balloons (moved off the top of the screen)
var escapedCount = 0;
for (var i = 0; i < balloons.length; i++) {
if (!balloons[i].active && balloons[i].y < 0) {
escapedCount++;
}
}
// If score reaches 500, player wins
if (score >= 500) {
gameActive = false;
LK.showYouWin();
}
};
// Start background music
LK.playMusic('beach_music');
A soft gradient sky transitioning from light blue to white, with subtle fluffy clouds scattered across. The style should be cartoonish and visually appealing.". Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A glowing, floating power-up icon shaped like a lightning bolt, rotating in mid-air. Colors include blue, green, and red variants.". Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A cartoon-style toy gun with a futuristic design, mainly blue with white and black details, a large trigger, and a barrel that shoots darts.". Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A cartoon-style seagull in mid-flight, white feathers with a light gray beak and wings slightly spread out. Expressions should be fun and mischievous.". Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows