/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0
});
/****
* Classes
****/
var Beehive = Container.expand(function () {
var self = Container.call(this);
// Main hive body - preserve dimensions
self.hiveBody = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.0,
tint: 0xD8B373 // More honey-like color for beehive
});
// Add honeycomb texture effect with layered shapes - preserve proportions
for (var i = 0; i < 3; i++) {
var honeyLayer = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.1 - i * 0.1,
scaleY: 0.9 - i * 0.1,
alpha: 0.3,
tint: 0xFFD700 // Gold honey color
});
}
// Hive entrance - preserve proportions
self.entrance = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
y: -20,
scaleX: 0.4,
scaleY: 0.2,
tint: 0x8B4513 // Brown color for entrance
});
// Darker entrance hole - preserve proportions
self.entranceHole = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
y: -20,
scaleX: 0.2,
scaleY: 0.15,
tint: 0x503000 // Dark entrance hole
});
// Hive texture stripes - preserve proportions
for (var i = 0; i < 5; i++) {
var stripe = self.attachAsset('beeStripe1', {
anchorX: 0.5,
anchorY: 0.5,
y: -25 + i * 15,
scaleX: 1.1 - Math.abs(i - 2) * 0.1,
// Curved effect
scaleY: 0.15
});
}
// Add some honey drips - preserve proportions
for (var i = 0; i < 3; i++) {
var honeyDrip = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.0,
x: -30 + i * 30,
y: 30,
scaleX: 0.1,
scaleY: 0.2 + Math.random() * 0.15,
tint: 0xFFD700 // Gold honey color
});
}
// Add some bees hovering near the hive - preserve proportions
for (var i = 0; i < 3; i++) {
var hoverBee = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
x: -45 + i * 25,
y: -30 - i * 8,
scaleX: 0.15,
scaleY: 0.08,
tint: 0xF7DF18
});
// Wings for hovering bees - preserve proportions
var leftWing = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
x: -45 + i * 25 - 4,
y: -30 - i * 8 - 4,
scaleX: 0.1,
scaleY: 0.04,
tint: 0xFFFFFF,
alpha: 0.6
});
var rightWing = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
x: -45 + i * 25 - 4,
y: -30 - i * 8 + 4,
scaleX: 0.1,
scaleY: 0.04,
tint: 0xFFFFFF,
alpha: 0.6
});
// Animate wings
tween(leftWing, {
rotation: -0.8,
alpha: 0.8
}, {
duration: 100 + i * 10,
easing: tween.easeInOut,
repeat: -1,
yoyo: true
});
tween(rightWing, {
rotation: 0.8,
alpha: 0.8
}, {
duration: 100 + i * 10,
easing: tween.easeInOut,
repeat: -1,
yoyo: true
});
}
self.bees = [];
self.lastBeeSpawn = 0;
// Small breathing animation for the hive
tween(self, {
y: self.y - 8
}, {
duration: 3000,
easing: tween.easeInOut,
repeat: -1,
yoyo: true
});
// Add subtle pulsing effect to the hive
tween(self.hiveBody, {
scaleX: self.hiveBody.scaleX * 1.03,
scaleY: self.hiveBody.scaleY * 1.02
}, {
duration: 2000,
easing: tween.easeInOut,
repeat: -1,
yoyo: true
});
self.update = function () {
// Bee spawning has been disabled
// We keep the update method for future functionality
};
self.spawnBee = function () {
var bee = new Insect('bee', 3);
bee.x = self.x;
bee.y = self.y - 80;
game.addChild(bee);
insects.push(bee);
// Make the entrance "pulse" when a bee emerges
tween(self.entrance, {
scaleX: self.entrance.scaleX * 1.2,
scaleY: self.entrance.scaleY * 1.2
}, {
duration: 200,
easing: tween.easeOut,
complete: function complete() {
tween(self.entrance, {
scaleX: 1.0,
scaleY: 0.6
}, {
duration: 300,
easing: tween.easeIn
});
}
});
// Setup wing tweens for this new bee
var wingDuration = 500 + Math.random() * 300;
tween(bee.leftWing, {
rotation: -1.2,
scaleX: bee.leftWing.scaleX * 1.2
}, {
duration: wingDuration * 0.6,
easing: tween.easeInOut,
repeat: -1,
yoyo: true
});
tween(bee.rightWing, {
rotation: 1.2,
scaleX: bee.rightWing.scaleX * 1.2
}, {
duration: wingDuration * 0.6,
easing: tween.easeInOut,
repeat: -1,
yoyo: true
});
// Play buzz sound
LK.getSound('buzz').play();
// Add initial flight pattern as bee leaves hive
tween(bee, {
x: bee.x + (Math.random() > 0.5 ? 100 : -100),
y: bee.y - 100
}, {
duration: 800,
easing: tween.easeOut
});
};
return self;
});
var Firework = Container.expand(function (x, y, color) {
var self = Container.call(this);
self.x = x || 1024;
self.y = y || 1366;
self.color = color || 0xffcc00;
self.particles = [];
self.particleCount = 20 + Math.floor(Math.random() * 30);
// Create particles
for (var i = 0; i < self.particleCount; i++) {
var particle = self.attachAsset('trailDot', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1 + Math.random() * 2,
scaleY: 1 + Math.random() * 2,
tint: self.color,
alpha: 0.8
});
// Random angle for each particle
var angle = Math.random() * Math.PI * 2;
var speed = 2 + Math.random() * 8;
particle.vx = Math.cos(angle) * speed;
particle.vy = Math.sin(angle) * speed;
particle.gravity = 0.05 + Math.random() * 0.05;
self.particles.push(particle);
}
// Animate explosion
self.update = function () {
var allFaded = true;
for (var i = 0; i < self.particles.length; i++) {
var p = self.particles[i];
p.x += p.vx;
p.y += p.vy;
p.vy += p.gravity; // Add gravity
p.alpha -= 0.01; // Fade out
if (p.alpha > 0.1) {
allFaded = false;
}
}
// Remove firework when all particles have faded
if (allFaded) {
self.destroy();
}
};
return self;
});
var Insect = Container.expand(function (type, speed, beeColor) {
var self = Container.call(this);
self.type = type || 'bee';
self.speed = speed || 6; // Double default speed
self.vx = Math.random() * self.speed * (Math.random() > 0.5 ? 1 : -1);
self.vy = Math.random() * self.speed * (Math.random() > 0.5 ? 1 : -1);
self.lastTrailTime = 0;
// Only 1/3 of insects will have trails by default
self.trailActive = false;
self.hasTrailFeature = Math.random() < 0.33; // Only 33% of insects can have trails
self.trails = [];
self.flightOffset = Math.random() * Math.PI * 2; // Random flight pattern offset
self.flightSpeed = 0.5 + Math.random() * 0.5; // Random flight pattern speed
self.lastRotation = Math.atan2(self.vy, self.vx);
self.interactive = true; // Make insect clickable
self.lastTouchPoint = {
x: 0,
y: 0
}; // Track the last touch point
self.attractionForce = 0.1 + Math.random() * 0.3; // How strongly insect is drawn to cursor
self.lastAttracted = 0; // When was the insect last attracted to cursor
if (self.type === 'bee') {
// Main body
self.body = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.4,
scaleY: 0.7,
tint: beeColor || 0xf7df18 // Use provided bee color or default
});
// Bee head
self.head = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
x: 80,
scaleX: 0.6,
scaleY: 0.6
});
// Left wing
self.leftWing = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
x: -25,
y: -30,
rotation: -0.7,
scaleX: 0.8,
alpha: 0.6,
tint: 0xffffff
});
// Right wing
self.rightWing = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
x: -25,
y: 30,
rotation: 0.7,
scaleX: 0.8,
alpha: 0.6,
tint: 0xffffff
});
// Body stripes (reversed direction - vertical instead of horizontal)
self.stripe1 = self.attachAsset('beeStripe1', {
anchorX: 0.5,
anchorY: 0.5,
rotation: Math.PI / 2,
x: -25,
scaleX: 0.7,
scaleY: 0.8,
tint: 0x000000
});
self.stripe2 = self.attachAsset('beeStripe2', {
anchorX: 0.5,
anchorY: 0.5,
rotation: Math.PI / 2,
x: 25,
scaleX: 0.7,
scaleY: 0.8,
tint: 0x000000
});
} else {
// Main body
self.body = self.attachAsset('flyBody', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.6,
scaleY: 0.6
});
// Fly head
self.head = self.attachAsset('flyBody', {
anchorX: 0.5,
anchorY: 0.5,
x: 90,
scaleX: 0.5,
scaleY: 0.5
});
// Left wing
self.leftWing = self.attachAsset('flyBody', {
anchorX: 0.5,
anchorY: 0.5,
x: -15,
y: -25,
rotation: -0.6,
scaleX: 1.0,
scaleY: 0.6,
alpha: 0.6,
tint: 0xccccff
});
// Right wing
self.rightWing = self.attachAsset('flyBody', {
anchorX: 0.5,
anchorY: 0.5,
x: -15,
y: 25,
rotation: 0.6,
scaleX: 1.0,
scaleY: 0.6,
alpha: 0.6,
tint: 0xccccff
});
// Body stripe
self.stripe1 = self.attachAsset('flyStripe', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.8,
tint: 0x000000
});
}
self.update = function () {
// Create more dynamic flight pattern with rapid changes in direction and speed
var time = LK.ticks * 0.01;
// Random direction changes based on time
if (Math.random() < 0.03) {
// Occasionally make sharp turns
self.vx += (Math.random() - 0.5) * self.speed * 0.8;
self.vy += (Math.random() - 0.5) * self.speed * 0.8;
}
// Check if a touch point exists to be attracted to
if (lastTouchX !== 0 && lastTouchY !== 0) {
// Only update attraction based on cursor every few frames
if (LK.ticks - self.lastAttracted > 10) {
self.lastAttracted = LK.ticks;
// Calculate direction to cursor
var dx = lastTouchX - self.x;
var dy = lastTouchY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Only attract if within reasonable range (increases chances of being caught)
if (distance < 500) {
// Calculate attraction force (stronger when closer)
// Use global attractionDifficulty to make it harder in higher levels
var attractStrength = self.attractionForce * attractionDifficulty * (1 - distance / 500);
// Make attraction weaker for higher speeds (harder to control fast insects)
attractStrength = attractStrength / (self.speed * 0.2);
// Add attraction vector to current velocity - insects can resist player attraction in higher levels
self.vx += dx / distance * attractStrength * self.speed;
self.vy += dy / distance * attractStrength * self.speed;
}
}
}
// Add jerky, insect-like movement with bursts of speed
var jerkFactor = Math.sin(time * 16) * 1.0; // Much higher frequency and amplitude for extreme movement
var burstSpeed = Math.random() < 0.05 ? self.speed * 3 : 0; // More frequent and faster speed bursts
// Normalize velocity for consistent speed
var currentSpeed = Math.sqrt(self.vx * self.vx + self.vy * self.vy);
if (currentSpeed > 0) {
var normalizedVx = self.vx / currentSpeed;
var normalizedVy = self.vy / currentSpeed;
// Apply jerk factor and burst speed to create more dynamic movement
self.x += self.vx + normalizedVx * jerkFactor + normalizedVx * burstSpeed;
self.y += self.vy + normalizedVy * jerkFactor + normalizedVy * burstSpeed;
} else {
// Prevent stalling
self.vx = (Math.random() - 0.5) * self.speed;
self.vy = (Math.random() - 0.5) * self.speed;
self.x += self.vx;
self.y += self.vy;
}
// More energetic bounce off screen edges with slight angle change
if (self.x < 0 || self.x > 2048) {
self.vx *= -1.1; // Bounce slightly faster
// Add slight randomness to bounce angle
self.vy += (Math.random() - 0.5) * self.speed * 0.5;
self.x = Math.max(0, Math.min(2048, self.x));
}
if (self.y < 0 || self.y > 2732) {
self.vy *= -1.1; // Bounce slightly faster
// Add slight randomness to bounce angle
self.vx += (Math.random() - 0.5) * self.speed * 0.5;
self.y = Math.max(0, Math.min(2732, self.y));
}
// More dynamic rotation with slight overshoot
var targetRotation = Math.atan2(self.vy, self.vx);
// Add slight randomness to rotation for more natural movement
var rotationSpeed = 0.15 + Math.random() * 0.1;
self.rotation = self.rotation + (targetRotation - self.rotation) * rotationSpeed;
// Wings are now animated with tweens
// Just update wing alpha for pulsing effect
if (self.leftWing && self.rightWing) {
var wingAlpha = 0.6 + Math.sin(LK.ticks * 0.1) * 0.2;
self.leftWing.alpha = wingAlpha;
self.rightWing.alpha = wingAlpha;
}
// Create trails when active and insect has the trail feature
if (self.hasTrailFeature && self.trailActive && LK.ticks % 5 === 0) {
var dot = LK.getAsset('trailDot', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.7,
tint: 0xFFFFFF // White trail dot color
});
dot.x = self.x;
dot.y = self.y;
if (self.type === 'bee') {
dot.tint = 0xFFFFFF; // Always white trail for bees
} else {
dot.tint = 0x000000; // Black trail for flies
}
// Add dot to the game
game.addChild(dot);
// Store reference to dot
self.trails.push({
dot: dot,
createdAt: LK.ticks
});
}
// Remove old trail dots after 10 seconds (previously 2 seconds)
for (var i = self.trails.length - 1; i >= 0; i--) {
var trail = self.trails[i];
if (LK.ticks - trail.createdAt > 600) {
// Changed from 120 (2 sec) to 600 (10 sec)
trail.dot.destroy();
self.trails.splice(i, 1);
}
}
};
return self;
});
var LevelCompleteMenu = Container.expand(function () {
var self = Container.call(this);
// Dark semi-transparent background
self.bg = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 20,
scaleY: 20,
tint: 0x000000,
alpha: 0.6
});
// Menu panel
self.panel = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 12,
scaleY: 8,
tint: 0xFFD700
});
// Title text
self.titleText = new Text2('Level Complete!', {
size: 120,
fill: 0x000000
});
self.titleText.anchor.set(0.5, 0.5);
self.titleText.y = -200;
self.addChild(self.titleText);
// Level display
self.levelText = new Text2('Level ' + currentLevel + ' Completed', {
size: 80,
fill: 0x000000
});
self.levelText.anchor.set(0.5, 0.5);
self.levelText.y = -80;
self.addChild(self.levelText);
// Difficulty indicator - shows players the challenge is increasing
self.difficultyText = new Text2('Difficulty: ' + Math.floor(difficultyMultiplier * 100) + '%', {
size: 60,
fill: 0x660000
});
self.difficultyText.anchor.set(0.5, 0.5);
self.difficultyText.y = -20;
self.addChild(self.difficultyText);
// Score display
self.scoreText = new Text2('Flies Caught: ' + fliesCaught, {
size: 80,
fill: 0x000000
});
self.scoreText.anchor.set(0.5, 0.5);
self.scoreText.y = 0;
self.addChild(self.scoreText);
// High score display
var highScore = storage.highScore || 0;
self.highScoreText = new Text2('High Score: ' + highScore, {
size: 80,
fill: 0x000000
});
self.highScoreText.anchor.set(0.5, 0.5);
self.highScoreText.y = 100;
self.addChild(self.highScoreText);
// Continue button
self.continueButton = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
y: 300,
scaleX: 6,
scaleY: 2,
tint: 0x008000
});
// Continue button text
self.continueButtonText = new Text2('Continue', {
size: 80,
fill: 0xFFFFFF
});
self.continueButtonText.anchor.set(0.5, 0.5);
self.continueButtonText.y = 300;
self.addChild(self.continueButtonText);
// Make button interactive
self.continueButton.interactive = true;
self.continueButton.down = function (x, y, obj) {
self.destroy();
startNextLevel();
};
// Update menu with current level information
self.updateMenu = function (level, caught) {
self.levelText.setText('Level ' + level + ' Completed');
self.scoreText.setText('Flies Caught: ' + caught);
// Show next level difficulty
var nextLevelDifficulty = 1.0 + level * 0.2; // Same formula as in startNextLevel
self.difficultyText.setText('Next Level Difficulty: ' + Math.floor(nextLevelDifficulty * 100) + '%');
// Change color based on difficulty level
if (nextLevelDifficulty >= 2.0) {
self.difficultyText.style.fill = 0xFF0000; // Red for very hard
} else if (nextLevelDifficulty >= 1.5) {
self.difficultyText.style.fill = 0xFF6600; // Orange for harder
}
// Update high score
var highScore = storage.highScore || 0;
if (caught > highScore) {
highScore = caught;
storage.highScore = highScore;
}
self.highScoreText.setText('High Score: ' + highScore);
};
return self;
});
var LevelCompletionPopup = Container.expand(function () {
var self = Container.call(this);
// Add a semi-transparent background
self.bg = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 20,
scaleY: 8,
tint: 0x000000,
alpha: 0.6
});
// Main text that says "LEVEL COMPLETE"
self.levelCompleteText = new Text2('LEVEL COMPLETE!', {
size: 150,
fill: 0xFFFFFF
});
self.levelCompleteText.anchor.set(0.5, 0.5);
self.addChild(self.levelCompleteText);
// Make the text pulse for emphasis
tween(self.levelCompleteText, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 800,
easing: tween.easeInOut,
repeat: -1,
yoyo: true
});
// Auto-dismiss after fireworks display
self.startFireworks = function () {
var fireworksCount = 12;
var fireworksInterval = LK.setInterval(function () {
var x = Math.random() * 1800 + 100;
var y = Math.random() * 1000 + 600;
var colors = [0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xff00ff, 0x00ffff];
var color = colors[Math.floor(Math.random() * colors.length)];
var firework = new Firework(x, y, color);
game.addChild(firework);
fireworksCount--;
if (fireworksCount <= 0) {
LK.clearInterval(fireworksInterval);
// Show menu after fireworks finish
LK.setTimeout(function () {
self.destroy();
var menu = new LevelCompleteMenu();
menu.x = 1024; // Center horizontally
menu.y = 1366; // Center vertically
menu.updateMenu(currentLevel, fliesCaught);
game.addChild(menu);
}, 2000);
}
}, 300);
};
return self;
});
/****
* Initialize Game
****/
// Player class removed
var game = new LK.Game({
backgroundColor: 0x000000 // Black background
});
/****
* Game Code
****/
// Function to start the next level after menu
function startNextLevel() {
// Increase difficulty for each level
difficultyMultiplier = 1.0 + (currentLevel - 1) * 0.2; // 20% harder each level
// Increase number of flies based on level (capped at 50)
var levelFlies = Math.min(baseFliesPerLevel + (currentLevel - 1) * 5, 50);
fliesRemaining = levelFlies;
// Make insects harder to catch with each level
attractionDifficulty = Math.max(0.05, 0.1 - (currentLevel - 1) * 0.01);
// Select bee color for this level
var newBeeColor;
// First level is always yellow
if (currentLevel === 1) {
newBeeColor = 0xf7df18; // Yellow for first level
} else {
// Use a set of predefined colors for variety
var levelColors = [0xff0000,
// Red
0x00ff00,
// Green
0x0000ff,
// Blue
0xff00ff,
// Magenta
0x00ffff,
// Cyan
0xffa500,
// Orange
0x800080,
// Purple
0x008000 // Dark Green
];
// Use modulo to cycle through colors for higher levels
var colorIndex = (currentLevel - 2) % levelColors.length;
newBeeColor = levelColors[colorIndex];
}
// Update the current level bee color for reference
currentLevelBeeColor = newBeeColor;
// Create new flies and bees for the next level
// Create flies based on current level difficulty
for (var i = 0; i < fliesRemaining; i++) {
createInsect('fly', baseInsectSpeed * difficultyMultiplier);
}
// Add some bees as well for variety - bees get faster too
for (var i = 0; i < maxBees; i++) {
createInsect('bee', baseBeeSpeed * difficultyMultiplier, newBeeColor);
}
// Setup wing tweens for all new insects
setupWingTweens();
// Update score text with new fly count
scoreTxt.setText('Flies: ' + fliesRemaining);
levelTxt.setText('Level: ' + currentLevel);
}
// Game variables
var insects = [];
var lastTrailToggleTime = 0;
var trailsEnabled = false;
var timeElapsed = 0;
var currentLevel = 1;
var fliesRemaining = 30;
var fliesCaught = 0;
var beeCount = 0;
var maxBees = 13; // Maximum number of bees per level
var currentLevelBeeColor = 0xf7df18; // Initial bee color
var lastTouchX = 0; // Track last touch X position
var lastTouchY = 0; // Track last touch Y position
var touchActive = false; // Is touch currently active
// Difficulty scaling variables
var baseInsectSpeed = 5; // Starting speed for insects
var baseBeeSpeed = 3; // Starting speed for bees
var baseFliesPerLevel = 30; // Base number of flies per level
var difficultyMultiplier = 1.0; // Increases with each level
var attractionDifficulty = 0.1; // How hard insects are to catch (attraction force)
// Set background color
game.setBackgroundColor(0x87CEEB); // Sky blue background
// Initialize scoreboard to display flies remaining
var scoreTxt = new Text2('Flies: ' + fliesRemaining, {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Level display
var levelTxt = new Text2('Level: ' + currentLevel, {
size: 60,
fill: 0xFFFFFF
});
levelTxt.anchor.set(0.5, 0);
levelTxt.y = 100;
LK.gui.top.addChild(levelTxt);
// Create beehive at the bottom center
var beehive = new Beehive();
beehive.x = 1024; // Center horizontally
beehive.y = 2732 - 120; // Position right at the bottom, maintain height
game.addChild(beehive);
// Create initial flies for level 1
for (var i = 0; i < baseFliesPerLevel; i++) {
createInsect('fly', baseInsectSpeed);
}
// Set first level bees to yellow
currentLevelBeeColor = 0xf7df18; // Yellow color for first level bees
// Add some initial bees
for (var i = 0; i < maxBees; i++) {
createInsect('bee', baseBeeSpeed, currentLevelBeeColor);
}
// Set up wing flapping tweens for all insects
function setupWingTweens() {
for (var i = 0; i < insects.length; i++) {
var insect = insects[i];
var wingDuration = 250 + Math.random() * 150; // Much faster wing flap duration
// Left wing tween with faster flapping
tween(insect.leftWing, {
rotation: -1.2,
// Wider wing movement
scaleX: insect.leftWing.scaleX * 1.2 // Wing stretches during flap
}, {
duration: wingDuration * 0.6,
// Faster wing movement
easing: tween.easeInOut,
repeat: -1,
// Continuous flapping
yoyo: true // Back and forth movement
});
// Right wing tween with slight offset
tween(insect.rightWing, {
rotation: 1.2,
// Wider wing movement
scaleX: insect.rightWing.scaleX * 1.2 // Wing stretches during flap
}, {
duration: wingDuration * 0.6,
// Faster wing movement
easing: tween.easeInOut,
repeat: -1,
// Continuous flapping
yoyo: true // Back and forth movement
});
}
}
// Initialize wing tweens
setupWingTweens();
// Play background music with fade in
LK.playMusic('bgmusic', {
fade: {
start: 0,
end: 1,
duration: 1000
}
});
// Game timer
var gameTimer = LK.setInterval(function () {
timeElapsed += 1;
// Toggle trails every 10 seconds
if (timeElapsed % 10 === 0 && timeElapsed > 0) {
toggleTrails();
}
// Don't automatically create new insects as they're now part of the level system
}, 1000);
// Function to handle level completion
function levelComplete() {
// Store current level's caught flies for display
var caughtThisLevel = fliesCaught;
// Increase level
currentLevel++;
levelTxt.setText('Level: ' + currentLevel);
// Reset fly counter for next level (actual count will be set in startNextLevel)
fliesCaught = 0;
beeCount = 0;
// Create a level-up effect - more dramatic for higher levels
var flashIntensity = Math.min(0.5 + currentLevel * 0.05, 0.8);
LK.effects.flashScreen(0xFFFFFF, 500, flashIntensity);
// Remove any remaining insects
for (var i = insects.length - 1; i >= 0; i--) {
insects[i].destroy();
}
insects = [];
// Show level completion popup with fireworks
LK.setTimeout(function () {
// Create and display the level completion popup
var popup = new LevelCompletionPopup();
popup.x = 1024; // Center horizontally
popup.y = 1366; // Center vertically
game.addChild(popup);
// Start fireworks display after a short delay
LK.setTimeout(function () {
popup.startFireworks();
}, 500);
}, 500);
}
// Function to create a new insect
function createInsect(type, speed, beeColor) {
// If type is not specified, generate based on context
// When creating initial level flies, we'll pass 'fly' as the type
type = type || (Math.random() < 0.7 ? 'fly' : 'bee'); // 70% flies, 30% bees
speed = speed || 5 + Math.random() * 5; // Faster speed between 5-10
var insect = new Insect(type, speed, beeColor);
// Position randomly
insect.x = Math.random() * 2048;
insect.y = Math.random() * 2000; // Keep away from bottom
game.addChild(insect);
insects.push(insect);
// Setup smooth wing tweens for this insect
var wingDuration = 250 + Math.random() * 150; // Much faster wing flap duration
// Left wing tween with faster flapping
tween(insect.leftWing, {
rotation: -1.2,
// Wider wing movement
scaleX: insect.leftWing.scaleX * 1.2 // Wing stretches during flap
}, {
duration: wingDuration * 0.6,
// Faster wing movement
easing: tween.easeInOut,
repeat: -1,
// Continuous flapping
yoyo: true // Back and forth movement
});
// Right wing tween with slight offset
tween(insect.rightWing, {
rotation: 1.2,
// Wider wing movement
scaleX: insect.rightWing.scaleX * 1.2 // Wing stretches during flap
}, {
duration: wingDuration * 0.6,
// Faster wing movement
easing: tween.easeInOut,
repeat: -1,
// Continuous flapping
yoyo: true // Back and forth movement
});
// Add more dynamic body movement
var bodyBobDuration = 200 + Math.random() * 150; // Much faster body movement
tween(insect, {
y: insect.y + (Math.random() * 50 - 25),
// Increased random up/down movement
x: insect.x + (Math.random() * 50 - 25),
// Increased random left/right movement
rotation: insect.rotation + (Math.random() * 0.3 - 0.15) // More rotation for erratic movement
}, {
duration: bodyBobDuration,
easing: tween.easeInOut,
repeat: -1,
// Infinite repetition
yoyo: true // Ping-pong effect
});
// Make all insects clickable with larger hitbox
insect.down = function (x, y, obj) {
// Calculate distance from touch to insect center
var dx = x - insect.x;
var dy = y - insect.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Increased hit area for easier catching - approximately double the visual size
var hitRadius = 120; // Larger hit area
// Use distance check instead of direct hit test
if (distance <= hitRadius) {
if (insect.type === 'fly') {
// Make the fly visually "pop" before removing it
tween(insect, {
scaleX: 1.3,
scaleY: 1.3,
alpha: 0.2
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
// Remove the fly when clicked
insect.destroy();
// Remove from insects array
var index = insects.indexOf(insect);
if (index > -1) {
insects.splice(index, 1);
}
// Update score
fliesCaught++;
fliesRemaining--;
scoreTxt.setText('Flies: ' + fliesRemaining);
// Play buzz sound
LK.getSound('buzz').play();
// Check if level is complete
if (fliesRemaining <= 0) {
levelComplete();
}
}
});
} else if (insect.type === 'bee') {
// Game over when clicking a bee
LK.effects.flashScreen(0xFF0000, 1000, 0.7); // Red flash for danger
LK.getSound('buzz').play();
// Make the bee visually "angry" before game over
tween(insect, {
scaleX: 1.5,
scaleY: 1.5,
tint: 0xFF0000
}, {
duration: 300,
easing: tween.easeOut
});
LK.setTimeout(function () {
LK.showGameOver(); // Show game over screen
}, 500);
}
}
};
// Play buzz sound on creation
LK.getSound('buzz').play();
}
// Function to toggle trails on insects that have the trail feature
function toggleTrails() {
trailsEnabled = !trailsEnabled;
for (var i = 0; i < insects.length; i++) {
// Only enable trails on insects that have the trail feature
if (insects[i].hasTrailFeature) {
insects[i].trailActive = trailsEnabled;
}
}
if (trailsEnabled) {
// Flash screen slightly to indicate trails activated
LK.effects.flashScreen(0xFFFFFF, 300, 0.3);
}
}
// Helper function to calculate distance between two points
function getDistance(x1, y1, x2, y2) {
var dx = x2 - x1;
var dy = y2 - y1;
return Math.sqrt(dx * dx + dy * dy);
}
// Touch/mouse handlers to track player movement for insect attraction
game.down = function (x, y, obj) {
lastTouchX = x;
lastTouchY = y;
touchActive = true;
// Check if any insects are close to the touch point
for (var i = 0; i < insects.length; i++) {
var insect = insects[i];
var dx = insect.x - x;
var dy = insect.y - y;
var distance = Math.sqrt(dx * dx + dy * dy);
// If touch is close to an insect, activate its click handler
if (distance < 100) {
insect.down(x, y, obj);
break; // Only handle one insect at a time
}
}
};
game.move = function (x, y, obj) {
if (touchActive) {
lastTouchX = x;
lastTouchY = y;
}
};
game.up = function (x, y, obj) {
// Keep the last position for a while to let insects still be attracted
// Will naturally fade when insects move elsewhere
touchActive = false;
};
// Main game update function
game.update = function () {
// Update beehive
beehive.update();
// Create a subtle visual cue if touch is active
if (touchActive && LK.ticks % 15 === 0) {
// Create a ripple effect at touch point
var ripple = LK.getAsset('trailDot', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1,
alpha: 0.6,
tint: 0xFFFFFF
});
ripple.x = lastTouchX;
ripple.y = lastTouchY;
game.addChild(ripple);
// Animate ripple expanding and fading
tween(ripple, {
scaleX: 8,
scaleY: 8,
alpha: 0
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
ripple.destroy();
}
});
}
// Count how many bees we currently have
beeCount = 0;
for (var i = 0; i < insects.length; i++) {
if (insects[i].type === 'bee') {
beeCount++;
}
}
// Occasionally add a new bee if we're below the maximum
if (LK.ticks % 180 === 0 && beeCount < maxBees) {
// Use the current level's bee color for consistency
var newBee = new Insect('bee', 3 + Math.random() * 2, currentLevelBeeColor);
// Position bee near the beehive
newBee.x = beehive.x + (Math.random() * 200 - 100);
newBee.y = beehive.y - 100 - Math.random() * 100;
game.addChild(newBee);
insects.push(newBee);
// Setup wing tweens for the new bee
var wingDuration = 250 + Math.random() * 150;
tween(newBee.leftWing, {
rotation: -1.2,
scaleX: newBee.leftWing.scaleX * 1.2
}, {
duration: wingDuration * 0.6,
easing: tween.easeInOut,
repeat: -1,
yoyo: true
});
tween(newBee.rightWing, {
rotation: 1.2,
scaleX: newBee.rightWing.scaleX * 1.2
}, {
duration: wingDuration * 0.6,
easing: tween.easeInOut,
repeat: -1,
yoyo: true
});
// Play buzz sound
LK.getSound('buzz').play();
}
// Add slight random movement to insects occasionally
if (LK.ticks % 60 === 0) {
for (var i = 0; i < insects.length; i++) {
var insect = insects[i];
// Change velocity slightly
insect.vx += (Math.random() - 0.5) * 2;
insect.vy += (Math.random() - 0.5) * 2;
// Limit max speed
var speed = Math.sqrt(insect.vx * insect.vx + insect.vy * insect.vy);
if (speed > insect.speed) {
insect.vx = insect.vx / speed * insect.speed;
insect.vy = insect.vy / speed * insect.speed;
}
}
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1", {
highScore: 0
});
/****
* Classes
****/
var Beehive = Container.expand(function () {
var self = Container.call(this);
// Main hive body - preserve dimensions
self.hiveBody = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.2,
scaleY: 1.0,
tint: 0xD8B373 // More honey-like color for beehive
});
// Add honeycomb texture effect with layered shapes - preserve proportions
for (var i = 0; i < 3; i++) {
var honeyLayer = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.1 - i * 0.1,
scaleY: 0.9 - i * 0.1,
alpha: 0.3,
tint: 0xFFD700 // Gold honey color
});
}
// Hive entrance - preserve proportions
self.entrance = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
y: -20,
scaleX: 0.4,
scaleY: 0.2,
tint: 0x8B4513 // Brown color for entrance
});
// Darker entrance hole - preserve proportions
self.entranceHole = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
y: -20,
scaleX: 0.2,
scaleY: 0.15,
tint: 0x503000 // Dark entrance hole
});
// Hive texture stripes - preserve proportions
for (var i = 0; i < 5; i++) {
var stripe = self.attachAsset('beeStripe1', {
anchorX: 0.5,
anchorY: 0.5,
y: -25 + i * 15,
scaleX: 1.1 - Math.abs(i - 2) * 0.1,
// Curved effect
scaleY: 0.15
});
}
// Add some honey drips - preserve proportions
for (var i = 0; i < 3; i++) {
var honeyDrip = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.0,
x: -30 + i * 30,
y: 30,
scaleX: 0.1,
scaleY: 0.2 + Math.random() * 0.15,
tint: 0xFFD700 // Gold honey color
});
}
// Add some bees hovering near the hive - preserve proportions
for (var i = 0; i < 3; i++) {
var hoverBee = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
x: -45 + i * 25,
y: -30 - i * 8,
scaleX: 0.15,
scaleY: 0.08,
tint: 0xF7DF18
});
// Wings for hovering bees - preserve proportions
var leftWing = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
x: -45 + i * 25 - 4,
y: -30 - i * 8 - 4,
scaleX: 0.1,
scaleY: 0.04,
tint: 0xFFFFFF,
alpha: 0.6
});
var rightWing = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
x: -45 + i * 25 - 4,
y: -30 - i * 8 + 4,
scaleX: 0.1,
scaleY: 0.04,
tint: 0xFFFFFF,
alpha: 0.6
});
// Animate wings
tween(leftWing, {
rotation: -0.8,
alpha: 0.8
}, {
duration: 100 + i * 10,
easing: tween.easeInOut,
repeat: -1,
yoyo: true
});
tween(rightWing, {
rotation: 0.8,
alpha: 0.8
}, {
duration: 100 + i * 10,
easing: tween.easeInOut,
repeat: -1,
yoyo: true
});
}
self.bees = [];
self.lastBeeSpawn = 0;
// Small breathing animation for the hive
tween(self, {
y: self.y - 8
}, {
duration: 3000,
easing: tween.easeInOut,
repeat: -1,
yoyo: true
});
// Add subtle pulsing effect to the hive
tween(self.hiveBody, {
scaleX: self.hiveBody.scaleX * 1.03,
scaleY: self.hiveBody.scaleY * 1.02
}, {
duration: 2000,
easing: tween.easeInOut,
repeat: -1,
yoyo: true
});
self.update = function () {
// Bee spawning has been disabled
// We keep the update method for future functionality
};
self.spawnBee = function () {
var bee = new Insect('bee', 3);
bee.x = self.x;
bee.y = self.y - 80;
game.addChild(bee);
insects.push(bee);
// Make the entrance "pulse" when a bee emerges
tween(self.entrance, {
scaleX: self.entrance.scaleX * 1.2,
scaleY: self.entrance.scaleY * 1.2
}, {
duration: 200,
easing: tween.easeOut,
complete: function complete() {
tween(self.entrance, {
scaleX: 1.0,
scaleY: 0.6
}, {
duration: 300,
easing: tween.easeIn
});
}
});
// Setup wing tweens for this new bee
var wingDuration = 500 + Math.random() * 300;
tween(bee.leftWing, {
rotation: -1.2,
scaleX: bee.leftWing.scaleX * 1.2
}, {
duration: wingDuration * 0.6,
easing: tween.easeInOut,
repeat: -1,
yoyo: true
});
tween(bee.rightWing, {
rotation: 1.2,
scaleX: bee.rightWing.scaleX * 1.2
}, {
duration: wingDuration * 0.6,
easing: tween.easeInOut,
repeat: -1,
yoyo: true
});
// Play buzz sound
LK.getSound('buzz').play();
// Add initial flight pattern as bee leaves hive
tween(bee, {
x: bee.x + (Math.random() > 0.5 ? 100 : -100),
y: bee.y - 100
}, {
duration: 800,
easing: tween.easeOut
});
};
return self;
});
var Firework = Container.expand(function (x, y, color) {
var self = Container.call(this);
self.x = x || 1024;
self.y = y || 1366;
self.color = color || 0xffcc00;
self.particles = [];
self.particleCount = 20 + Math.floor(Math.random() * 30);
// Create particles
for (var i = 0; i < self.particleCount; i++) {
var particle = self.attachAsset('trailDot', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1 + Math.random() * 2,
scaleY: 1 + Math.random() * 2,
tint: self.color,
alpha: 0.8
});
// Random angle for each particle
var angle = Math.random() * Math.PI * 2;
var speed = 2 + Math.random() * 8;
particle.vx = Math.cos(angle) * speed;
particle.vy = Math.sin(angle) * speed;
particle.gravity = 0.05 + Math.random() * 0.05;
self.particles.push(particle);
}
// Animate explosion
self.update = function () {
var allFaded = true;
for (var i = 0; i < self.particles.length; i++) {
var p = self.particles[i];
p.x += p.vx;
p.y += p.vy;
p.vy += p.gravity; // Add gravity
p.alpha -= 0.01; // Fade out
if (p.alpha > 0.1) {
allFaded = false;
}
}
// Remove firework when all particles have faded
if (allFaded) {
self.destroy();
}
};
return self;
});
var Insect = Container.expand(function (type, speed, beeColor) {
var self = Container.call(this);
self.type = type || 'bee';
self.speed = speed || 6; // Double default speed
self.vx = Math.random() * self.speed * (Math.random() > 0.5 ? 1 : -1);
self.vy = Math.random() * self.speed * (Math.random() > 0.5 ? 1 : -1);
self.lastTrailTime = 0;
// Only 1/3 of insects will have trails by default
self.trailActive = false;
self.hasTrailFeature = Math.random() < 0.33; // Only 33% of insects can have trails
self.trails = [];
self.flightOffset = Math.random() * Math.PI * 2; // Random flight pattern offset
self.flightSpeed = 0.5 + Math.random() * 0.5; // Random flight pattern speed
self.lastRotation = Math.atan2(self.vy, self.vx);
self.interactive = true; // Make insect clickable
self.lastTouchPoint = {
x: 0,
y: 0
}; // Track the last touch point
self.attractionForce = 0.1 + Math.random() * 0.3; // How strongly insect is drawn to cursor
self.lastAttracted = 0; // When was the insect last attracted to cursor
if (self.type === 'bee') {
// Main body
self.body = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.4,
scaleY: 0.7,
tint: beeColor || 0xf7df18 // Use provided bee color or default
});
// Bee head
self.head = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
x: 80,
scaleX: 0.6,
scaleY: 0.6
});
// Left wing
self.leftWing = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
x: -25,
y: -30,
rotation: -0.7,
scaleX: 0.8,
alpha: 0.6,
tint: 0xffffff
});
// Right wing
self.rightWing = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
x: -25,
y: 30,
rotation: 0.7,
scaleX: 0.8,
alpha: 0.6,
tint: 0xffffff
});
// Body stripes (reversed direction - vertical instead of horizontal)
self.stripe1 = self.attachAsset('beeStripe1', {
anchorX: 0.5,
anchorY: 0.5,
rotation: Math.PI / 2,
x: -25,
scaleX: 0.7,
scaleY: 0.8,
tint: 0x000000
});
self.stripe2 = self.attachAsset('beeStripe2', {
anchorX: 0.5,
anchorY: 0.5,
rotation: Math.PI / 2,
x: 25,
scaleX: 0.7,
scaleY: 0.8,
tint: 0x000000
});
} else {
// Main body
self.body = self.attachAsset('flyBody', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1.6,
scaleY: 0.6
});
// Fly head
self.head = self.attachAsset('flyBody', {
anchorX: 0.5,
anchorY: 0.5,
x: 90,
scaleX: 0.5,
scaleY: 0.5
});
// Left wing
self.leftWing = self.attachAsset('flyBody', {
anchorX: 0.5,
anchorY: 0.5,
x: -15,
y: -25,
rotation: -0.6,
scaleX: 1.0,
scaleY: 0.6,
alpha: 0.6,
tint: 0xccccff
});
// Right wing
self.rightWing = self.attachAsset('flyBody', {
anchorX: 0.5,
anchorY: 0.5,
x: -15,
y: 25,
rotation: 0.6,
scaleX: 1.0,
scaleY: 0.6,
alpha: 0.6,
tint: 0xccccff
});
// Body stripe
self.stripe1 = self.attachAsset('flyStripe', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.7,
scaleY: 0.8,
tint: 0x000000
});
}
self.update = function () {
// Create more dynamic flight pattern with rapid changes in direction and speed
var time = LK.ticks * 0.01;
// Random direction changes based on time
if (Math.random() < 0.03) {
// Occasionally make sharp turns
self.vx += (Math.random() - 0.5) * self.speed * 0.8;
self.vy += (Math.random() - 0.5) * self.speed * 0.8;
}
// Check if a touch point exists to be attracted to
if (lastTouchX !== 0 && lastTouchY !== 0) {
// Only update attraction based on cursor every few frames
if (LK.ticks - self.lastAttracted > 10) {
self.lastAttracted = LK.ticks;
// Calculate direction to cursor
var dx = lastTouchX - self.x;
var dy = lastTouchY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Only attract if within reasonable range (increases chances of being caught)
if (distance < 500) {
// Calculate attraction force (stronger when closer)
// Use global attractionDifficulty to make it harder in higher levels
var attractStrength = self.attractionForce * attractionDifficulty * (1 - distance / 500);
// Make attraction weaker for higher speeds (harder to control fast insects)
attractStrength = attractStrength / (self.speed * 0.2);
// Add attraction vector to current velocity - insects can resist player attraction in higher levels
self.vx += dx / distance * attractStrength * self.speed;
self.vy += dy / distance * attractStrength * self.speed;
}
}
}
// Add jerky, insect-like movement with bursts of speed
var jerkFactor = Math.sin(time * 16) * 1.0; // Much higher frequency and amplitude for extreme movement
var burstSpeed = Math.random() < 0.05 ? self.speed * 3 : 0; // More frequent and faster speed bursts
// Normalize velocity for consistent speed
var currentSpeed = Math.sqrt(self.vx * self.vx + self.vy * self.vy);
if (currentSpeed > 0) {
var normalizedVx = self.vx / currentSpeed;
var normalizedVy = self.vy / currentSpeed;
// Apply jerk factor and burst speed to create more dynamic movement
self.x += self.vx + normalizedVx * jerkFactor + normalizedVx * burstSpeed;
self.y += self.vy + normalizedVy * jerkFactor + normalizedVy * burstSpeed;
} else {
// Prevent stalling
self.vx = (Math.random() - 0.5) * self.speed;
self.vy = (Math.random() - 0.5) * self.speed;
self.x += self.vx;
self.y += self.vy;
}
// More energetic bounce off screen edges with slight angle change
if (self.x < 0 || self.x > 2048) {
self.vx *= -1.1; // Bounce slightly faster
// Add slight randomness to bounce angle
self.vy += (Math.random() - 0.5) * self.speed * 0.5;
self.x = Math.max(0, Math.min(2048, self.x));
}
if (self.y < 0 || self.y > 2732) {
self.vy *= -1.1; // Bounce slightly faster
// Add slight randomness to bounce angle
self.vx += (Math.random() - 0.5) * self.speed * 0.5;
self.y = Math.max(0, Math.min(2732, self.y));
}
// More dynamic rotation with slight overshoot
var targetRotation = Math.atan2(self.vy, self.vx);
// Add slight randomness to rotation for more natural movement
var rotationSpeed = 0.15 + Math.random() * 0.1;
self.rotation = self.rotation + (targetRotation - self.rotation) * rotationSpeed;
// Wings are now animated with tweens
// Just update wing alpha for pulsing effect
if (self.leftWing && self.rightWing) {
var wingAlpha = 0.6 + Math.sin(LK.ticks * 0.1) * 0.2;
self.leftWing.alpha = wingAlpha;
self.rightWing.alpha = wingAlpha;
}
// Create trails when active and insect has the trail feature
if (self.hasTrailFeature && self.trailActive && LK.ticks % 5 === 0) {
var dot = LK.getAsset('trailDot', {
anchorX: 0.5,
anchorY: 0.5,
alpha: 0.7,
tint: 0xFFFFFF // White trail dot color
});
dot.x = self.x;
dot.y = self.y;
if (self.type === 'bee') {
dot.tint = 0xFFFFFF; // Always white trail for bees
} else {
dot.tint = 0x000000; // Black trail for flies
}
// Add dot to the game
game.addChild(dot);
// Store reference to dot
self.trails.push({
dot: dot,
createdAt: LK.ticks
});
}
// Remove old trail dots after 10 seconds (previously 2 seconds)
for (var i = self.trails.length - 1; i >= 0; i--) {
var trail = self.trails[i];
if (LK.ticks - trail.createdAt > 600) {
// Changed from 120 (2 sec) to 600 (10 sec)
trail.dot.destroy();
self.trails.splice(i, 1);
}
}
};
return self;
});
var LevelCompleteMenu = Container.expand(function () {
var self = Container.call(this);
// Dark semi-transparent background
self.bg = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 20,
scaleY: 20,
tint: 0x000000,
alpha: 0.6
});
// Menu panel
self.panel = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 12,
scaleY: 8,
tint: 0xFFD700
});
// Title text
self.titleText = new Text2('Level Complete!', {
size: 120,
fill: 0x000000
});
self.titleText.anchor.set(0.5, 0.5);
self.titleText.y = -200;
self.addChild(self.titleText);
// Level display
self.levelText = new Text2('Level ' + currentLevel + ' Completed', {
size: 80,
fill: 0x000000
});
self.levelText.anchor.set(0.5, 0.5);
self.levelText.y = -80;
self.addChild(self.levelText);
// Difficulty indicator - shows players the challenge is increasing
self.difficultyText = new Text2('Difficulty: ' + Math.floor(difficultyMultiplier * 100) + '%', {
size: 60,
fill: 0x660000
});
self.difficultyText.anchor.set(0.5, 0.5);
self.difficultyText.y = -20;
self.addChild(self.difficultyText);
// Score display
self.scoreText = new Text2('Flies Caught: ' + fliesCaught, {
size: 80,
fill: 0x000000
});
self.scoreText.anchor.set(0.5, 0.5);
self.scoreText.y = 0;
self.addChild(self.scoreText);
// High score display
var highScore = storage.highScore || 0;
self.highScoreText = new Text2('High Score: ' + highScore, {
size: 80,
fill: 0x000000
});
self.highScoreText.anchor.set(0.5, 0.5);
self.highScoreText.y = 100;
self.addChild(self.highScoreText);
// Continue button
self.continueButton = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
y: 300,
scaleX: 6,
scaleY: 2,
tint: 0x008000
});
// Continue button text
self.continueButtonText = new Text2('Continue', {
size: 80,
fill: 0xFFFFFF
});
self.continueButtonText.anchor.set(0.5, 0.5);
self.continueButtonText.y = 300;
self.addChild(self.continueButtonText);
// Make button interactive
self.continueButton.interactive = true;
self.continueButton.down = function (x, y, obj) {
self.destroy();
startNextLevel();
};
// Update menu with current level information
self.updateMenu = function (level, caught) {
self.levelText.setText('Level ' + level + ' Completed');
self.scoreText.setText('Flies Caught: ' + caught);
// Show next level difficulty
var nextLevelDifficulty = 1.0 + level * 0.2; // Same formula as in startNextLevel
self.difficultyText.setText('Next Level Difficulty: ' + Math.floor(nextLevelDifficulty * 100) + '%');
// Change color based on difficulty level
if (nextLevelDifficulty >= 2.0) {
self.difficultyText.style.fill = 0xFF0000; // Red for very hard
} else if (nextLevelDifficulty >= 1.5) {
self.difficultyText.style.fill = 0xFF6600; // Orange for harder
}
// Update high score
var highScore = storage.highScore || 0;
if (caught > highScore) {
highScore = caught;
storage.highScore = highScore;
}
self.highScoreText.setText('High Score: ' + highScore);
};
return self;
});
var LevelCompletionPopup = Container.expand(function () {
var self = Container.call(this);
// Add a semi-transparent background
self.bg = self.attachAsset('beeBody', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 20,
scaleY: 8,
tint: 0x000000,
alpha: 0.6
});
// Main text that says "LEVEL COMPLETE"
self.levelCompleteText = new Text2('LEVEL COMPLETE!', {
size: 150,
fill: 0xFFFFFF
});
self.levelCompleteText.anchor.set(0.5, 0.5);
self.addChild(self.levelCompleteText);
// Make the text pulse for emphasis
tween(self.levelCompleteText, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 800,
easing: tween.easeInOut,
repeat: -1,
yoyo: true
});
// Auto-dismiss after fireworks display
self.startFireworks = function () {
var fireworksCount = 12;
var fireworksInterval = LK.setInterval(function () {
var x = Math.random() * 1800 + 100;
var y = Math.random() * 1000 + 600;
var colors = [0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xff00ff, 0x00ffff];
var color = colors[Math.floor(Math.random() * colors.length)];
var firework = new Firework(x, y, color);
game.addChild(firework);
fireworksCount--;
if (fireworksCount <= 0) {
LK.clearInterval(fireworksInterval);
// Show menu after fireworks finish
LK.setTimeout(function () {
self.destroy();
var menu = new LevelCompleteMenu();
menu.x = 1024; // Center horizontally
menu.y = 1366; // Center vertically
menu.updateMenu(currentLevel, fliesCaught);
game.addChild(menu);
}, 2000);
}
}, 300);
};
return self;
});
/****
* Initialize Game
****/
// Player class removed
var game = new LK.Game({
backgroundColor: 0x000000 // Black background
});
/****
* Game Code
****/
// Function to start the next level after menu
function startNextLevel() {
// Increase difficulty for each level
difficultyMultiplier = 1.0 + (currentLevel - 1) * 0.2; // 20% harder each level
// Increase number of flies based on level (capped at 50)
var levelFlies = Math.min(baseFliesPerLevel + (currentLevel - 1) * 5, 50);
fliesRemaining = levelFlies;
// Make insects harder to catch with each level
attractionDifficulty = Math.max(0.05, 0.1 - (currentLevel - 1) * 0.01);
// Select bee color for this level
var newBeeColor;
// First level is always yellow
if (currentLevel === 1) {
newBeeColor = 0xf7df18; // Yellow for first level
} else {
// Use a set of predefined colors for variety
var levelColors = [0xff0000,
// Red
0x00ff00,
// Green
0x0000ff,
// Blue
0xff00ff,
// Magenta
0x00ffff,
// Cyan
0xffa500,
// Orange
0x800080,
// Purple
0x008000 // Dark Green
];
// Use modulo to cycle through colors for higher levels
var colorIndex = (currentLevel - 2) % levelColors.length;
newBeeColor = levelColors[colorIndex];
}
// Update the current level bee color for reference
currentLevelBeeColor = newBeeColor;
// Create new flies and bees for the next level
// Create flies based on current level difficulty
for (var i = 0; i < fliesRemaining; i++) {
createInsect('fly', baseInsectSpeed * difficultyMultiplier);
}
// Add some bees as well for variety - bees get faster too
for (var i = 0; i < maxBees; i++) {
createInsect('bee', baseBeeSpeed * difficultyMultiplier, newBeeColor);
}
// Setup wing tweens for all new insects
setupWingTweens();
// Update score text with new fly count
scoreTxt.setText('Flies: ' + fliesRemaining);
levelTxt.setText('Level: ' + currentLevel);
}
// Game variables
var insects = [];
var lastTrailToggleTime = 0;
var trailsEnabled = false;
var timeElapsed = 0;
var currentLevel = 1;
var fliesRemaining = 30;
var fliesCaught = 0;
var beeCount = 0;
var maxBees = 13; // Maximum number of bees per level
var currentLevelBeeColor = 0xf7df18; // Initial bee color
var lastTouchX = 0; // Track last touch X position
var lastTouchY = 0; // Track last touch Y position
var touchActive = false; // Is touch currently active
// Difficulty scaling variables
var baseInsectSpeed = 5; // Starting speed for insects
var baseBeeSpeed = 3; // Starting speed for bees
var baseFliesPerLevel = 30; // Base number of flies per level
var difficultyMultiplier = 1.0; // Increases with each level
var attractionDifficulty = 0.1; // How hard insects are to catch (attraction force)
// Set background color
game.setBackgroundColor(0x87CEEB); // Sky blue background
// Initialize scoreboard to display flies remaining
var scoreTxt = new Text2('Flies: ' + fliesRemaining, {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Level display
var levelTxt = new Text2('Level: ' + currentLevel, {
size: 60,
fill: 0xFFFFFF
});
levelTxt.anchor.set(0.5, 0);
levelTxt.y = 100;
LK.gui.top.addChild(levelTxt);
// Create beehive at the bottom center
var beehive = new Beehive();
beehive.x = 1024; // Center horizontally
beehive.y = 2732 - 120; // Position right at the bottom, maintain height
game.addChild(beehive);
// Create initial flies for level 1
for (var i = 0; i < baseFliesPerLevel; i++) {
createInsect('fly', baseInsectSpeed);
}
// Set first level bees to yellow
currentLevelBeeColor = 0xf7df18; // Yellow color for first level bees
// Add some initial bees
for (var i = 0; i < maxBees; i++) {
createInsect('bee', baseBeeSpeed, currentLevelBeeColor);
}
// Set up wing flapping tweens for all insects
function setupWingTweens() {
for (var i = 0; i < insects.length; i++) {
var insect = insects[i];
var wingDuration = 250 + Math.random() * 150; // Much faster wing flap duration
// Left wing tween with faster flapping
tween(insect.leftWing, {
rotation: -1.2,
// Wider wing movement
scaleX: insect.leftWing.scaleX * 1.2 // Wing stretches during flap
}, {
duration: wingDuration * 0.6,
// Faster wing movement
easing: tween.easeInOut,
repeat: -1,
// Continuous flapping
yoyo: true // Back and forth movement
});
// Right wing tween with slight offset
tween(insect.rightWing, {
rotation: 1.2,
// Wider wing movement
scaleX: insect.rightWing.scaleX * 1.2 // Wing stretches during flap
}, {
duration: wingDuration * 0.6,
// Faster wing movement
easing: tween.easeInOut,
repeat: -1,
// Continuous flapping
yoyo: true // Back and forth movement
});
}
}
// Initialize wing tweens
setupWingTweens();
// Play background music with fade in
LK.playMusic('bgmusic', {
fade: {
start: 0,
end: 1,
duration: 1000
}
});
// Game timer
var gameTimer = LK.setInterval(function () {
timeElapsed += 1;
// Toggle trails every 10 seconds
if (timeElapsed % 10 === 0 && timeElapsed > 0) {
toggleTrails();
}
// Don't automatically create new insects as they're now part of the level system
}, 1000);
// Function to handle level completion
function levelComplete() {
// Store current level's caught flies for display
var caughtThisLevel = fliesCaught;
// Increase level
currentLevel++;
levelTxt.setText('Level: ' + currentLevel);
// Reset fly counter for next level (actual count will be set in startNextLevel)
fliesCaught = 0;
beeCount = 0;
// Create a level-up effect - more dramatic for higher levels
var flashIntensity = Math.min(0.5 + currentLevel * 0.05, 0.8);
LK.effects.flashScreen(0xFFFFFF, 500, flashIntensity);
// Remove any remaining insects
for (var i = insects.length - 1; i >= 0; i--) {
insects[i].destroy();
}
insects = [];
// Show level completion popup with fireworks
LK.setTimeout(function () {
// Create and display the level completion popup
var popup = new LevelCompletionPopup();
popup.x = 1024; // Center horizontally
popup.y = 1366; // Center vertically
game.addChild(popup);
// Start fireworks display after a short delay
LK.setTimeout(function () {
popup.startFireworks();
}, 500);
}, 500);
}
// Function to create a new insect
function createInsect(type, speed, beeColor) {
// If type is not specified, generate based on context
// When creating initial level flies, we'll pass 'fly' as the type
type = type || (Math.random() < 0.7 ? 'fly' : 'bee'); // 70% flies, 30% bees
speed = speed || 5 + Math.random() * 5; // Faster speed between 5-10
var insect = new Insect(type, speed, beeColor);
// Position randomly
insect.x = Math.random() * 2048;
insect.y = Math.random() * 2000; // Keep away from bottom
game.addChild(insect);
insects.push(insect);
// Setup smooth wing tweens for this insect
var wingDuration = 250 + Math.random() * 150; // Much faster wing flap duration
// Left wing tween with faster flapping
tween(insect.leftWing, {
rotation: -1.2,
// Wider wing movement
scaleX: insect.leftWing.scaleX * 1.2 // Wing stretches during flap
}, {
duration: wingDuration * 0.6,
// Faster wing movement
easing: tween.easeInOut,
repeat: -1,
// Continuous flapping
yoyo: true // Back and forth movement
});
// Right wing tween with slight offset
tween(insect.rightWing, {
rotation: 1.2,
// Wider wing movement
scaleX: insect.rightWing.scaleX * 1.2 // Wing stretches during flap
}, {
duration: wingDuration * 0.6,
// Faster wing movement
easing: tween.easeInOut,
repeat: -1,
// Continuous flapping
yoyo: true // Back and forth movement
});
// Add more dynamic body movement
var bodyBobDuration = 200 + Math.random() * 150; // Much faster body movement
tween(insect, {
y: insect.y + (Math.random() * 50 - 25),
// Increased random up/down movement
x: insect.x + (Math.random() * 50 - 25),
// Increased random left/right movement
rotation: insect.rotation + (Math.random() * 0.3 - 0.15) // More rotation for erratic movement
}, {
duration: bodyBobDuration,
easing: tween.easeInOut,
repeat: -1,
// Infinite repetition
yoyo: true // Ping-pong effect
});
// Make all insects clickable with larger hitbox
insect.down = function (x, y, obj) {
// Calculate distance from touch to insect center
var dx = x - insect.x;
var dy = y - insect.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Increased hit area for easier catching - approximately double the visual size
var hitRadius = 120; // Larger hit area
// Use distance check instead of direct hit test
if (distance <= hitRadius) {
if (insect.type === 'fly') {
// Make the fly visually "pop" before removing it
tween(insect, {
scaleX: 1.3,
scaleY: 1.3,
alpha: 0.2
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
// Remove the fly when clicked
insect.destroy();
// Remove from insects array
var index = insects.indexOf(insect);
if (index > -1) {
insects.splice(index, 1);
}
// Update score
fliesCaught++;
fliesRemaining--;
scoreTxt.setText('Flies: ' + fliesRemaining);
// Play buzz sound
LK.getSound('buzz').play();
// Check if level is complete
if (fliesRemaining <= 0) {
levelComplete();
}
}
});
} else if (insect.type === 'bee') {
// Game over when clicking a bee
LK.effects.flashScreen(0xFF0000, 1000, 0.7); // Red flash for danger
LK.getSound('buzz').play();
// Make the bee visually "angry" before game over
tween(insect, {
scaleX: 1.5,
scaleY: 1.5,
tint: 0xFF0000
}, {
duration: 300,
easing: tween.easeOut
});
LK.setTimeout(function () {
LK.showGameOver(); // Show game over screen
}, 500);
}
}
};
// Play buzz sound on creation
LK.getSound('buzz').play();
}
// Function to toggle trails on insects that have the trail feature
function toggleTrails() {
trailsEnabled = !trailsEnabled;
for (var i = 0; i < insects.length; i++) {
// Only enable trails on insects that have the trail feature
if (insects[i].hasTrailFeature) {
insects[i].trailActive = trailsEnabled;
}
}
if (trailsEnabled) {
// Flash screen slightly to indicate trails activated
LK.effects.flashScreen(0xFFFFFF, 300, 0.3);
}
}
// Helper function to calculate distance between two points
function getDistance(x1, y1, x2, y2) {
var dx = x2 - x1;
var dy = y2 - y1;
return Math.sqrt(dx * dx + dy * dy);
}
// Touch/mouse handlers to track player movement for insect attraction
game.down = function (x, y, obj) {
lastTouchX = x;
lastTouchY = y;
touchActive = true;
// Check if any insects are close to the touch point
for (var i = 0; i < insects.length; i++) {
var insect = insects[i];
var dx = insect.x - x;
var dy = insect.y - y;
var distance = Math.sqrt(dx * dx + dy * dy);
// If touch is close to an insect, activate its click handler
if (distance < 100) {
insect.down(x, y, obj);
break; // Only handle one insect at a time
}
}
};
game.move = function (x, y, obj) {
if (touchActive) {
lastTouchX = x;
lastTouchY = y;
}
};
game.up = function (x, y, obj) {
// Keep the last position for a while to let insects still be attracted
// Will naturally fade when insects move elsewhere
touchActive = false;
};
// Main game update function
game.update = function () {
// Update beehive
beehive.update();
// Create a subtle visual cue if touch is active
if (touchActive && LK.ticks % 15 === 0) {
// Create a ripple effect at touch point
var ripple = LK.getAsset('trailDot', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1,
alpha: 0.6,
tint: 0xFFFFFF
});
ripple.x = lastTouchX;
ripple.y = lastTouchY;
game.addChild(ripple);
// Animate ripple expanding and fading
tween(ripple, {
scaleX: 8,
scaleY: 8,
alpha: 0
}, {
duration: 400,
easing: tween.easeOut,
onFinish: function onFinish() {
ripple.destroy();
}
});
}
// Count how many bees we currently have
beeCount = 0;
for (var i = 0; i < insects.length; i++) {
if (insects[i].type === 'bee') {
beeCount++;
}
}
// Occasionally add a new bee if we're below the maximum
if (LK.ticks % 180 === 0 && beeCount < maxBees) {
// Use the current level's bee color for consistency
var newBee = new Insect('bee', 3 + Math.random() * 2, currentLevelBeeColor);
// Position bee near the beehive
newBee.x = beehive.x + (Math.random() * 200 - 100);
newBee.y = beehive.y - 100 - Math.random() * 100;
game.addChild(newBee);
insects.push(newBee);
// Setup wing tweens for the new bee
var wingDuration = 250 + Math.random() * 150;
tween(newBee.leftWing, {
rotation: -1.2,
scaleX: newBee.leftWing.scaleX * 1.2
}, {
duration: wingDuration * 0.6,
easing: tween.easeInOut,
repeat: -1,
yoyo: true
});
tween(newBee.rightWing, {
rotation: 1.2,
scaleX: newBee.rightWing.scaleX * 1.2
}, {
duration: wingDuration * 0.6,
easing: tween.easeInOut,
repeat: -1,
yoyo: true
});
// Play buzz sound
LK.getSound('buzz').play();
}
// Add slight random movement to insects occasionally
if (LK.ticks % 60 === 0) {
for (var i = 0; i < insects.length; i++) {
var insect = insects[i];
// Change velocity slightly
insect.vx += (Math.random() - 0.5) * 2;
insect.vy += (Math.random() - 0.5) * 2;
// Limit max speed
var speed = Math.sqrt(insect.vx * insect.vx + insect.vy * insect.vy);
if (speed > insect.speed) {
insect.vx = insect.vx / speed * insect.speed;
insect.vy = insect.vy / speed * insect.speed;
}
}
}
};