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