/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Fly = Container.expand(function () {
var self = Container.call(this);
// Choose assets based on current level - only bugs for level 3+
var flyAsset;
if (currentLevel >= 3) {
// Level 3 and above: only spawn bugs
flyAsset = Math.random() < 0.5 ? 'bug1' : 'bug2';
} else {
// Levels 1-2: only spawn flies
flyAsset = Math.random() < 0.5 ? 'fly1' : 'fly2';
}
var flyGraphics = self.attachAsset(flyAsset, {
anchorX: 0.5,
anchorY: 0.5
});
// Play sound based on fly type when spawned
if (flyAsset === 'fly1' && currentLevel < 3) {
LK.getSound('buzz').play();
} else if (flyAsset === 'fly2' && currentLevel < 3) {
LK.getSound('miss').play();
} else if (flyAsset === 'bug1') {
LK.getSound('bug1').play();
} else if (flyAsset === 'bug2') {
LK.getSound('bug2').play();
}
self.speed = 2 + Math.random() * 3;
// Initialize direction based on character type
if (flyAsset === 'bug1' || flyAsset === 'bug2') {
// Bugs prefer linear horizontal movement
self.directionX = Math.random() < 0.5 ? -1 : 1; // Strong left or right preference
self.directionY = (Math.random() - 0.5) * 0.4; // Minimal vertical component
} else {
// Flies have random movement (original behavior)
self.directionX = (Math.random() - 0.5) * 2;
self.directionY = (Math.random() - 0.5) * 2;
}
self.timeAlive = 0;
self.maxLifetime = 2000 + Math.random() * 3000; // 2-5 seconds max
self.buzzTimer = 0;
self.isSwatted = false;
// Normalize direction
var length = Math.sqrt(self.directionX * self.directionX + self.directionY * self.directionY);
if (length > 0) {
self.directionX /= length;
self.directionY /= length;
}
self.update = function () {
if (self.isSwatted) {
return;
}
self.timeAlive += 16.67; // ~60fps
// Different movement patterns for bugs vs flies
if (flyAsset === 'bug1' || flyAsset === 'bug2') {
// Level 3: Constant horizontal speed with random vertical zigzag
if (currentLevel >= 3) {
// Maintain constant horizontal direction
// Create random vertical zigzag pattern
if (!self.zigzagTimer) {
self.zigzagTimer = 0;
self.nextZigzagTime = 500 + Math.random() * 1000; // Random interval between 0.5-1.5 seconds
}
self.zigzagTimer += 16.67;
if (self.zigzagTimer >= self.nextZigzagTime) {
// Start new zigzag movement
var targetY = self.y + (Math.random() - 0.5) * 400; // Random vertical target within 400px range
targetY = Math.max(50, Math.min(2682, targetY)); // Keep within bounds
tween(self, {
y: targetY
}, {
duration: 300 + Math.random() * 700,
// Random duration 0.3-1 second
easing: tween.easeInOut
});
self.zigzagTimer = 0;
self.nextZigzagTime = 500 + Math.random() * 1000;
}
// Only move horizontally with constant speed
self.x += self.directionX * self.speed * 1.9 * 1.9; // Level 3 speed multiplier increased by 1.9x
} else {
// Bug movement for levels 1-2: prefer linear motion with rare vertical adjustments
if (Math.random() < 0.02) {
// Very rare direction changes
// Prefer horizontal movement (70% chance for horizontal, 30% for vertical)
if (Math.random() < 0.7) {
// Horizontal movement adjustment
self.directionX = (Math.random() - 0.5) * 2;
self.directionY *= 0.3; // Reduce vertical component
} else {
// Rare vertical adjustment
self.directionY += (Math.random() - 0.5) * 0.5;
}
// Normalize direction to prevent bugs from moving too fast
var length = Math.sqrt(self.directionX * self.directionX + self.directionY * self.directionY);
if (length > 1) {
self.directionX /= length;
self.directionY /= length;
}
}
}
} else {
// Fly movement: more frequent and erratic (original behavior)
if (Math.random() < 0.05) {
self.directionX += (Math.random() - 0.5) * 0.8;
self.directionY += (Math.random() - 0.5) * 0.8;
// Normalize direction to prevent flies from moving too fast
var length = Math.sqrt(self.directionX * self.directionX + self.directionY * self.directionY);
if (length > 1) {
self.directionX /= length;
self.directionY /= length;
}
}
// Add random sudden direction changes for more realistic fly movement
if (Math.random() < 0.01) {
self.directionX = (Math.random() - 0.5) * 2;
self.directionY = (Math.random() - 0.5) * 2;
}
}
// Add speed variation for more random movement
var speedMultiplier = 0.7 + Math.random() * 0.6; // Random speed between 70% and 130%
// Apply speed boosts based on level and fly type
var finalSpeed = self.speed;
if (currentLevel >= 3 && (flyAsset === 'bug1' || flyAsset === 'bug2')) {
finalSpeed *= 1.9 * 1.9; // Additional 1.9x speed increase for level 3 bugs
} else if (currentLevel === 2 && (flyAsset === 'fly1' || flyAsset === 'fly2')) {
finalSpeed *= 1.7; // 1.7x speed increase for level 2 flies
}
// Move fly with level speed multiplier (skip for level 3 bugs as they use zigzag pattern)
if (!(currentLevel >= 3 && (flyAsset === 'bug1' || flyAsset === 'bug2'))) {
self.x += self.directionX * finalSpeed * speedMultiplier * speedMultiplier;
self.y += self.directionY * finalSpeed * speedMultiplier * speedMultiplier;
}
// Bounce off walls
if (self.x < 50 || self.x > 1998) {
self.directionX *= -1;
self.x = Math.max(50, Math.min(1998, self.x));
}
// For level 3 bugs, don't bounce vertically as they use zigzag pattern
if (!(currentLevel >= 3 && (flyAsset === 'bug1' || flyAsset === 'bug2'))) {
if (self.y < 50 || self.y > 2682) {
self.directionY *= -1;
self.y = Math.max(50, Math.min(2682, self.y));
}
}
// Buzzing sound effect
self.buzzTimer += 16.67;
if (self.buzzTimer > 1000 + Math.random() * 2000 && currentLevel < 3) {
LK.getSound('buzz').play();
self.buzzTimer = 0;
}
// Flies now move in straight lines without rotation
// Check if lifetime expired
if (self.timeAlive > self.maxLifetime) {
self.escape();
}
};
self.escape = function () {
if (!self.isSwatted) {
missedFlies++;
if (currentLevel < 3) {
LK.getSound('miss').play();
}
}
self.destroy();
for (var i = flies.length - 1; i >= 0; i--) {
if (flies[i] === self) {
flies.splice(i, 1);
break;
}
}
};
self.swat = function () {
if (self.isSwatted) {
return;
}
self.isSwatted = true;
// Update kill counters based on fly asset type
if (flyAsset === 'fly1') {
fly1Kills++;
} else if (flyAsset === 'fly2') {
fly2Kills++;
} else if (flyAsset === 'bug1') {
bug1Kills++;
} else if (flyAsset === 'bug2') {
bug2Kills++;
}
LK.setScore(LK.getScore() + 10);
scoreTxt.setText(LK.getScore());
// Show crush effect at fly position - use bugCrush for bugs, crush for flies
var crushAsset = flyAsset === 'bug1' || flyAsset === 'bug2' ? 'bugCrush' : 'crush';
var crushEffect = LK.getAsset(crushAsset, {
anchorX: 0.5,
anchorY: 0.5,
x: self.x,
y: self.y
});
game.addChild(crushEffect);
// Remove crush effect after 0.2 seconds
LK.setTimeout(function () {
crushEffect.destroy();
}, 200);
// Visual feedback
tween(flyGraphics, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 200,
onFinish: function onFinish() {
self.destroy();
for (var i = flies.length - 1; i >= 0; i--) {
if (flies[i] === self) {
flies.splice(i, 1);
break;
}
}
}
});
};
self.down = function (x, y, obj) {
// Flies no longer handle their own swatting - this is now handled by the swatter
};
return self;
});
var Swatter = Container.expand(function () {
var self = Container.call(this);
// Create swatter using handle1 image
var swatterGraphics = self.attachAsset('handle1', {
anchorX: 0.5,
anchorY: 0.5
});
// Swatting animation
self.swat = function () {
// Quick scale animation for swatting effect
tween(swatterGraphics, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 100,
onFinish: function onFinish() {
tween(swatterGraphics, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xf0f8ff
});
/****
* Game Code
****/
function showBackgroundForLevel(level) {
// Remove existing backgrounds first
for (var i = game.children.length - 1; i >= 0; i--) {
var child = game.children[i];
// Check if this child is a background by checking for background asset names
if (child.assetId === 'level1BG' || child.assetId === 'level2BG' || child.assetId === 'level3BG') {
child.destroy();
}
}
// Add new background based on level
var bgAssetKey = '';
if (level === 1) {
bgAssetKey = 'level1BG';
} else if (level === 2) {
bgAssetKey = 'level2BG';
} else if (level === 3) {
bgAssetKey = 'level3BG';
}
if (bgAssetKey) {
var background = LK.getAsset(bgAssetKey, {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
// Store asset ID for future reference
background.assetId = bgAssetKey;
// Add background at index 0 so it appears behind other objects
game.addChildAt(background, 0);
}
}
var flies = [];
var spawnTimer = 0;
var spawnInterval = 2000; // Start with 2 seconds between spawns
var missedFlies = 0;
var maxMissedFlies = 10;
var gameDifficulty = 1;
var currentLevel = 1;
var levelTarget = 250; // Points needed to complete level 1
var speedMultiplier = 1; // Speed multiplier for current level
// Kill count tracking for each character type
var fly1Kills = 0;
var fly2Kills = 0;
var bug1Kills = 0;
var bug2Kills = 0;
// Score display
var scoreTxt = new Text2('0', {
size: 120,
fill: 0x333333
});
scoreTxt.setText(LK.getScore());
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Missed flies counter
var missedTxt = new Text2('Missed: 0/' + maxMissedFlies, {
size: 80,
fill: 0xCC0000
});
missedTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(missedTxt);
// Level display
var levelTxt = new Text2('Level: 1', {
size: 80,
fill: 0x333333
});
levelTxt.anchor.set(0, 0);
LK.gui.topLeft.addChild(levelTxt);
function spawnFly() {
var fly = new Fly();
var attempts = 0;
var maxAttempts = 50;
var validPosition = false;
var newX, newY;
while (!validPosition && attempts < maxAttempts) {
// Generate random position within screen bounds (with margin)
if (currentLevel >= 3) {
// Level 3+: bugs spawn in right AND bottom half of screen (intersection)
// Right half: x from center (1024) to right edge
// Bottom half: y from center (1366) to bottom edge
newX = 1024 + Math.random() * (2048 - 1024 - 100);
newY = 1366 + Math.random() * (2732 - 1366 - 100);
} else {
// Levels 1-2: flies can spawn anywhere
newX = 100 + Math.random() * (2048 - 200);
newY = 100 + Math.random() * (2732 - 200);
}
validPosition = true;
attempts++;
// Check distance from all existing flies
for (var i = 0; i < flies.length; i++) {
var existingFly = flies[i];
var distance = Math.sqrt((newX - existingFly.x) * (newX - existingFly.x) + (newY - existingFly.y) * (newY - existingFly.y));
if (distance < 350) {
validPosition = false;
break;
}
}
}
// If we couldn't find a valid position after max attempts, use the last generated position
fly.x = newX;
fly.y = newY;
flies.push(fly);
game.addChild(fly);
}
function increaseDifficulty() {
gameDifficulty += 0.1;
spawnInterval = Math.max(800, 2000 / gameDifficulty); // Minimum 0.8 seconds
// Increase fly speed for new flies
for (var i = 0; i < flies.length; i++) {
flies[i].speed = Math.min(flies[i].speed * 1.05, 8);
}
}
var levelCompleteShown = false;
var gamePaused = false;
function createConfettiEffect() {
// Create multiple confetti particles
for (var i = 0; i < 30; i++) {
var confetti = LK.getAsset('crush', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024 + (Math.random() - 0.5) * 400,
y: 1366 + (Math.random() - 0.5) * 200,
scaleX: 0.5 + Math.random() * 0.5,
scaleY: 0.5 + Math.random() * 0.5,
rotation: Math.random() * Math.PI * 2
});
game.addChild(confetti);
// Animate confetti falling and fading
tween(confetti, {
x: confetti.x + (Math.random() - 0.5) * 600,
y: confetti.y + 800 + Math.random() * 400,
rotation: confetti.rotation + Math.PI * 4,
alpha: 0
}, {
duration: 2000 + Math.random() * 1000,
onFinish: function onFinish() {
confetti.destroy();
}
});
}
}
function showLevelComplete() {
if (levelCompleteShown) {
return;
}
levelCompleteShown = true;
// Pause background music and play level complete sound
LK.stopMusic();
LK.getSound('levelCompleteSound').play();
// Pause the game
gamePaused = true;
// Hide the swatter
swatter.visible = false;
// Add confetti effect
createConfettiEffect();
// Create level complete overlay
var overlay = new Container();
overlay.x = 0;
overlay.y = 0;
game.addChild(overlay);
// Create background using levelCompleteBg image
var bg = LK.getAsset('levelCompleteBg', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
overlay.addChild(bg);
// Create next level button with frame
var buttonContainer = new Container();
buttonContainer.x = 1024;
buttonContainer.y = 2150;
overlay.addChild(buttonContainer);
// Create button using nextLevelBtn image
var buttonFrame = LK.getAsset('nextLevelBtn', {
anchorX: 0.5,
anchorY: 0.5
});
buttonContainer.addChild(buttonFrame);
// Handle next level button click
overlay.down = function (x, y, obj) {
// Check if click is on next level button area (nextLevelBtn dimensions: 1240x220)
if (x > 404 && x < 1644 && y > 2040 && y < 2260) {
// Button press animation
tween(buttonContainer, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100,
onFinish: function onFinish() {
tween(buttonContainer, {
scaleX: 1,
scaleY: 1
}, {
duration: 100,
onFinish: function onFinish() {
overlay.destroy();
levelCompleteShown = false;
currentLevel++;
if (currentLevel === 2) {
levelTarget = 575; // Level 2 target is 575 points
} else if (currentLevel === 3) {
levelTarget = 1325; // Level 3 target is 1325 points
}
levelTxt.setText('Level: ' + currentLevel);
// Update background for new level
showBackgroundForLevel(currentLevel);
// Resume background music and the game, show swatter again
// Play appropriate music based on level
if (currentLevel === 3) {
LK.playMusic('forestSound');
} else if (currentLevel === 2) {
LK.playMusic('level2Sound');
} else {
LK.playMusic('bgMusic');
}
gamePaused = false;
swatter.visible = true;
}
});
}
});
}
};
}
game.update = function () {
// Don't update game logic when paused
if (gamePaused) {
return;
}
// Update missed flies display
missedTxt.setText('Missed: ' + missedFlies + '/' + maxMissedFlies);
// Check level progression
if (LK.getScore() >= levelTarget && !levelCompleteShown) {
if (currentLevel === 1) {
// Increase speed by 1.7x when reaching 250 points
speedMultiplier *= 1.7;
// Show level complete for level 1
showLevelComplete();
} else if (currentLevel === 2) {
// Increase speed by 1.9x when reaching 575 points
speedMultiplier *= 1.9;
// Show level complete for level 2
showLevelComplete();
} else {
// Play win sound (keep background music playing)
LK.getSound('winSound').play();
// Create kill count display container before showing you win
var killCountContainer = new Container();
killCountContainer.x = 1024;
killCountContainer.y = 1366;
game.addChild(killCountContainer);
// Display fly1 kills
var fly1Image = LK.getAsset('fly1', {
anchorX: 0.5,
anchorY: 0.5,
x: -300,
y: -150
});
killCountContainer.addChild(fly1Image);
var fly1Text = new Text2('X ' + fly1Kills, {
size: 120,
fill: 0x333333
});
fly1Text.anchor.set(0, 0.5);
fly1Text.x = -200;
fly1Text.y = -150;
killCountContainer.addChild(fly1Text);
// Display fly2 kills
var fly2Image = LK.getAsset('fly2', {
anchorX: 0.5,
anchorY: 0.5,
x: -300,
y: -50
});
killCountContainer.addChild(fly2Image);
var fly2Text = new Text2('X ' + fly2Kills, {
size: 120,
fill: 0x333333
});
fly2Text.anchor.set(0, 0.5);
fly2Text.x = -200;
fly2Text.y = -50;
killCountContainer.addChild(fly2Text);
// Display bug1 kills
var bug1Image = LK.getAsset('bug1', {
anchorX: 0.5,
anchorY: 0.5,
x: -300,
y: 50
});
killCountContainer.addChild(bug1Image);
var bug1Text = new Text2('X ' + bug1Kills, {
size: 120,
fill: 0x333333
});
bug1Text.anchor.set(0, 0.5);
bug1Text.x = -200;
bug1Text.y = 50;
killCountContainer.addChild(bug1Text);
// Display bug2 kills
var bug2Image = LK.getAsset('bug2', {
anchorX: 0.5,
anchorY: 0.5,
x: -300,
y: 150
});
killCountContainer.addChild(bug2Image);
var bug2Text = new Text2('X ' + bug2Kills, {
size: 120,
fill: 0x333333
});
bug2Text.anchor.set(0, 0.5);
bug2Text.x = -200;
bug2Text.y = 150;
killCountContainer.addChild(bug2Text);
// Show kill counts for 5 seconds before you win
LK.setTimeout(function () {
killCountContainer.destroy();
LK.showYouWin();
}, 5000);
}
}
// Check game over condition
if (missedFlies >= maxMissedFlies) {
// Destroy all existing flies when missed count reaches 10/10
for (var i = flies.length - 1; i >= 0; i--) {
flies[i].destroy();
}
flies = []; // Clear the flies array
// Create kill count display container before showing game over
var killCountContainer = new Container();
killCountContainer.x = 1024;
killCountContainer.y = 1366;
game.addChild(killCountContainer);
// Display fly1 kills
var fly1Image = LK.getAsset('fly1', {
anchorX: 0.5,
anchorY: 0.5,
x: -300,
y: -150
});
killCountContainer.addChild(fly1Image);
var fly1Text = new Text2('X ' + fly1Kills, {
size: 120,
fill: 0x333333
});
fly1Text.anchor.set(0, 0.5);
fly1Text.x = -200;
fly1Text.y = -150;
killCountContainer.addChild(fly1Text);
// Display fly2 kills
var fly2Image = LK.getAsset('fly2', {
anchorX: 0.5,
anchorY: 0.5,
x: -300,
y: -50
});
killCountContainer.addChild(fly2Image);
var fly2Text = new Text2('X ' + fly2Kills, {
size: 120,
fill: 0x333333
});
fly2Text.anchor.set(0, 0.5);
fly2Text.x = -200;
fly2Text.y = -50;
killCountContainer.addChild(fly2Text);
// Display bug1 kills
var bug1Image = LK.getAsset('bug1', {
anchorX: 0.5,
anchorY: 0.5,
x: -300,
y: 50
});
killCountContainer.addChild(bug1Image);
var bug1Text = new Text2('X ' + bug1Kills, {
size: 120,
fill: 0x333333
});
bug1Text.anchor.set(0, 0.5);
bug1Text.x = -200;
bug1Text.y = 50;
killCountContainer.addChild(bug1Text);
// Display bug2 kills
var bug2Image = LK.getAsset('bug2', {
anchorX: 0.5,
anchorY: 0.5,
x: -300,
y: 150
});
killCountContainer.addChild(bug2Image);
var bug2Text = new Text2('X ' + bug2Kills, {
size: 120,
fill: 0x333333
});
bug2Text.anchor.set(0, 0.5);
bug2Text.x = -200;
bug2Text.y = 150;
killCountContainer.addChild(bug2Text);
// Show kill counts for 5 seconds before game over
LK.setTimeout(function () {
killCountContainer.destroy();
LK.showGameOver();
}, 5000);
return;
}
// Spawn new flies
spawnTimer += 16.67;
// Level 3: Increase bug spawn rate by 1.4x (reduce interval by 1.4)
var effectiveSpawnInterval = spawnInterval;
if (currentLevel >= 3) {
effectiveSpawnInterval = spawnInterval / 1.4;
}
if (spawnTimer >= effectiveSpawnInterval) {
spawnFly();
spawnTimer = 0;
}
// Increase difficulty every 10 seconds
if (LK.ticks % 600 === 0) {
increaseDifficulty();
}
// Limit number of flies on screen
if (flies.length > 15) {
var oldestFly = flies[0];
oldestFly.escape();
}
};
// Create swatter that follows mouse
var swatter = new Swatter();
game.addChild(swatter);
// Mouse move handler to move swatter
game.move = function (x, y, obj) {
swatter.x = x;
swatter.y = y;
};
// Mouse down handler for swatting
game.down = function (x, y, obj) {
LK.getSound('hit1').play();
swatter.swat();
// Check if we hit any flies with 30% reduced hit radius from handle1 width
var hitRadius = 150 * 0.7; // 30% reduction from handle1 width
for (var i = flies.length - 1; i >= 0; i--) {
var fly = flies[i];
var distance = Math.sqrt((fly.x - x) * (fly.x - x) + (fly.y - y) * (fly.y - y));
if (distance <= hitRadius) {
fly.swat();
LK.getSound('swat').play();
break;
}
}
};
// Start game directly with level 1
showBackgroundForLevel(currentLevel);
LK.playMusic('bgMusic');
spawnFly(); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Fly = Container.expand(function () {
var self = Container.call(this);
// Choose assets based on current level - only bugs for level 3+
var flyAsset;
if (currentLevel >= 3) {
// Level 3 and above: only spawn bugs
flyAsset = Math.random() < 0.5 ? 'bug1' : 'bug2';
} else {
// Levels 1-2: only spawn flies
flyAsset = Math.random() < 0.5 ? 'fly1' : 'fly2';
}
var flyGraphics = self.attachAsset(flyAsset, {
anchorX: 0.5,
anchorY: 0.5
});
// Play sound based on fly type when spawned
if (flyAsset === 'fly1' && currentLevel < 3) {
LK.getSound('buzz').play();
} else if (flyAsset === 'fly2' && currentLevel < 3) {
LK.getSound('miss').play();
} else if (flyAsset === 'bug1') {
LK.getSound('bug1').play();
} else if (flyAsset === 'bug2') {
LK.getSound('bug2').play();
}
self.speed = 2 + Math.random() * 3;
// Initialize direction based on character type
if (flyAsset === 'bug1' || flyAsset === 'bug2') {
// Bugs prefer linear horizontal movement
self.directionX = Math.random() < 0.5 ? -1 : 1; // Strong left or right preference
self.directionY = (Math.random() - 0.5) * 0.4; // Minimal vertical component
} else {
// Flies have random movement (original behavior)
self.directionX = (Math.random() - 0.5) * 2;
self.directionY = (Math.random() - 0.5) * 2;
}
self.timeAlive = 0;
self.maxLifetime = 2000 + Math.random() * 3000; // 2-5 seconds max
self.buzzTimer = 0;
self.isSwatted = false;
// Normalize direction
var length = Math.sqrt(self.directionX * self.directionX + self.directionY * self.directionY);
if (length > 0) {
self.directionX /= length;
self.directionY /= length;
}
self.update = function () {
if (self.isSwatted) {
return;
}
self.timeAlive += 16.67; // ~60fps
// Different movement patterns for bugs vs flies
if (flyAsset === 'bug1' || flyAsset === 'bug2') {
// Level 3: Constant horizontal speed with random vertical zigzag
if (currentLevel >= 3) {
// Maintain constant horizontal direction
// Create random vertical zigzag pattern
if (!self.zigzagTimer) {
self.zigzagTimer = 0;
self.nextZigzagTime = 500 + Math.random() * 1000; // Random interval between 0.5-1.5 seconds
}
self.zigzagTimer += 16.67;
if (self.zigzagTimer >= self.nextZigzagTime) {
// Start new zigzag movement
var targetY = self.y + (Math.random() - 0.5) * 400; // Random vertical target within 400px range
targetY = Math.max(50, Math.min(2682, targetY)); // Keep within bounds
tween(self, {
y: targetY
}, {
duration: 300 + Math.random() * 700,
// Random duration 0.3-1 second
easing: tween.easeInOut
});
self.zigzagTimer = 0;
self.nextZigzagTime = 500 + Math.random() * 1000;
}
// Only move horizontally with constant speed
self.x += self.directionX * self.speed * 1.9 * 1.9; // Level 3 speed multiplier increased by 1.9x
} else {
// Bug movement for levels 1-2: prefer linear motion with rare vertical adjustments
if (Math.random() < 0.02) {
// Very rare direction changes
// Prefer horizontal movement (70% chance for horizontal, 30% for vertical)
if (Math.random() < 0.7) {
// Horizontal movement adjustment
self.directionX = (Math.random() - 0.5) * 2;
self.directionY *= 0.3; // Reduce vertical component
} else {
// Rare vertical adjustment
self.directionY += (Math.random() - 0.5) * 0.5;
}
// Normalize direction to prevent bugs from moving too fast
var length = Math.sqrt(self.directionX * self.directionX + self.directionY * self.directionY);
if (length > 1) {
self.directionX /= length;
self.directionY /= length;
}
}
}
} else {
// Fly movement: more frequent and erratic (original behavior)
if (Math.random() < 0.05) {
self.directionX += (Math.random() - 0.5) * 0.8;
self.directionY += (Math.random() - 0.5) * 0.8;
// Normalize direction to prevent flies from moving too fast
var length = Math.sqrt(self.directionX * self.directionX + self.directionY * self.directionY);
if (length > 1) {
self.directionX /= length;
self.directionY /= length;
}
}
// Add random sudden direction changes for more realistic fly movement
if (Math.random() < 0.01) {
self.directionX = (Math.random() - 0.5) * 2;
self.directionY = (Math.random() - 0.5) * 2;
}
}
// Add speed variation for more random movement
var speedMultiplier = 0.7 + Math.random() * 0.6; // Random speed between 70% and 130%
// Apply speed boosts based on level and fly type
var finalSpeed = self.speed;
if (currentLevel >= 3 && (flyAsset === 'bug1' || flyAsset === 'bug2')) {
finalSpeed *= 1.9 * 1.9; // Additional 1.9x speed increase for level 3 bugs
} else if (currentLevel === 2 && (flyAsset === 'fly1' || flyAsset === 'fly2')) {
finalSpeed *= 1.7; // 1.7x speed increase for level 2 flies
}
// Move fly with level speed multiplier (skip for level 3 bugs as they use zigzag pattern)
if (!(currentLevel >= 3 && (flyAsset === 'bug1' || flyAsset === 'bug2'))) {
self.x += self.directionX * finalSpeed * speedMultiplier * speedMultiplier;
self.y += self.directionY * finalSpeed * speedMultiplier * speedMultiplier;
}
// Bounce off walls
if (self.x < 50 || self.x > 1998) {
self.directionX *= -1;
self.x = Math.max(50, Math.min(1998, self.x));
}
// For level 3 bugs, don't bounce vertically as they use zigzag pattern
if (!(currentLevel >= 3 && (flyAsset === 'bug1' || flyAsset === 'bug2'))) {
if (self.y < 50 || self.y > 2682) {
self.directionY *= -1;
self.y = Math.max(50, Math.min(2682, self.y));
}
}
// Buzzing sound effect
self.buzzTimer += 16.67;
if (self.buzzTimer > 1000 + Math.random() * 2000 && currentLevel < 3) {
LK.getSound('buzz').play();
self.buzzTimer = 0;
}
// Flies now move in straight lines without rotation
// Check if lifetime expired
if (self.timeAlive > self.maxLifetime) {
self.escape();
}
};
self.escape = function () {
if (!self.isSwatted) {
missedFlies++;
if (currentLevel < 3) {
LK.getSound('miss').play();
}
}
self.destroy();
for (var i = flies.length - 1; i >= 0; i--) {
if (flies[i] === self) {
flies.splice(i, 1);
break;
}
}
};
self.swat = function () {
if (self.isSwatted) {
return;
}
self.isSwatted = true;
// Update kill counters based on fly asset type
if (flyAsset === 'fly1') {
fly1Kills++;
} else if (flyAsset === 'fly2') {
fly2Kills++;
} else if (flyAsset === 'bug1') {
bug1Kills++;
} else if (flyAsset === 'bug2') {
bug2Kills++;
}
LK.setScore(LK.getScore() + 10);
scoreTxt.setText(LK.getScore());
// Show crush effect at fly position - use bugCrush for bugs, crush for flies
var crushAsset = flyAsset === 'bug1' || flyAsset === 'bug2' ? 'bugCrush' : 'crush';
var crushEffect = LK.getAsset(crushAsset, {
anchorX: 0.5,
anchorY: 0.5,
x: self.x,
y: self.y
});
game.addChild(crushEffect);
// Remove crush effect after 0.2 seconds
LK.setTimeout(function () {
crushEffect.destroy();
}, 200);
// Visual feedback
tween(flyGraphics, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 200,
onFinish: function onFinish() {
self.destroy();
for (var i = flies.length - 1; i >= 0; i--) {
if (flies[i] === self) {
flies.splice(i, 1);
break;
}
}
}
});
};
self.down = function (x, y, obj) {
// Flies no longer handle their own swatting - this is now handled by the swatter
};
return self;
});
var Swatter = Container.expand(function () {
var self = Container.call(this);
// Create swatter using handle1 image
var swatterGraphics = self.attachAsset('handle1', {
anchorX: 0.5,
anchorY: 0.5
});
// Swatting animation
self.swat = function () {
// Quick scale animation for swatting effect
tween(swatterGraphics, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 100,
onFinish: function onFinish() {
tween(swatterGraphics, {
scaleX: 1,
scaleY: 1
}, {
duration: 100
});
}
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0xf0f8ff
});
/****
* Game Code
****/
function showBackgroundForLevel(level) {
// Remove existing backgrounds first
for (var i = game.children.length - 1; i >= 0; i--) {
var child = game.children[i];
// Check if this child is a background by checking for background asset names
if (child.assetId === 'level1BG' || child.assetId === 'level2BG' || child.assetId === 'level3BG') {
child.destroy();
}
}
// Add new background based on level
var bgAssetKey = '';
if (level === 1) {
bgAssetKey = 'level1BG';
} else if (level === 2) {
bgAssetKey = 'level2BG';
} else if (level === 3) {
bgAssetKey = 'level3BG';
}
if (bgAssetKey) {
var background = LK.getAsset(bgAssetKey, {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
// Store asset ID for future reference
background.assetId = bgAssetKey;
// Add background at index 0 so it appears behind other objects
game.addChildAt(background, 0);
}
}
var flies = [];
var spawnTimer = 0;
var spawnInterval = 2000; // Start with 2 seconds between spawns
var missedFlies = 0;
var maxMissedFlies = 10;
var gameDifficulty = 1;
var currentLevel = 1;
var levelTarget = 250; // Points needed to complete level 1
var speedMultiplier = 1; // Speed multiplier for current level
// Kill count tracking for each character type
var fly1Kills = 0;
var fly2Kills = 0;
var bug1Kills = 0;
var bug2Kills = 0;
// Score display
var scoreTxt = new Text2('0', {
size: 120,
fill: 0x333333
});
scoreTxt.setText(LK.getScore());
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Missed flies counter
var missedTxt = new Text2('Missed: 0/' + maxMissedFlies, {
size: 80,
fill: 0xCC0000
});
missedTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(missedTxt);
// Level display
var levelTxt = new Text2('Level: 1', {
size: 80,
fill: 0x333333
});
levelTxt.anchor.set(0, 0);
LK.gui.topLeft.addChild(levelTxt);
function spawnFly() {
var fly = new Fly();
var attempts = 0;
var maxAttempts = 50;
var validPosition = false;
var newX, newY;
while (!validPosition && attempts < maxAttempts) {
// Generate random position within screen bounds (with margin)
if (currentLevel >= 3) {
// Level 3+: bugs spawn in right AND bottom half of screen (intersection)
// Right half: x from center (1024) to right edge
// Bottom half: y from center (1366) to bottom edge
newX = 1024 + Math.random() * (2048 - 1024 - 100);
newY = 1366 + Math.random() * (2732 - 1366 - 100);
} else {
// Levels 1-2: flies can spawn anywhere
newX = 100 + Math.random() * (2048 - 200);
newY = 100 + Math.random() * (2732 - 200);
}
validPosition = true;
attempts++;
// Check distance from all existing flies
for (var i = 0; i < flies.length; i++) {
var existingFly = flies[i];
var distance = Math.sqrt((newX - existingFly.x) * (newX - existingFly.x) + (newY - existingFly.y) * (newY - existingFly.y));
if (distance < 350) {
validPosition = false;
break;
}
}
}
// If we couldn't find a valid position after max attempts, use the last generated position
fly.x = newX;
fly.y = newY;
flies.push(fly);
game.addChild(fly);
}
function increaseDifficulty() {
gameDifficulty += 0.1;
spawnInterval = Math.max(800, 2000 / gameDifficulty); // Minimum 0.8 seconds
// Increase fly speed for new flies
for (var i = 0; i < flies.length; i++) {
flies[i].speed = Math.min(flies[i].speed * 1.05, 8);
}
}
var levelCompleteShown = false;
var gamePaused = false;
function createConfettiEffect() {
// Create multiple confetti particles
for (var i = 0; i < 30; i++) {
var confetti = LK.getAsset('crush', {
anchorX: 0.5,
anchorY: 0.5,
x: 1024 + (Math.random() - 0.5) * 400,
y: 1366 + (Math.random() - 0.5) * 200,
scaleX: 0.5 + Math.random() * 0.5,
scaleY: 0.5 + Math.random() * 0.5,
rotation: Math.random() * Math.PI * 2
});
game.addChild(confetti);
// Animate confetti falling and fading
tween(confetti, {
x: confetti.x + (Math.random() - 0.5) * 600,
y: confetti.y + 800 + Math.random() * 400,
rotation: confetti.rotation + Math.PI * 4,
alpha: 0
}, {
duration: 2000 + Math.random() * 1000,
onFinish: function onFinish() {
confetti.destroy();
}
});
}
}
function showLevelComplete() {
if (levelCompleteShown) {
return;
}
levelCompleteShown = true;
// Pause background music and play level complete sound
LK.stopMusic();
LK.getSound('levelCompleteSound').play();
// Pause the game
gamePaused = true;
// Hide the swatter
swatter.visible = false;
// Add confetti effect
createConfettiEffect();
// Create level complete overlay
var overlay = new Container();
overlay.x = 0;
overlay.y = 0;
game.addChild(overlay);
// Create background using levelCompleteBg image
var bg = LK.getAsset('levelCompleteBg', {
anchorX: 0,
anchorY: 0,
x: 0,
y: 0
});
overlay.addChild(bg);
// Create next level button with frame
var buttonContainer = new Container();
buttonContainer.x = 1024;
buttonContainer.y = 2150;
overlay.addChild(buttonContainer);
// Create button using nextLevelBtn image
var buttonFrame = LK.getAsset('nextLevelBtn', {
anchorX: 0.5,
anchorY: 0.5
});
buttonContainer.addChild(buttonFrame);
// Handle next level button click
overlay.down = function (x, y, obj) {
// Check if click is on next level button area (nextLevelBtn dimensions: 1240x220)
if (x > 404 && x < 1644 && y > 2040 && y < 2260) {
// Button press animation
tween(buttonContainer, {
scaleX: 0.95,
scaleY: 0.95
}, {
duration: 100,
onFinish: function onFinish() {
tween(buttonContainer, {
scaleX: 1,
scaleY: 1
}, {
duration: 100,
onFinish: function onFinish() {
overlay.destroy();
levelCompleteShown = false;
currentLevel++;
if (currentLevel === 2) {
levelTarget = 575; // Level 2 target is 575 points
} else if (currentLevel === 3) {
levelTarget = 1325; // Level 3 target is 1325 points
}
levelTxt.setText('Level: ' + currentLevel);
// Update background for new level
showBackgroundForLevel(currentLevel);
// Resume background music and the game, show swatter again
// Play appropriate music based on level
if (currentLevel === 3) {
LK.playMusic('forestSound');
} else if (currentLevel === 2) {
LK.playMusic('level2Sound');
} else {
LK.playMusic('bgMusic');
}
gamePaused = false;
swatter.visible = true;
}
});
}
});
}
};
}
game.update = function () {
// Don't update game logic when paused
if (gamePaused) {
return;
}
// Update missed flies display
missedTxt.setText('Missed: ' + missedFlies + '/' + maxMissedFlies);
// Check level progression
if (LK.getScore() >= levelTarget && !levelCompleteShown) {
if (currentLevel === 1) {
// Increase speed by 1.7x when reaching 250 points
speedMultiplier *= 1.7;
// Show level complete for level 1
showLevelComplete();
} else if (currentLevel === 2) {
// Increase speed by 1.9x when reaching 575 points
speedMultiplier *= 1.9;
// Show level complete for level 2
showLevelComplete();
} else {
// Play win sound (keep background music playing)
LK.getSound('winSound').play();
// Create kill count display container before showing you win
var killCountContainer = new Container();
killCountContainer.x = 1024;
killCountContainer.y = 1366;
game.addChild(killCountContainer);
// Display fly1 kills
var fly1Image = LK.getAsset('fly1', {
anchorX: 0.5,
anchorY: 0.5,
x: -300,
y: -150
});
killCountContainer.addChild(fly1Image);
var fly1Text = new Text2('X ' + fly1Kills, {
size: 120,
fill: 0x333333
});
fly1Text.anchor.set(0, 0.5);
fly1Text.x = -200;
fly1Text.y = -150;
killCountContainer.addChild(fly1Text);
// Display fly2 kills
var fly2Image = LK.getAsset('fly2', {
anchorX: 0.5,
anchorY: 0.5,
x: -300,
y: -50
});
killCountContainer.addChild(fly2Image);
var fly2Text = new Text2('X ' + fly2Kills, {
size: 120,
fill: 0x333333
});
fly2Text.anchor.set(0, 0.5);
fly2Text.x = -200;
fly2Text.y = -50;
killCountContainer.addChild(fly2Text);
// Display bug1 kills
var bug1Image = LK.getAsset('bug1', {
anchorX: 0.5,
anchorY: 0.5,
x: -300,
y: 50
});
killCountContainer.addChild(bug1Image);
var bug1Text = new Text2('X ' + bug1Kills, {
size: 120,
fill: 0x333333
});
bug1Text.anchor.set(0, 0.5);
bug1Text.x = -200;
bug1Text.y = 50;
killCountContainer.addChild(bug1Text);
// Display bug2 kills
var bug2Image = LK.getAsset('bug2', {
anchorX: 0.5,
anchorY: 0.5,
x: -300,
y: 150
});
killCountContainer.addChild(bug2Image);
var bug2Text = new Text2('X ' + bug2Kills, {
size: 120,
fill: 0x333333
});
bug2Text.anchor.set(0, 0.5);
bug2Text.x = -200;
bug2Text.y = 150;
killCountContainer.addChild(bug2Text);
// Show kill counts for 5 seconds before you win
LK.setTimeout(function () {
killCountContainer.destroy();
LK.showYouWin();
}, 5000);
}
}
// Check game over condition
if (missedFlies >= maxMissedFlies) {
// Destroy all existing flies when missed count reaches 10/10
for (var i = flies.length - 1; i >= 0; i--) {
flies[i].destroy();
}
flies = []; // Clear the flies array
// Create kill count display container before showing game over
var killCountContainer = new Container();
killCountContainer.x = 1024;
killCountContainer.y = 1366;
game.addChild(killCountContainer);
// Display fly1 kills
var fly1Image = LK.getAsset('fly1', {
anchorX: 0.5,
anchorY: 0.5,
x: -300,
y: -150
});
killCountContainer.addChild(fly1Image);
var fly1Text = new Text2('X ' + fly1Kills, {
size: 120,
fill: 0x333333
});
fly1Text.anchor.set(0, 0.5);
fly1Text.x = -200;
fly1Text.y = -150;
killCountContainer.addChild(fly1Text);
// Display fly2 kills
var fly2Image = LK.getAsset('fly2', {
anchorX: 0.5,
anchorY: 0.5,
x: -300,
y: -50
});
killCountContainer.addChild(fly2Image);
var fly2Text = new Text2('X ' + fly2Kills, {
size: 120,
fill: 0x333333
});
fly2Text.anchor.set(0, 0.5);
fly2Text.x = -200;
fly2Text.y = -50;
killCountContainer.addChild(fly2Text);
// Display bug1 kills
var bug1Image = LK.getAsset('bug1', {
anchorX: 0.5,
anchorY: 0.5,
x: -300,
y: 50
});
killCountContainer.addChild(bug1Image);
var bug1Text = new Text2('X ' + bug1Kills, {
size: 120,
fill: 0x333333
});
bug1Text.anchor.set(0, 0.5);
bug1Text.x = -200;
bug1Text.y = 50;
killCountContainer.addChild(bug1Text);
// Display bug2 kills
var bug2Image = LK.getAsset('bug2', {
anchorX: 0.5,
anchorY: 0.5,
x: -300,
y: 150
});
killCountContainer.addChild(bug2Image);
var bug2Text = new Text2('X ' + bug2Kills, {
size: 120,
fill: 0x333333
});
bug2Text.anchor.set(0, 0.5);
bug2Text.x = -200;
bug2Text.y = 150;
killCountContainer.addChild(bug2Text);
// Show kill counts for 5 seconds before game over
LK.setTimeout(function () {
killCountContainer.destroy();
LK.showGameOver();
}, 5000);
return;
}
// Spawn new flies
spawnTimer += 16.67;
// Level 3: Increase bug spawn rate by 1.4x (reduce interval by 1.4)
var effectiveSpawnInterval = spawnInterval;
if (currentLevel >= 3) {
effectiveSpawnInterval = spawnInterval / 1.4;
}
if (spawnTimer >= effectiveSpawnInterval) {
spawnFly();
spawnTimer = 0;
}
// Increase difficulty every 10 seconds
if (LK.ticks % 600 === 0) {
increaseDifficulty();
}
// Limit number of flies on screen
if (flies.length > 15) {
var oldestFly = flies[0];
oldestFly.escape();
}
};
// Create swatter that follows mouse
var swatter = new Swatter();
game.addChild(swatter);
// Mouse move handler to move swatter
game.move = function (x, y, obj) {
swatter.x = x;
swatter.y = y;
};
// Mouse down handler for swatting
game.down = function (x, y, obj) {
LK.getSound('hit1').play();
swatter.swat();
// Check if we hit any flies with 30% reduced hit radius from handle1 width
var hitRadius = 150 * 0.7; // 30% reduction from handle1 width
for (var i = flies.length - 1; i >= 0; i--) {
var fly = flies[i];
var distance = Math.sqrt((fly.x - x) * (fly.x - x) + (fly.y - y) * (fly.y - y));
if (distance <= hitRadius) {
fly.swat();
LK.getSound('swat').play();
break;
}
}
};
// Start game directly with level 1
showBackgroundForLevel(currentLevel);
LK.playMusic('bgMusic');
spawnFly();
2 boyutlu ve renkli bir plastik sineklik
level complete background. In-Game asset. 2d. High contrast. No shadows
crushed fly In-Game asset. 2d. High contrast. No shadows
arkaplan için geniş bir zemin gerçekçi bir salon genellikle pencere kapı koltuk gibi şeyler olsun. In-Game asset. 2d. High contrast. No shadows
arkaplan için gerçekçi bir oda içinde çalışma masası bilgisayar pencere kapı gibi şeyler olsun. yüksek çözünürlüklü ve gerçekçi olması gerekiyor In-Game asset. 2d. High contrast. No shadows
gerçekçi bir orman ambiyansı tam ortasında büyük bir böcek yuvası olan ve yeşil tonlarında. In-Game asset. 2d. High contrast. No shadows
ezilmiş bir böcek. In-Game asset. 2d. High contrast. No shadows
next level button. In-Game asset. 2d. High contrast. No shadows