/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var Bonus = Container.expand(function () { var self = Container.call(this); var bonusGraphics = self.attachAsset('Bonus', { anchorX: 0.5, anchorY: 0.5 }); bonusGraphics.scaleX = 0.3; bonusGraphics.scaleY = 0.3; self.fallSpeed = 3; self.points = 50; self.collected = false; self.update = function () { if (self.collected) return; self.y += self.fallSpeed; // Remove if it hits the ground if (self.y > 2600) { self.collected = true; self.alpha = 0; } }; self.collect = function () { if (self.collected) return false; self.collected = true; // Flash effect LK.effects.flashObject(self, 0xFFFFFF, 200); // Fade out animation tween(self, { alpha: 0, scaleX: bonusGraphics.scaleX * 2, scaleY: bonusGraphics.scaleY * 2 }, { duration: 300, easing: tween.easeOut }); return true; }; return self; }); var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); self.targetX = 0; self.targetY = 0; self.speed = 25; self.travelled = 0; self.maxDistance = 200; self.update = function () { var dx = self.targetX - self.x; var dy = self.targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > 5 && self.travelled < self.maxDistance) { var moveX = dx / distance * self.speed; var moveY = dy / distance * self.speed; self.x += moveX; self.y += moveY; self.travelled += Math.sqrt(moveX * moveX + moveY * moveY); } else { self.alpha -= 0.1; } }; return self; }); var Cloud = Container.expand(function () { var self = Container.call(this); var cloudGraphics = self.attachAsset('cloud', { anchorX: 0.5, anchorY: 0.5 }); cloudGraphics.alpha = 0.7; self.speed = 0.5 + Math.random() * 1; // Random slow speed self.direction = Math.random() < 0.5 ? 1 : -1; // Left or right self.update = function () { self.x += self.speed * self.direction; // Reset position when off screen if (self.direction > 0 && self.x > 2200) { self.x = -200; } else if (self.direction < 0 && self.x < -200) { self.x = 2200; } }; return self; }); var Crosshair = Container.expand(function () { var self = Container.call(this); var crosshairGraphics = self.attachAsset('crosshair', { anchorX: 0.5, anchorY: 0.5 }); crosshairGraphics.alpha = 0.7; self.visible = false; return self; }); var Duck = Container.expand(function () { var self = Container.call(this); var duckGraphics = self.attachAsset('duck', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 2 + Math.random() * 8; // Random speed between 2-10 self.direction = Math.random() < 0.5 ? 1 : -1; // Left or right self.verticalSpeed = (Math.random() - 0.5) * 2; // Random vertical movement self.isHit = false; self.points = 60; // Set initial position based on direction if (self.direction > 0) { self.x = -100; // Duck moving right (from left side) should face left duckGraphics.scaleX = -1; } else { self.x = 2148; // Duck moving left (from right side) should face right duckGraphics.scaleX = 1; } self.y = 300 + Math.random() * 1000; // Random height self.update = function () { if (self.isHit) return; self.x += self.speed * self.direction; self.y += self.verticalSpeed; // Add some wobble to flight pattern self.y += Math.sin(LK.ticks * 0.1 + self.x * 0.01) * 2; // Keep ducks within screen bounds vertically if (self.y < 200) { self.y = 200; self.verticalSpeed = Math.abs(self.verticalSpeed); } if (self.y > 2500) { self.y = 2500; self.verticalSpeed = -Math.abs(self.verticalSpeed); } }; self.hit = function () { if (self.isHit) return false; self.isHit = true; LK.getSound('hit').play(); // Flash effect LK.effects.flashObject(self, 0xFFFFFF, 300); // Create floating points display var pointsDisplay = new PointsDisplay(); pointsDisplay.x = self.x; pointsDisplay.y = self.y - 50; pointsDisplays.push(pointsDisplay); game.addChild(pointsDisplay); pointsDisplay.show(self.points); // 30% chance to drop a bonus if (Math.random() < 0.3) { var bonus = new Bonus(); bonus.x = self.x; bonus.y = self.y; bonuses.push(bonus); game.addChild(bonus); } // Fall down animation tween(self, { y: self.y + 200, alpha: 0, rotation: Math.PI }, { duration: 800, easing: tween.easeIn }); return true; }; return self; }); var Grass = Container.expand(function () { var self = Container.call(this); var grassGraphics = self.attachAsset('grass', { anchorX: 0.5, anchorY: 1.0 }); grassGraphics.alpha = 0.8; return self; }); var Hunter = Container.expand(function () { var self = Container.call(this); var hunterGraphics = self.attachAsset('hunters', { anchorX: 0.5, anchorY: 1.0 }); self.defaultY = 0; self.shootOffset = -30; self.isLookingRight = true; self.shoot = function (targetX, targetY) { // Determine which direction to look based on target (reversed) var shouldLookRight = targetX < self.x; if (shouldLookRight !== self.isLookingRight) { self.isLookingRight = shouldLookRight; // Flip hunter sprite hunterGraphics.scaleX = shouldLookRight ? 1 : -1; } // Rotation effect removed - hunter no longer rotates to aim // Enhanced hunter body recoil animation tween(self, { y: self.defaultY + 25, x: self.x + (shouldLookRight ? -8 : 8) // Slight backward lean }, { duration: 100, easing: tween.easeOut, onFinish: function onFinish() { tween(self, { y: self.defaultY, x: 2048 / 2 // Return to center }, { duration: 250, easing: tween.easeInOut }); } }); }; return self; }); var PointsDisplay = Container.expand(function () { var self = Container.call(this); var pointsGraphics = self.attachAsset('points', { anchorX: 0.5, anchorY: 0.5 }); pointsGraphics.scaleX = 0.8; pointsGraphics.scaleY = 0.8; self.show = function (points) { // Start animation - move upward and fade out tween(self, { y: self.y - 150, alpha: 0, scaleX: pointsGraphics.scaleX * 1.5, scaleY: pointsGraphics.scaleY * 1.5 }, { duration: 1500, easing: tween.easeOut }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87CEEB }); /**** * Game Code ****/ var ducks = []; var bullets = []; var bonuses = []; var clouds = []; var pointsDisplays = []; var crosshair = null; var missedDucks = 0; var maxMissedDucks = 5; var consecutiveHits = 0; var waveNumber = 1; var ducksInWave = 3; var ducksSpawned = 0; var waveTimer = 0; // UI Elements var scoreTxt = new Text2('Score: 0', { size: 80, fill: 0xFFFFFF }); scoreTxt.anchor.set(0.5, 0); LK.gui.top.addChild(scoreTxt); var missedTxt = new Text2('Missed: 0/5', { size: 60, fill: 0xFF0000 }); missedTxt.anchor.set(1, 0); LK.gui.topRight.addChild(missedTxt); var waveTxt = new Text2('Wave: 1', { size: 60, fill: 0x00FF00 }); waveTxt.anchor.set(0, 0); waveTxt.x = 150; // Offset from top-left to avoid menu waveTxt.y = 50; LK.gui.topLeft.addChild(waveTxt); // Create crosshair crosshair = game.addChild(new Crosshair()); // Create hunter positioned at bottom center var hunter = game.addChild(new Hunter()); hunter.x = 2048 / 2; hunter.y = 2732 - 50; hunter.defaultY = hunter.y; // Create grass across the entire bottom of the screen var grassObjects = []; var grassWidth = 400; // Width of each grass asset var numGrassObjects = Math.ceil(2048 / grassWidth) + 1; // Cover full width plus some overlap for (var g = 0; g < numGrassObjects; g++) { var grass = game.addChild(new Grass()); grass.x = g * (grassWidth * 0.8); // Slight overlap between grass objects grass.y = 2732 - 30; grassObjects.push(grass); } // Create clouds at top of screen for (var c = 0; c < 4; c++) { var cloud = game.addChild(new Cloud()); cloud.x = 200 + c * 500 + Math.random() * 200; // Spread across screen width cloud.y = 100 + Math.random() * 150; // Random height at top clouds.push(cloud); } function spawnDuck() { var duck = new Duck(); // Adjust speed based on wave duck.speed += waveNumber * 0.5; duck.points = 60 + waveNumber * 10; // Base 60 points plus wave bonus ducks.push(duck); game.addChild(duck); ducksSpawned++; } function updateScore() { scoreTxt.setText('Score: ' + LK.getScore()); } function updateMissed() { missedTxt.setText('Missed: ' + missedDucks + '/' + maxMissedDucks); } function updateWave() { waveTxt.setText('Wave: ' + waveNumber); } function checkHit(x, y) { var hitDuck = null; var minDistance = 100; // Hit radius for (var i = 0; i < ducks.length; i++) { var duck = ducks[i]; if (duck.isHit) continue; var dx = duck.x - x; var dy = duck.y - y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < minDistance) { minDistance = distance; hitDuck = duck; } } return hitDuck; } function startNextWave() { waveNumber++; ducksSpawned = 0; ducksInWave = Math.min(3 + Math.floor(waveNumber / 2), 8); // Max 8 ducks per wave waveTimer = 0; updateWave(); } // Game controls var mouseX = 2048 / 2; var mouseY = 2732 / 2; game.move = function (x, y, obj) { // Update mouse position continuously mouseX = x; mouseY = y; }; game.down = function (x, y, obj) { // Update mouse position mouseX = x; mouseY = y; // Show crosshair crosshair.x = x; crosshair.y = y; crosshair.visible = true; // Move crosshair to front to ensure it appears above ducks game.removeChild(crosshair); game.addChild(crosshair); // Create bullet var bullet = new Bullet(); bullet.x = x; bullet.y = y; bullet.targetX = x; bullet.targetY = y; bullets.push(bullet); game.addChild(bullet); // Play shoot sound LK.getSound('shoot').play(); // Trigger hunter shooting animation hunter.shoot(x, y); // Check for bonus collection var hitBonus = null; var minBonusDistance = 80; for (var b = 0; b < bonuses.length; b++) { var bonus = bonuses[b]; if (bonus.collected) continue; var bdx = bonus.x - x; var bdy = bonus.y - y; var bonusDistance = Math.sqrt(bdx * bdx + bdy * bdy); if (bonusDistance < minBonusDistance) { minBonusDistance = bonusDistance; hitBonus = bonus; } } if (hitBonus && hitBonus.collect()) { LK.setScore(LK.getScore() + hitBonus.points); updateScore(); } // Check for hit var hitDuck = checkHit(x, y); if (hitDuck) { if (hitDuck.hit()) { consecutiveHits++; var points = 60; // Fixed 60 points per duck // Bonus for consecutive hits if (consecutiveHits > 1) { points += consecutiveHits * 10; } LK.setScore(LK.getScore() + points); updateScore(); } } else { consecutiveHits = 0; LK.getSound('miss').play(); } // Hide crosshair after short delay LK.setTimeout(function () { crosshair.visible = false; }, 100); }; game.update = function () { // Update hunter facing direction based on mouse (reversed) var hunterGraphics = hunter.children[0]; // Hunter graphics is first child var shouldLookRight = mouseX < hunter.x; if (shouldLookRight !== hunter.isLookingRight) { hunter.isLookingRight = shouldLookRight; // Flip hunter sprite hunterGraphics.scaleX = shouldLookRight ? 1 : -1; } waveTimer++; // Spawn ducks for current wave if (ducksSpawned < ducksInWave && waveTimer % 120 === 0) { // Spawn every 2 seconds spawnDuck(); } // Update and remove off-screen ducks for (var i = ducks.length - 1; i >= 0; i--) { var duck = ducks[i]; if (duck.lastX === undefined) duck.lastX = duck.x; if (duck.lastOffScreen === undefined) duck.lastOffScreen = false; var currentOffScreen = duck.x < -150 || duck.x > 2198; // Check if duck just went off screen if (!duck.lastOffScreen && currentOffScreen && !duck.isHit) { missedDucks++; updateMissed(); consecutiveHits = 0; if (missedDucks >= maxMissedDucks) { LK.showGameOver(); return; } } // Remove duck if it's been off screen for a while or hit and faded if (currentOffScreen && (duck.lastOffScreen || duck.isHit) || duck.alpha <= 0) { duck.destroy(); ducks.splice(i, 1); } else { duck.lastX = duck.x; duck.lastOffScreen = currentOffScreen; } } // Update and remove bullets for (var j = bullets.length - 1; j >= 0; j--) { var bullet = bullets[j]; if (bullet.alpha <= 0) { bullet.destroy(); bullets.splice(j, 1); } } // Update and remove bonuses for (var k = bonuses.length - 1; k >= 0; k--) { var bonus = bonuses[k]; if (bonus.alpha <= 0 || bonus.collected) { bonus.destroy(); bonuses.splice(k, 1); } } // Update and remove points displays for (var p = pointsDisplays.length - 1; p >= 0; p--) { var pointsDisplay = pointsDisplays[p]; if (pointsDisplay.alpha <= 0) { pointsDisplay.destroy(); pointsDisplays.splice(p, 1); } } // Check if wave is complete if (ducksSpawned >= ducksInWave && ducks.length === 0) { startNextWave(); } // Win condition - survive 10 waves if (waveNumber > 10) { LK.showYouWin(); } }; // Initialize first wave spawnDuck();
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bonus = Container.expand(function () {
var self = Container.call(this);
var bonusGraphics = self.attachAsset('Bonus', {
anchorX: 0.5,
anchorY: 0.5
});
bonusGraphics.scaleX = 0.3;
bonusGraphics.scaleY = 0.3;
self.fallSpeed = 3;
self.points = 50;
self.collected = false;
self.update = function () {
if (self.collected) return;
self.y += self.fallSpeed;
// Remove if it hits the ground
if (self.y > 2600) {
self.collected = true;
self.alpha = 0;
}
};
self.collect = function () {
if (self.collected) return false;
self.collected = true;
// Flash effect
LK.effects.flashObject(self, 0xFFFFFF, 200);
// Fade out animation
tween(self, {
alpha: 0,
scaleX: bonusGraphics.scaleX * 2,
scaleY: bonusGraphics.scaleY * 2
}, {
duration: 300,
easing: tween.easeOut
});
return true;
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.targetX = 0;
self.targetY = 0;
self.speed = 25;
self.travelled = 0;
self.maxDistance = 200;
self.update = function () {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5 && self.travelled < self.maxDistance) {
var moveX = dx / distance * self.speed;
var moveY = dy / distance * self.speed;
self.x += moveX;
self.y += moveY;
self.travelled += Math.sqrt(moveX * moveX + moveY * moveY);
} else {
self.alpha -= 0.1;
}
};
return self;
});
var Cloud = Container.expand(function () {
var self = Container.call(this);
var cloudGraphics = self.attachAsset('cloud', {
anchorX: 0.5,
anchorY: 0.5
});
cloudGraphics.alpha = 0.7;
self.speed = 0.5 + Math.random() * 1; // Random slow speed
self.direction = Math.random() < 0.5 ? 1 : -1; // Left or right
self.update = function () {
self.x += self.speed * self.direction;
// Reset position when off screen
if (self.direction > 0 && self.x > 2200) {
self.x = -200;
} else if (self.direction < 0 && self.x < -200) {
self.x = 2200;
}
};
return self;
});
var Crosshair = Container.expand(function () {
var self = Container.call(this);
var crosshairGraphics = self.attachAsset('crosshair', {
anchorX: 0.5,
anchorY: 0.5
});
crosshairGraphics.alpha = 0.7;
self.visible = false;
return self;
});
var Duck = Container.expand(function () {
var self = Container.call(this);
var duckGraphics = self.attachAsset('duck', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2 + Math.random() * 8; // Random speed between 2-10
self.direction = Math.random() < 0.5 ? 1 : -1; // Left or right
self.verticalSpeed = (Math.random() - 0.5) * 2; // Random vertical movement
self.isHit = false;
self.points = 60;
// Set initial position based on direction
if (self.direction > 0) {
self.x = -100;
// Duck moving right (from left side) should face left
duckGraphics.scaleX = -1;
} else {
self.x = 2148;
// Duck moving left (from right side) should face right
duckGraphics.scaleX = 1;
}
self.y = 300 + Math.random() * 1000; // Random height
self.update = function () {
if (self.isHit) return;
self.x += self.speed * self.direction;
self.y += self.verticalSpeed;
// Add some wobble to flight pattern
self.y += Math.sin(LK.ticks * 0.1 + self.x * 0.01) * 2;
// Keep ducks within screen bounds vertically
if (self.y < 200) {
self.y = 200;
self.verticalSpeed = Math.abs(self.verticalSpeed);
}
if (self.y > 2500) {
self.y = 2500;
self.verticalSpeed = -Math.abs(self.verticalSpeed);
}
};
self.hit = function () {
if (self.isHit) return false;
self.isHit = true;
LK.getSound('hit').play();
// Flash effect
LK.effects.flashObject(self, 0xFFFFFF, 300);
// Create floating points display
var pointsDisplay = new PointsDisplay();
pointsDisplay.x = self.x;
pointsDisplay.y = self.y - 50;
pointsDisplays.push(pointsDisplay);
game.addChild(pointsDisplay);
pointsDisplay.show(self.points);
// 30% chance to drop a bonus
if (Math.random() < 0.3) {
var bonus = new Bonus();
bonus.x = self.x;
bonus.y = self.y;
bonuses.push(bonus);
game.addChild(bonus);
}
// Fall down animation
tween(self, {
y: self.y + 200,
alpha: 0,
rotation: Math.PI
}, {
duration: 800,
easing: tween.easeIn
});
return true;
};
return self;
});
var Grass = Container.expand(function () {
var self = Container.call(this);
var grassGraphics = self.attachAsset('grass', {
anchorX: 0.5,
anchorY: 1.0
});
grassGraphics.alpha = 0.8;
return self;
});
var Hunter = Container.expand(function () {
var self = Container.call(this);
var hunterGraphics = self.attachAsset('hunters', {
anchorX: 0.5,
anchorY: 1.0
});
self.defaultY = 0;
self.shootOffset = -30;
self.isLookingRight = true;
self.shoot = function (targetX, targetY) {
// Determine which direction to look based on target (reversed)
var shouldLookRight = targetX < self.x;
if (shouldLookRight !== self.isLookingRight) {
self.isLookingRight = shouldLookRight;
// Flip hunter sprite
hunterGraphics.scaleX = shouldLookRight ? 1 : -1;
}
// Rotation effect removed - hunter no longer rotates to aim
// Enhanced hunter body recoil animation
tween(self, {
y: self.defaultY + 25,
x: self.x + (shouldLookRight ? -8 : 8) // Slight backward lean
}, {
duration: 100,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(self, {
y: self.defaultY,
x: 2048 / 2 // Return to center
}, {
duration: 250,
easing: tween.easeInOut
});
}
});
};
return self;
});
var PointsDisplay = Container.expand(function () {
var self = Container.call(this);
var pointsGraphics = self.attachAsset('points', {
anchorX: 0.5,
anchorY: 0.5
});
pointsGraphics.scaleX = 0.8;
pointsGraphics.scaleY = 0.8;
self.show = function (points) {
// Start animation - move upward and fade out
tween(self, {
y: self.y - 150,
alpha: 0,
scaleX: pointsGraphics.scaleX * 1.5,
scaleY: pointsGraphics.scaleY * 1.5
}, {
duration: 1500,
easing: tween.easeOut
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87CEEB
});
/****
* Game Code
****/
var ducks = [];
var bullets = [];
var bonuses = [];
var clouds = [];
var pointsDisplays = [];
var crosshair = null;
var missedDucks = 0;
var maxMissedDucks = 5;
var consecutiveHits = 0;
var waveNumber = 1;
var ducksInWave = 3;
var ducksSpawned = 0;
var waveTimer = 0;
// UI Elements
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var missedTxt = new Text2('Missed: 0/5', {
size: 60,
fill: 0xFF0000
});
missedTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(missedTxt);
var waveTxt = new Text2('Wave: 1', {
size: 60,
fill: 0x00FF00
});
waveTxt.anchor.set(0, 0);
waveTxt.x = 150; // Offset from top-left to avoid menu
waveTxt.y = 50;
LK.gui.topLeft.addChild(waveTxt);
// Create crosshair
crosshair = game.addChild(new Crosshair());
// Create hunter positioned at bottom center
var hunter = game.addChild(new Hunter());
hunter.x = 2048 / 2;
hunter.y = 2732 - 50;
hunter.defaultY = hunter.y;
// Create grass across the entire bottom of the screen
var grassObjects = [];
var grassWidth = 400; // Width of each grass asset
var numGrassObjects = Math.ceil(2048 / grassWidth) + 1; // Cover full width plus some overlap
for (var g = 0; g < numGrassObjects; g++) {
var grass = game.addChild(new Grass());
grass.x = g * (grassWidth * 0.8); // Slight overlap between grass objects
grass.y = 2732 - 30;
grassObjects.push(grass);
}
// Create clouds at top of screen
for (var c = 0; c < 4; c++) {
var cloud = game.addChild(new Cloud());
cloud.x = 200 + c * 500 + Math.random() * 200; // Spread across screen width
cloud.y = 100 + Math.random() * 150; // Random height at top
clouds.push(cloud);
}
function spawnDuck() {
var duck = new Duck();
// Adjust speed based on wave
duck.speed += waveNumber * 0.5;
duck.points = 60 + waveNumber * 10; // Base 60 points plus wave bonus
ducks.push(duck);
game.addChild(duck);
ducksSpawned++;
}
function updateScore() {
scoreTxt.setText('Score: ' + LK.getScore());
}
function updateMissed() {
missedTxt.setText('Missed: ' + missedDucks + '/' + maxMissedDucks);
}
function updateWave() {
waveTxt.setText('Wave: ' + waveNumber);
}
function checkHit(x, y) {
var hitDuck = null;
var minDistance = 100; // Hit radius
for (var i = 0; i < ducks.length; i++) {
var duck = ducks[i];
if (duck.isHit) continue;
var dx = duck.x - x;
var dy = duck.y - y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < minDistance) {
minDistance = distance;
hitDuck = duck;
}
}
return hitDuck;
}
function startNextWave() {
waveNumber++;
ducksSpawned = 0;
ducksInWave = Math.min(3 + Math.floor(waveNumber / 2), 8); // Max 8 ducks per wave
waveTimer = 0;
updateWave();
}
// Game controls
var mouseX = 2048 / 2;
var mouseY = 2732 / 2;
game.move = function (x, y, obj) {
// Update mouse position continuously
mouseX = x;
mouseY = y;
};
game.down = function (x, y, obj) {
// Update mouse position
mouseX = x;
mouseY = y;
// Show crosshair
crosshair.x = x;
crosshair.y = y;
crosshair.visible = true;
// Move crosshair to front to ensure it appears above ducks
game.removeChild(crosshair);
game.addChild(crosshair);
// Create bullet
var bullet = new Bullet();
bullet.x = x;
bullet.y = y;
bullet.targetX = x;
bullet.targetY = y;
bullets.push(bullet);
game.addChild(bullet);
// Play shoot sound
LK.getSound('shoot').play();
// Trigger hunter shooting animation
hunter.shoot(x, y);
// Check for bonus collection
var hitBonus = null;
var minBonusDistance = 80;
for (var b = 0; b < bonuses.length; b++) {
var bonus = bonuses[b];
if (bonus.collected) continue;
var bdx = bonus.x - x;
var bdy = bonus.y - y;
var bonusDistance = Math.sqrt(bdx * bdx + bdy * bdy);
if (bonusDistance < minBonusDistance) {
minBonusDistance = bonusDistance;
hitBonus = bonus;
}
}
if (hitBonus && hitBonus.collect()) {
LK.setScore(LK.getScore() + hitBonus.points);
updateScore();
}
// Check for hit
var hitDuck = checkHit(x, y);
if (hitDuck) {
if (hitDuck.hit()) {
consecutiveHits++;
var points = 60; // Fixed 60 points per duck
// Bonus for consecutive hits
if (consecutiveHits > 1) {
points += consecutiveHits * 10;
}
LK.setScore(LK.getScore() + points);
updateScore();
}
} else {
consecutiveHits = 0;
LK.getSound('miss').play();
}
// Hide crosshair after short delay
LK.setTimeout(function () {
crosshair.visible = false;
}, 100);
};
game.update = function () {
// Update hunter facing direction based on mouse (reversed)
var hunterGraphics = hunter.children[0]; // Hunter graphics is first child
var shouldLookRight = mouseX < hunter.x;
if (shouldLookRight !== hunter.isLookingRight) {
hunter.isLookingRight = shouldLookRight;
// Flip hunter sprite
hunterGraphics.scaleX = shouldLookRight ? 1 : -1;
}
waveTimer++;
// Spawn ducks for current wave
if (ducksSpawned < ducksInWave && waveTimer % 120 === 0) {
// Spawn every 2 seconds
spawnDuck();
}
// Update and remove off-screen ducks
for (var i = ducks.length - 1; i >= 0; i--) {
var duck = ducks[i];
if (duck.lastX === undefined) duck.lastX = duck.x;
if (duck.lastOffScreen === undefined) duck.lastOffScreen = false;
var currentOffScreen = duck.x < -150 || duck.x > 2198;
// Check if duck just went off screen
if (!duck.lastOffScreen && currentOffScreen && !duck.isHit) {
missedDucks++;
updateMissed();
consecutiveHits = 0;
if (missedDucks >= maxMissedDucks) {
LK.showGameOver();
return;
}
}
// Remove duck if it's been off screen for a while or hit and faded
if (currentOffScreen && (duck.lastOffScreen || duck.isHit) || duck.alpha <= 0) {
duck.destroy();
ducks.splice(i, 1);
} else {
duck.lastX = duck.x;
duck.lastOffScreen = currentOffScreen;
}
}
// Update and remove bullets
for (var j = bullets.length - 1; j >= 0; j--) {
var bullet = bullets[j];
if (bullet.alpha <= 0) {
bullet.destroy();
bullets.splice(j, 1);
}
}
// Update and remove bonuses
for (var k = bonuses.length - 1; k >= 0; k--) {
var bonus = bonuses[k];
if (bonus.alpha <= 0 || bonus.collected) {
bonus.destroy();
bonuses.splice(k, 1);
}
}
// Update and remove points displays
for (var p = pointsDisplays.length - 1; p >= 0; p--) {
var pointsDisplay = pointsDisplays[p];
if (pointsDisplay.alpha <= 0) {
pointsDisplay.destroy();
pointsDisplays.splice(p, 1);
}
}
// Check if wave is complete
if (ducksSpawned >= ducksInWave && ducks.length === 0) {
startNextWave();
}
// Win condition - survive 10 waves
if (waveNumber > 10) {
LK.showYouWin();
}
};
// Initialize first wave
spawnDuck();
Flying Duck. In-Game asset. 2d. High contrast. No shadows
Bomb effect. In-Game asset. 2d. High contrast. No shadows
Bullet. In-Game asset. 2d. High contrast. No shadows
grass. In-Game asset. 2d. High contrast. No shadows
Duck hunter gun. In-Game asset. 2d. High contrast. No shadows
Duck hunter without gun from behind of him. In-Game asset. 2d. High contrast. No shadows
Silahını yukarı doğrultup nişan almış bir ördek avcısının arkadan görünüşünü çiz. In-Game asset. 2d. High contrast. No shadows
cloud. In-Game asset. 2d. High contrast. No shadows
Bonus coin. In-Game asset. 2d. High contrast. No shadows