/**** * Classes ****/ // BigMosquito class: represents a large mosquito var BigMosquito = Container.expand(function () { var self = Container.call(this); // If this is the special big bee (arı), use blue box asset, else use mosquito var mosquitoGfx; if (self.isBigBee) { mosquitoGfx = self.attachAsset('bigbee', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1 }); } else { mosquitoGfx = self.attachAsset('mosquito', { anchorX: 0.5, anchorY: 0.5, scaleX: 2.2, scaleY: 2.2 }); } // Big mosquito speed (slower for regular, faster for big bee) if (self.isBigBee) { self.speed = 8 + Math.random() * 4; // 8-12 px/tick for big bee (arı) } else { self.speed = 4 + Math.random() * 2; // 4-6 px/tick for regular big mosquito } // Direction in radians (random) self.direction = Math.random() * Math.PI * 2; self.changeDirTimer = 40 + Math.floor(Math.random() * 60); self.alive = true; // Big mosquito dies in 1 hit (default) self.update = function () { // If racket exists, home in on racket if (typeof racket !== "undefined" && racket !== null && racket.x !== undefined && racket.y !== undefined) { var dx = racket.x - self.x; var dy = racket.y - self.y; var angleToRacket = Math.atan2(dy, dx); // Smoothly turn toward racket var angleDiff = angleToRacket - self.direction; // Normalize angleDiff to [-PI, PI] while (angleDiff > Math.PI) { angleDiff -= 2 * Math.PI; } while (angleDiff < -Math.PI) { angleDiff += 2 * Math.PI; } // Turn speed: bigger = more aggressive var turnSpeed = 0.07; if (Math.abs(angleDiff) < turnSpeed) { self.direction = angleToRacket; } else { self.direction += turnSpeed * Math.sign(angleDiff); } } self.x += Math.cos(self.direction) * self.speed; self.y += Math.sin(self.direction) * self.speed; var margin = mosquitoGfx.width / 2 + 10; if (self.x < margin) { self.x = margin; self.direction = Math.PI - self.direction + (Math.random() - 0.5) * 0.5; } if (self.x > 2048 - margin) { self.x = 2048 - margin; self.direction = Math.PI - self.direction + (Math.random() - 0.5) * 0.5; } if (self.y < margin + 100) { self.y = margin + 100; self.direction = -self.direction + (Math.random() - 0.5) * 0.5; } if (self.y > 2732 - margin) { self.y = 2732 - margin; self.direction = -self.direction + (Math.random() - 0.5) * 0.5; } self.changeDirTimer--; if (self.changeDirTimer <= 0) { self.direction += (Math.random() - 0.5) * Math.PI / 1.5; self.changeDirTimer = 40 + Math.floor(Math.random() * 60); } }; // When hit, play animation and destroy self.squash = function (_onFinish) { self.alive = false; self.scaleX = 2.5; self.scaleY = 0.7; self.alpha = 0; if (_onFinish) { _onFinish(); } }; return self; }); //var tween = LK.import("@upit/tween.v1"); // Mosquito class: represents a single mosquito var Mosquito = Container.expand(function () { var self = Container.call(this); // Attach mosquito asset (ellipse, small, dark color) var mosquitoGfx = self.attachAsset('mosquito', { anchorX: 0.5, anchorY: 0.5 }); // Mosquito speed (pixels per tick) self.speed = 6 + Math.random() * 4; // 6-10 px/tick // Direction in radians (random) self.direction = Math.random() * Math.PI * 2; // Time until next direction change self.changeDirTimer = 30 + Math.floor(Math.random() * 60); // Mark as alive self.alive = true; // Update method: called every tick self.update = function () { // If racket exists and is close, move away from racket if (typeof racket !== "undefined" && racket !== null && racket.x !== undefined && racket.y !== undefined) { var dx = self.x - racket.x; var dy = self.y - racket.y; var dist = Math.sqrt(dx * dx + dy * dy); var fleeRadius = 400; // px, how close before fleeing if (dist < fleeRadius) { // Move away from racket: set direction away, with some random jitter var angleFromRacket = Math.atan2(dy, dx); // Add a little randomness so they don't all flee in a straight line self.direction = angleFromRacket + (Math.random() - 0.5) * 0.5; // Optional: speed up a bit when fleeing self.x += Math.cos(self.direction) * (self.speed + 2); self.y += Math.sin(self.direction) * (self.speed + 2); } else { self.x += Math.cos(self.direction) * self.speed; self.y += Math.sin(self.direction) * self.speed; } } else { self.x += Math.cos(self.direction) * self.speed; self.y += Math.sin(self.direction) * self.speed; } // Bounce off walls (game area: 0,0 to 2048,2732) var margin = mosquitoGfx.width / 2 + 10; if (self.x < margin) { self.x = margin; self.direction = Math.PI - self.direction + (Math.random() - 0.5) * 0.5; } if (self.x > 2048 - margin) { self.x = 2048 - margin; self.direction = Math.PI - self.direction + (Math.random() - 0.5) * 0.5; } if (self.y < margin + 100) { // leave top 100px for menu self.y = margin + 100; self.direction = -self.direction + (Math.random() - 0.5) * 0.5; } if (self.y > 2732 - margin) { self.y = 2732 - margin; self.direction = -self.direction + (Math.random() - 0.5) * 0.5; } // Change direction randomly self.changeDirTimer--; if (self.changeDirTimer <= 0) { self.direction += (Math.random() - 0.5) * Math.PI / 1.5; self.changeDirTimer = 30 + Math.floor(Math.random() * 60); } }; // When hit, play animation and destroy self.squash = function (_onFinish) { self.alive = false; // Instantly squash and fade out (no tween) self.scaleX = 1.7; self.scaleY = 0.5; self.alpha = 0; if (_onFinish) { _onFinish(); } }; return self; }); // Racket class: represents the player's racket var Racket = Container.expand(function () { var self = Container.call(this); // Attach racket asset (rectangle, bright color) var racketGfx = self.attachAsset('racket', { anchorX: 0.5, anchorY: 0.5 }); // Optionally, add a little shadow for visibility racketGfx.alpha = 0.95; // Racket size for collision self.radius = racketGfx.width * 0.5; // For touch feedback self.flash = function () { // Instantly flash racket (no tween) racketGfx.tint = 0xffff00; LK.setTimeout(function () { racketGfx.tint = 0xffffff; }, 80); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x888888 // Gray background }); /**** * Game Code ****/ // --- Game Variables --- // --- Game Variables --- // --- Asset Initialization --- var mosquitoes = []; var racket = null; var score = 0; var scoreTxt = null; // Player health (3 lives) var playerHealth = 3; var healthTxt = null; // Timer removed: no time limit var maxMosquitoes = 5; // Start value, will increase over time var mosquitoRampTick = 0; // Track ticks for ramping up // Removed mosquitoesEscaped and maxEscaped (kaçan sayısı) as requested var gameActive = true; var dragNode = null; game.bigMosquitoSpawned = false; // Track big mosquito approach timers var bigMosquitoApproachTimers = []; // --- UI Elements --- // Skor text scoreTxt = new Text2('0', { size: 120, fill: "#222" }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); // Health text (hearts) healthTxt = new Text2('❤❤❤', { size: 100, fill: "#c00" }); // Anchor to center-top, so it aligns with score healthTxt.anchor.set(0.5, 0); // Position health exactly centered below score healthTxt.x = LK.gui.top.width / 2; healthTxt.y = scoreTxt.height + 10; LK.gui.top.addChild(healthTxt); function updateHealthUI() { var hearts = ""; for (var i = 0; i < playerHealth; i++) { hearts += "❤"; } healthTxt.setText(hearts); } // --- Helper Functions --- function spawnMosquito() { if (!gameActive) { return; } var m = new Mosquito(); // Random position, not too close to top (menu) var margin = 80; m.x = margin + Math.random() * (2048 - 2 * margin); m.y = 150 + Math.random() * (2732 - 250); mosquitoes.push(m); game.addChild(m); } function updateScore() { scoreTxt.setText(score); } // updateTimer removed: no timer to update // Removed updateMissed function (kaçan sayısı) function endGame(win) { gameActive = false; // Show win or game over if (win) { LK.showYouWin(); } else { LK.showGameOver(); } } // --- Racket Setup --- racket = new Racket(); game.addChild(racket); // Start racket in center, lower half racket.x = 2048 / 2; racket.y = 2732 * 0.7; // --- Touch/Drag Controls --- game.down = function (x, y, obj) { // Don't allow drag in top left 100x100 if (x < 100 && y < 100) { return; } dragNode = racket; // Move racket instantly to touch racket.x = x; racket.y = y; }; game.move = function (x, y, obj) { if (!gameActive) { return; } if (dragNode) { // Clamp racket inside game area (leave top 100px) var rw = racket.width * 0.5; var rh = racket.height * 0.5; var nx = Math.max(rw, Math.min(2048 - rw, x)); var ny = Math.max(100 + rh, Math.min(2732 - rh, y)); racket.x = nx; racket.y = ny; } }; game.up = function (x, y, obj) { dragNode = null; }; // --- Main Game Loop --- game.update = function () { if (!gameActive) { return; } // Update mosquitoes for (var i = mosquitoes.length - 1; i >= 0; i--) { var m = mosquitoes[i]; if (!m.alive) { continue; } m.update(); // Check collision with racket var dx = m.x - racket.x; var dy = m.y - racket.y; var dist = Math.sqrt(dx * dx + dy * dy); var hitRadius = m.width * 0.5 + racket.width * 0.5 * 0.7; // --- Big Mosquito Approach Logic --- if (m instanceof BigMosquito) { // Track last and current approach state if (typeof m.lastApproaching === "undefined") { m.lastApproaching = false; } if (typeof m.sticking === "undefined") { m.sticking = false; } var approachRadius = m.width * 0.5 + racket.width * 0.5 * 1.1; // slightly larger than hit var isApproaching = dist < approachRadius; // If just started approaching, stick to racket and start timer if (!m.lastApproaching && isApproaching) { // Stick to racket m.sticking = true; m.stickOffsetX = m.x - racket.x; m.stickOffsetY = m.y - racket.y; // Start a 1s timer for this mosquito if not already started if (!m._approachTimerActive) { m._approachTimerActive = true; m._approachTimerId = LK.setTimeout(function (mosq, idx) { return function () { // Only lose health if still alive, still close, and still sticking if (mosq.alive && mosquitoes.indexOf(mosq) !== -1 && mosq.sticking) { var dx2 = mosq.x - racket.x; var dy2 = mosq.y - racket.y; var dist2 = Math.sqrt(dx2 * dx2 + dy2 * dy2); if (dist2 < approachRadius) { playerHealth -= 1; updateHealthUI(); racket.flash(); if (playerHealth <= 0) { endGame(false); return; } } } mosq._approachTimerActive = false; mosq._approachTimerId = null; mosq.sticking = false; }; }(m, i), 1000); bigMosquitoApproachTimers.push(m._approachTimerId); } } // If moved away, cancel timer if running and unstick if (m.lastApproaching && !isApproaching) { if (m._approachTimerActive && m._approachTimerId) { LK.clearTimeout(m._approachTimerId); m._approachTimerActive = false; m._approachTimerId = null; } m.sticking = false; } // If sticking, follow racket if (m.sticking) { m.x = racket.x + (typeof m.stickOffsetX === "number" ? m.stickOffsetX : 0); m.y = racket.y + (typeof m.stickOffsetY === "number" ? m.stickOffsetY : 0); } m.lastApproaching = isApproaching; } // --- End Big Mosquito Approach Logic --- if (dist < hitRadius) { // If big mosquito, destroy on first hit if (m instanceof BigMosquito) { // If this is the special big bee (arı) at score 50 if (m.isBigBee) { // Remove the scheduled timeout to auto-remove the bee if (m._removeTimeout) { LK.clearTimeout(m._removeTimeout); m._removeTimeout = null; } // Reduce player health by 5 playerHealth -= 5; updateHealthUI(); racket.flash(); if (playerHealth <= 0) { endGame(false); return; } } // Cancel any pending approach timer if (m._approachTimerActive && m._approachTimerId) { LK.clearTimeout(m._approachTimerId); m._approachTimerActive = false; m._approachTimerId = null; } // Cancel any pending approach timer and unstick if (m._approachTimerActive && m._approachTimerId) { LK.clearTimeout(m._approachTimerId); m._approachTimerActive = false; m._approachTimerId = null; } m.sticking = false; racket.flash(); m.squash(function () { m.destroy(); }); mosquitoes.splice(i, 1); continue; } // Hit! m.squash(function () { m.destroy(); }); mosquitoes.splice(i, 1); score += 1; updateScore(); racket.flash(); // Spawn big bee (arı) every time score increases by 30 (i.e., at 30, 60, 90, ...) if (score > 0 && score % 30 === 0) { // Prevent multiple spawns for the same score if (typeof game.lastBigBeeScore === "undefined" || game.lastBigBeeScore !== score) { game.lastBigBeeScore = score; var bigBee = new BigMosquito(); bigBee.isBigBee = true; // Mark as special bee BEFORE asset attach // Re-attach blue box asset for big bee if (typeof bigBee.children !== "undefined" && bigBee.children.length > 0) { for (var i = bigBee.children.length - 1; i >= 0; i--) { bigBee.removeChild(bigBee.children[i]); } } bigBee.attachAsset('bigbee', { anchorX: 0.5, anchorY: 0.5, scaleX: 1, scaleY: 1 }); // Random position, not too close to top (menu) var margin = 120; bigBee.x = margin + Math.random() * (2048 - 2 * margin); bigBee.y = 200 + Math.random() * (2732 - 400); mosquitoes.push(bigBee); game.addChild(bigBee); // Show info text for 5 seconds if (typeof game.bigBeeInfoTxt !== "undefined" && game.bigBeeInfoTxt) { LK.gui.top.removeChild(game.bigBeeInfoTxt); game.bigBeeInfoTxt = null; } game.bigBeeInfoTxt = new Text2("The bee will disappear after 5 seconds", { size: 50, fill: 0x0055FF }); // Center anchor both horizontally and vertically game.bigBeeInfoTxt.anchor.set(0.5, 0.5); // Pause the game when big bee appears gameActive = false; LK.setTimeout(function () { // Center in the middle of the screen (LK.gui.top is overlay, so use its width/height) game.bigBeeInfoTxt.x = LK.gui.top.width / 2 - 120; game.bigBeeInfoTxt.y = LK.gui.top.height / 2; // Ensure the text is fully visible and not clipped // If the text is too wide or tall, adjust size or position to fit // Defensive: get current size from .style or fallback to 50 var currentSize = game.bigBeeInfoTxt && game.bigBeeInfoTxt.style && typeof game.bigBeeInfoTxt.style.size === "number" ? game.bigBeeInfoTxt.style.size : 50; if (game.bigBeeInfoTxt.width > LK.gui.top.width - 100) { game.bigBeeInfoTxt.setStyle({ size: Math.floor(currentSize * (LK.gui.top.width - 100) / game.bigBeeInfoTxt.width) }); game.bigBeeInfoTxt.x = LK.gui.top.width / 2 - 120; } if (game.bigBeeInfoTxt.height > LK.gui.top.height - 100) { // Re-fetch current size in case it changed above var currentSize2 = game.bigBeeInfoTxt && game.bigBeeInfoTxt.style && typeof game.bigBeeInfoTxt.style.size === "number" ? game.bigBeeInfoTxt.style.size : 50; game.bigBeeInfoTxt.setStyle({ size: Math.floor(currentSize2 * (LK.gui.top.height - 100) / game.bigBeeInfoTxt.height) }); game.bigBeeInfoTxt.y = LK.gui.top.height / 2; } // After resizing, re-center to ensure perfect centering game.bigBeeInfoTxt.x = LK.gui.top.width / 2 - 120; game.bigBeeInfoTxt.y = LK.gui.top.height / 2; }, 0); LK.gui.top.addChild(game.bigBeeInfoTxt); // Remove the big bee after 5 seconds if still alive, and resume the game bigBee._removeTimeout = LK.setTimeout(function () { var idx = mosquitoes.indexOf(bigBee); if (idx !== -1 && bigBee.alive) { bigBee.squash(function () { bigBee.destroy(); }); mosquitoes.splice(idx, 1); } // Remove info text if (typeof game.bigBeeInfoTxt !== "undefined" && game.bigBeeInfoTxt) { LK.gui.top.removeChild(game.bigBeeInfoTxt); game.bigBeeInfoTxt = null; } // Resume the game after big bee disappears gameActive = true; }, 5000); } } // For other multiples of 5 (except 10), spawn big mosquito as before if (score > 0 && score % 5 === 0 && score !== 10) { var bigM = new BigMosquito(); // Random position, not too close to top (menu) var margin = 120; bigM.x = margin + Math.random() * (2048 - 2 * margin); bigM.y = 200 + Math.random() * (2732 - 400); mosquitoes.push(bigM); game.addChild(bigM); } // Show shop at score 35 // Win condition if (score >= 10000000000000000000000000000000000000000000000000000000) { endGame(true); return; } continue; } // Removed mosquito escape logic: mosquitoes no longer get destroyed at the edge } // End game if there are more than 20 mosquitoes on screen if (mosquitoes.length > 20 && gameActive) { endGame(false); return; } // Gradually increase maxMosquitoes every 300 ticks (about every 5 seconds) mosquitoRampTick = typeof mosquitoRampTick === "number" ? mosquitoRampTick + 1 : 1; if (mosquitoRampTick % 300 === 0 && maxMosquitoes < 20) { maxMosquitoes += 1; } // Spawn exactly 2 mosquitoes every 1 second using a timer if (typeof mosquitoSpawnTimer === "undefined") { var mosquitoSpawnTimer = LK.setInterval(function () { if (!gameActive) { return; } // Always spawn 2 mosquitoes every second, regardless of current count (unless at or above maxMosquitoes) var canSpawn = Math.max(0, maxMosquitoes - mosquitoes.length); var toSpawn = Math.min(2, canSpawn); for (var i = 0; i < toSpawn; i++) { spawnMosquito(); } }, 1000); } }; // Timer removed: no time-based lose condition // --- Game Start --- score = 0; updateScore(); playerHealth = 3; if (typeof updateHealthUI === "function") { updateHealthUI(); } for (var i = 0; i < maxMosquitoes; i++) { spawnMosquito(); }
/****
* Classes
****/
// BigMosquito class: represents a large mosquito
var BigMosquito = Container.expand(function () {
var self = Container.call(this);
// If this is the special big bee (arı), use blue box asset, else use mosquito
var mosquitoGfx;
if (self.isBigBee) {
mosquitoGfx = self.attachAsset('bigbee', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1
});
} else {
mosquitoGfx = self.attachAsset('mosquito', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2.2,
scaleY: 2.2
});
}
// Big mosquito speed (slower for regular, faster for big bee)
if (self.isBigBee) {
self.speed = 8 + Math.random() * 4; // 8-12 px/tick for big bee (arı)
} else {
self.speed = 4 + Math.random() * 2; // 4-6 px/tick for regular big mosquito
}
// Direction in radians (random)
self.direction = Math.random() * Math.PI * 2;
self.changeDirTimer = 40 + Math.floor(Math.random() * 60);
self.alive = true;
// Big mosquito dies in 1 hit (default)
self.update = function () {
// If racket exists, home in on racket
if (typeof racket !== "undefined" && racket !== null && racket.x !== undefined && racket.y !== undefined) {
var dx = racket.x - self.x;
var dy = racket.y - self.y;
var angleToRacket = Math.atan2(dy, dx);
// Smoothly turn toward racket
var angleDiff = angleToRacket - self.direction;
// Normalize angleDiff to [-PI, PI]
while (angleDiff > Math.PI) {
angleDiff -= 2 * Math.PI;
}
while (angleDiff < -Math.PI) {
angleDiff += 2 * Math.PI;
}
// Turn speed: bigger = more aggressive
var turnSpeed = 0.07;
if (Math.abs(angleDiff) < turnSpeed) {
self.direction = angleToRacket;
} else {
self.direction += turnSpeed * Math.sign(angleDiff);
}
}
self.x += Math.cos(self.direction) * self.speed;
self.y += Math.sin(self.direction) * self.speed;
var margin = mosquitoGfx.width / 2 + 10;
if (self.x < margin) {
self.x = margin;
self.direction = Math.PI - self.direction + (Math.random() - 0.5) * 0.5;
}
if (self.x > 2048 - margin) {
self.x = 2048 - margin;
self.direction = Math.PI - self.direction + (Math.random() - 0.5) * 0.5;
}
if (self.y < margin + 100) {
self.y = margin + 100;
self.direction = -self.direction + (Math.random() - 0.5) * 0.5;
}
if (self.y > 2732 - margin) {
self.y = 2732 - margin;
self.direction = -self.direction + (Math.random() - 0.5) * 0.5;
}
self.changeDirTimer--;
if (self.changeDirTimer <= 0) {
self.direction += (Math.random() - 0.5) * Math.PI / 1.5;
self.changeDirTimer = 40 + Math.floor(Math.random() * 60);
}
};
// When hit, play animation and destroy
self.squash = function (_onFinish) {
self.alive = false;
self.scaleX = 2.5;
self.scaleY = 0.7;
self.alpha = 0;
if (_onFinish) {
_onFinish();
}
};
return self;
});
//var tween = LK.import("@upit/tween.v1");
// Mosquito class: represents a single mosquito
var Mosquito = Container.expand(function () {
var self = Container.call(this);
// Attach mosquito asset (ellipse, small, dark color)
var mosquitoGfx = self.attachAsset('mosquito', {
anchorX: 0.5,
anchorY: 0.5
});
// Mosquito speed (pixels per tick)
self.speed = 6 + Math.random() * 4; // 6-10 px/tick
// Direction in radians (random)
self.direction = Math.random() * Math.PI * 2;
// Time until next direction change
self.changeDirTimer = 30 + Math.floor(Math.random() * 60);
// Mark as alive
self.alive = true;
// Update method: called every tick
self.update = function () {
// If racket exists and is close, move away from racket
if (typeof racket !== "undefined" && racket !== null && racket.x !== undefined && racket.y !== undefined) {
var dx = self.x - racket.x;
var dy = self.y - racket.y;
var dist = Math.sqrt(dx * dx + dy * dy);
var fleeRadius = 400; // px, how close before fleeing
if (dist < fleeRadius) {
// Move away from racket: set direction away, with some random jitter
var angleFromRacket = Math.atan2(dy, dx);
// Add a little randomness so they don't all flee in a straight line
self.direction = angleFromRacket + (Math.random() - 0.5) * 0.5;
// Optional: speed up a bit when fleeing
self.x += Math.cos(self.direction) * (self.speed + 2);
self.y += Math.sin(self.direction) * (self.speed + 2);
} else {
self.x += Math.cos(self.direction) * self.speed;
self.y += Math.sin(self.direction) * self.speed;
}
} else {
self.x += Math.cos(self.direction) * self.speed;
self.y += Math.sin(self.direction) * self.speed;
}
// Bounce off walls (game area: 0,0 to 2048,2732)
var margin = mosquitoGfx.width / 2 + 10;
if (self.x < margin) {
self.x = margin;
self.direction = Math.PI - self.direction + (Math.random() - 0.5) * 0.5;
}
if (self.x > 2048 - margin) {
self.x = 2048 - margin;
self.direction = Math.PI - self.direction + (Math.random() - 0.5) * 0.5;
}
if (self.y < margin + 100) {
// leave top 100px for menu
self.y = margin + 100;
self.direction = -self.direction + (Math.random() - 0.5) * 0.5;
}
if (self.y > 2732 - margin) {
self.y = 2732 - margin;
self.direction = -self.direction + (Math.random() - 0.5) * 0.5;
}
// Change direction randomly
self.changeDirTimer--;
if (self.changeDirTimer <= 0) {
self.direction += (Math.random() - 0.5) * Math.PI / 1.5;
self.changeDirTimer = 30 + Math.floor(Math.random() * 60);
}
};
// When hit, play animation and destroy
self.squash = function (_onFinish) {
self.alive = false;
// Instantly squash and fade out (no tween)
self.scaleX = 1.7;
self.scaleY = 0.5;
self.alpha = 0;
if (_onFinish) {
_onFinish();
}
};
return self;
});
// Racket class: represents the player's racket
var Racket = Container.expand(function () {
var self = Container.call(this);
// Attach racket asset (rectangle, bright color)
var racketGfx = self.attachAsset('racket', {
anchorX: 0.5,
anchorY: 0.5
});
// Optionally, add a little shadow for visibility
racketGfx.alpha = 0.95;
// Racket size for collision
self.radius = racketGfx.width * 0.5;
// For touch feedback
self.flash = function () {
// Instantly flash racket (no tween)
racketGfx.tint = 0xffff00;
LK.setTimeout(function () {
racketGfx.tint = 0xffffff;
}, 80);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x888888 // Gray background
});
/****
* Game Code
****/
// --- Game Variables ---
// --- Game Variables ---
// --- Asset Initialization ---
var mosquitoes = [];
var racket = null;
var score = 0;
var scoreTxt = null;
// Player health (3 lives)
var playerHealth = 3;
var healthTxt = null;
// Timer removed: no time limit
var maxMosquitoes = 5; // Start value, will increase over time
var mosquitoRampTick = 0; // Track ticks for ramping up
// Removed mosquitoesEscaped and maxEscaped (kaçan sayısı) as requested
var gameActive = true;
var dragNode = null;
game.bigMosquitoSpawned = false;
// Track big mosquito approach timers
var bigMosquitoApproachTimers = [];
// --- UI Elements ---
// Skor text
scoreTxt = new Text2('0', {
size: 120,
fill: "#222"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Health text (hearts)
healthTxt = new Text2('❤❤❤', {
size: 100,
fill: "#c00"
});
// Anchor to center-top, so it aligns with score
healthTxt.anchor.set(0.5, 0);
// Position health exactly centered below score
healthTxt.x = LK.gui.top.width / 2;
healthTxt.y = scoreTxt.height + 10;
LK.gui.top.addChild(healthTxt);
function updateHealthUI() {
var hearts = "";
for (var i = 0; i < playerHealth; i++) {
hearts += "❤";
}
healthTxt.setText(hearts);
}
// --- Helper Functions ---
function spawnMosquito() {
if (!gameActive) {
return;
}
var m = new Mosquito();
// Random position, not too close to top (menu)
var margin = 80;
m.x = margin + Math.random() * (2048 - 2 * margin);
m.y = 150 + Math.random() * (2732 - 250);
mosquitoes.push(m);
game.addChild(m);
}
function updateScore() {
scoreTxt.setText(score);
}
// updateTimer removed: no timer to update
// Removed updateMissed function (kaçan sayısı)
function endGame(win) {
gameActive = false;
// Show win or game over
if (win) {
LK.showYouWin();
} else {
LK.showGameOver();
}
}
// --- Racket Setup ---
racket = new Racket();
game.addChild(racket);
// Start racket in center, lower half
racket.x = 2048 / 2;
racket.y = 2732 * 0.7;
// --- Touch/Drag Controls ---
game.down = function (x, y, obj) {
// Don't allow drag in top left 100x100
if (x < 100 && y < 100) {
return;
}
dragNode = racket;
// Move racket instantly to touch
racket.x = x;
racket.y = y;
};
game.move = function (x, y, obj) {
if (!gameActive) {
return;
}
if (dragNode) {
// Clamp racket inside game area (leave top 100px)
var rw = racket.width * 0.5;
var rh = racket.height * 0.5;
var nx = Math.max(rw, Math.min(2048 - rw, x));
var ny = Math.max(100 + rh, Math.min(2732 - rh, y));
racket.x = nx;
racket.y = ny;
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
// --- Main Game Loop ---
game.update = function () {
if (!gameActive) {
return;
}
// Update mosquitoes
for (var i = mosquitoes.length - 1; i >= 0; i--) {
var m = mosquitoes[i];
if (!m.alive) {
continue;
}
m.update();
// Check collision with racket
var dx = m.x - racket.x;
var dy = m.y - racket.y;
var dist = Math.sqrt(dx * dx + dy * dy);
var hitRadius = m.width * 0.5 + racket.width * 0.5 * 0.7;
// --- Big Mosquito Approach Logic ---
if (m instanceof BigMosquito) {
// Track last and current approach state
if (typeof m.lastApproaching === "undefined") {
m.lastApproaching = false;
}
if (typeof m.sticking === "undefined") {
m.sticking = false;
}
var approachRadius = m.width * 0.5 + racket.width * 0.5 * 1.1; // slightly larger than hit
var isApproaching = dist < approachRadius;
// If just started approaching, stick to racket and start timer
if (!m.lastApproaching && isApproaching) {
// Stick to racket
m.sticking = true;
m.stickOffsetX = m.x - racket.x;
m.stickOffsetY = m.y - racket.y;
// Start a 1s timer for this mosquito if not already started
if (!m._approachTimerActive) {
m._approachTimerActive = true;
m._approachTimerId = LK.setTimeout(function (mosq, idx) {
return function () {
// Only lose health if still alive, still close, and still sticking
if (mosq.alive && mosquitoes.indexOf(mosq) !== -1 && mosq.sticking) {
var dx2 = mosq.x - racket.x;
var dy2 = mosq.y - racket.y;
var dist2 = Math.sqrt(dx2 * dx2 + dy2 * dy2);
if (dist2 < approachRadius) {
playerHealth -= 1;
updateHealthUI();
racket.flash();
if (playerHealth <= 0) {
endGame(false);
return;
}
}
}
mosq._approachTimerActive = false;
mosq._approachTimerId = null;
mosq.sticking = false;
};
}(m, i), 1000);
bigMosquitoApproachTimers.push(m._approachTimerId);
}
}
// If moved away, cancel timer if running and unstick
if (m.lastApproaching && !isApproaching) {
if (m._approachTimerActive && m._approachTimerId) {
LK.clearTimeout(m._approachTimerId);
m._approachTimerActive = false;
m._approachTimerId = null;
}
m.sticking = false;
}
// If sticking, follow racket
if (m.sticking) {
m.x = racket.x + (typeof m.stickOffsetX === "number" ? m.stickOffsetX : 0);
m.y = racket.y + (typeof m.stickOffsetY === "number" ? m.stickOffsetY : 0);
}
m.lastApproaching = isApproaching;
}
// --- End Big Mosquito Approach Logic ---
if (dist < hitRadius) {
// If big mosquito, destroy on first hit
if (m instanceof BigMosquito) {
// If this is the special big bee (arı) at score 50
if (m.isBigBee) {
// Remove the scheduled timeout to auto-remove the bee
if (m._removeTimeout) {
LK.clearTimeout(m._removeTimeout);
m._removeTimeout = null;
}
// Reduce player health by 5
playerHealth -= 5;
updateHealthUI();
racket.flash();
if (playerHealth <= 0) {
endGame(false);
return;
}
}
// Cancel any pending approach timer
if (m._approachTimerActive && m._approachTimerId) {
LK.clearTimeout(m._approachTimerId);
m._approachTimerActive = false;
m._approachTimerId = null;
}
// Cancel any pending approach timer and unstick
if (m._approachTimerActive && m._approachTimerId) {
LK.clearTimeout(m._approachTimerId);
m._approachTimerActive = false;
m._approachTimerId = null;
}
m.sticking = false;
racket.flash();
m.squash(function () {
m.destroy();
});
mosquitoes.splice(i, 1);
continue;
}
// Hit!
m.squash(function () {
m.destroy();
});
mosquitoes.splice(i, 1);
score += 1;
updateScore();
racket.flash();
// Spawn big bee (arı) every time score increases by 30 (i.e., at 30, 60, 90, ...)
if (score > 0 && score % 30 === 0) {
// Prevent multiple spawns for the same score
if (typeof game.lastBigBeeScore === "undefined" || game.lastBigBeeScore !== score) {
game.lastBigBeeScore = score;
var bigBee = new BigMosquito();
bigBee.isBigBee = true; // Mark as special bee BEFORE asset attach
// Re-attach blue box asset for big bee
if (typeof bigBee.children !== "undefined" && bigBee.children.length > 0) {
for (var i = bigBee.children.length - 1; i >= 0; i--) {
bigBee.removeChild(bigBee.children[i]);
}
}
bigBee.attachAsset('bigbee', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 1,
scaleY: 1
});
// Random position, not too close to top (menu)
var margin = 120;
bigBee.x = margin + Math.random() * (2048 - 2 * margin);
bigBee.y = 200 + Math.random() * (2732 - 400);
mosquitoes.push(bigBee);
game.addChild(bigBee);
// Show info text for 5 seconds
if (typeof game.bigBeeInfoTxt !== "undefined" && game.bigBeeInfoTxt) {
LK.gui.top.removeChild(game.bigBeeInfoTxt);
game.bigBeeInfoTxt = null;
}
game.bigBeeInfoTxt = new Text2("The bee will disappear after 5 seconds", {
size: 50,
fill: 0x0055FF
});
// Center anchor both horizontally and vertically
game.bigBeeInfoTxt.anchor.set(0.5, 0.5);
// Pause the game when big bee appears
gameActive = false;
LK.setTimeout(function () {
// Center in the middle of the screen (LK.gui.top is overlay, so use its width/height)
game.bigBeeInfoTxt.x = LK.gui.top.width / 2 - 120;
game.bigBeeInfoTxt.y = LK.gui.top.height / 2;
// Ensure the text is fully visible and not clipped
// If the text is too wide or tall, adjust size or position to fit
// Defensive: get current size from .style or fallback to 50
var currentSize = game.bigBeeInfoTxt && game.bigBeeInfoTxt.style && typeof game.bigBeeInfoTxt.style.size === "number" ? game.bigBeeInfoTxt.style.size : 50;
if (game.bigBeeInfoTxt.width > LK.gui.top.width - 100) {
game.bigBeeInfoTxt.setStyle({
size: Math.floor(currentSize * (LK.gui.top.width - 100) / game.bigBeeInfoTxt.width)
});
game.bigBeeInfoTxt.x = LK.gui.top.width / 2 - 120;
}
if (game.bigBeeInfoTxt.height > LK.gui.top.height - 100) {
// Re-fetch current size in case it changed above
var currentSize2 = game.bigBeeInfoTxt && game.bigBeeInfoTxt.style && typeof game.bigBeeInfoTxt.style.size === "number" ? game.bigBeeInfoTxt.style.size : 50;
game.bigBeeInfoTxt.setStyle({
size: Math.floor(currentSize2 * (LK.gui.top.height - 100) / game.bigBeeInfoTxt.height)
});
game.bigBeeInfoTxt.y = LK.gui.top.height / 2;
}
// After resizing, re-center to ensure perfect centering
game.bigBeeInfoTxt.x = LK.gui.top.width / 2 - 120;
game.bigBeeInfoTxt.y = LK.gui.top.height / 2;
}, 0);
LK.gui.top.addChild(game.bigBeeInfoTxt);
// Remove the big bee after 5 seconds if still alive, and resume the game
bigBee._removeTimeout = LK.setTimeout(function () {
var idx = mosquitoes.indexOf(bigBee);
if (idx !== -1 && bigBee.alive) {
bigBee.squash(function () {
bigBee.destroy();
});
mosquitoes.splice(idx, 1);
}
// Remove info text
if (typeof game.bigBeeInfoTxt !== "undefined" && game.bigBeeInfoTxt) {
LK.gui.top.removeChild(game.bigBeeInfoTxt);
game.bigBeeInfoTxt = null;
}
// Resume the game after big bee disappears
gameActive = true;
}, 5000);
}
}
// For other multiples of 5 (except 10), spawn big mosquito as before
if (score > 0 && score % 5 === 0 && score !== 10) {
var bigM = new BigMosquito();
// Random position, not too close to top (menu)
var margin = 120;
bigM.x = margin + Math.random() * (2048 - 2 * margin);
bigM.y = 200 + Math.random() * (2732 - 400);
mosquitoes.push(bigM);
game.addChild(bigM);
}
// Show shop at score 35
// Win condition
if (score >= 10000000000000000000000000000000000000000000000000000000) {
endGame(true);
return;
}
continue;
}
// Removed mosquito escape logic: mosquitoes no longer get destroyed at the edge
}
// End game if there are more than 20 mosquitoes on screen
if (mosquitoes.length > 20 && gameActive) {
endGame(false);
return;
}
// Gradually increase maxMosquitoes every 300 ticks (about every 5 seconds)
mosquitoRampTick = typeof mosquitoRampTick === "number" ? mosquitoRampTick + 1 : 1;
if (mosquitoRampTick % 300 === 0 && maxMosquitoes < 20) {
maxMosquitoes += 1;
}
// Spawn exactly 2 mosquitoes every 1 second using a timer
if (typeof mosquitoSpawnTimer === "undefined") {
var mosquitoSpawnTimer = LK.setInterval(function () {
if (!gameActive) {
return;
}
// Always spawn 2 mosquitoes every second, regardless of current count (unless at or above maxMosquitoes)
var canSpawn = Math.max(0, maxMosquitoes - mosquitoes.length);
var toSpawn = Math.min(2, canSpawn);
for (var i = 0; i < toSpawn; i++) {
spawnMosquito();
}
}, 1000);
}
};
// Timer removed: no time-based lose condition
// --- Game Start ---
score = 0;
updateScore();
playerHealth = 3;
if (typeof updateHealthUI === "function") {
updateHealthUI();
}
for (var i = 0; i < maxMosquitoes; i++) {
spawnMosquito();
}
sivrisinek. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
racket sivriseinek için . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
arı. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat