User prompt
Please fix the bug: 'Uncaught TypeError: Cannot set properties of undefined (setting 'fill')' in or related to this line: 'txt.style.fill = color || 0xFFD700;' Line Number: 42
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'size')' in or related to this line: 'scoreText.style.size = 90 * scale;' Line Number: 311
User prompt
🕹️ Gameplay Improvements: Fix Duck Collision Issue in Level 3: Ducks in Level 3 must be hittable just like in earlier levels. Make sure hitboxes are accurate and responsive. Progressive Levels: Add at least 5 levels with increasing difficulty. Ducks move faster and in bigger groups as levels progress. Add a Score System: Show a score counter at the top. +10 points per duck hit. Show final score on "Level Complete" or "Game Over" screen. Add Limited Ammo: Each level has a set number of bullets (e.g., 5–10). Display remaining bullets on screen. Add a reload animation or sound if all bullets are used. Add Timer: Each level should have a countdown timer. If the timer runs out, the level ends. Encourage fast and accurate shooting. 🐶 Retro Dog Animation: Dog Celebrates After Each Duck Hit: Show a retro pixel dog pop up and celebrate when a duck is hit. Dog lifts the duck in its mouth or laughs happily. Add retro-style bark sound effect. 📱 Mobile Optimization: Touch Controls: Make sure the game works smoothly on phones and tablets. Tap anywhere to shoot; make the tap area responsive. Responsive UI: Score, bullets, and timer should resize properly on mobile screens. 🎨 Visual & Audio Polish: Retro Background Music: Add looping 8-bit background music that matches the arcade style. Use sound effects for duck flaps, shots, dog barks, and duck falls. Variety of Ducks: Add different duck types (normal, fast, golden). Golden duck = rare, faster, gives +50 points. 🧠 Bonus Features: Headshot Bonus: If the player hits the head of the duck, award extra points (+5 bonus). Achievements / Milestones: Show simple pop-ups like "Nice Shot!", "Triple Hit!", or "Sharp Shooter!" to reward good performance. Start Menu & Restart Button: Add a start screen with "Play", "How to Play", and "High Scores". Include a restart option after game over. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
level text must be under the high score text
User prompt
level text should be middle in screen
User prompt
separate level text and high score text
User prompt
can you update my game link so users can see my games last version
User prompt
🔧 Check and Fix the Following: Collision Detection / Hitbox: Make sure the ducks in Level 3 have the same hitbox size and position as ducks in Levels 1 and 2. Adjust the hitbox to cover the full duck sprite (not just a tiny part). Click/Tap Registration: Ensure that player taps/clicks are properly registered on fast-moving ducks. Use a slightly larger hit area for fast ducks to make them easier to hit. Speed Adjustment (if needed): If ducks in Level 3 are too fast, reduce their speed slightly so players have a fair chance to react. Z-Index / Layering: Make sure ducks are not behind other UI elements or invisible layers that block interaction. Ducks must be on the topmost clickable layer. Consistency: Apply the same shooting logic from Level 1 and 2 to all ducks in Level 3. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
when ı shot the ducks game end fix this
User prompt
1. Game Ends After One Duck Is Shot – FIX THIS: Do not end the game when a duck is hit. Instead, when a duck is shot: Add +10 points to the score. Play a short “duck hit” animation and sound. Let the duck fall to the ground and disappear. The game should only end: When the player runs out of time. Or after missing too many ducks. Or after completing all levels. 🐶 2. Add Duck Retriever Dog Animation: After a duck is shot and falls to the ground: Show a retro-style dog popping up from the bottom of the screen. The dog should hold the duck in its mouth or raise it proudly (like in Duck Hunt). Play a short celebration animation (2–3 seconds). Optional: Add a bark or celebration sound. Dog Animation Details: Pixel art (8-bit or 16-bit style). Only appears after a duck is shot. Stays on screen for a short time, then disappears.
User prompt
🎯 1. Duck Speed and Spawn Rate (Too Fast at Start): Ducks should appear one at a time in Level 1. In Level 1, ducks should move slowly (slow flight speed). Starting from Level 2, ducks can start appearing more frequently and faster, with speed increasing slightly each level. Duck spawn schedule per level: Level 1: One duck every 3 seconds, max 5 ducks, slow speed. Level 2: One duck every 2 seconds, max 8 ducks, medium speed. Level 3: Two ducks at a time every 2 seconds, max 12 ducks, faster. Level 4+: Three ducks at a time every 1.5 seconds, max 15 ducks, fast speed. 🧮 2. Add a Scoring System: Add a visible Score counter at the top of the screen. Each duck hit = +10 points. Missing a duck = no points, but does not subtract. Show final score on “Game Over” and “Level Complete” screens. 🪙 3. Optional: Bonus Points Hitting 3 ducks in a row without missing = Bonus +20 points. Hitting a rare "golden duck" (optional) = +50 points. 📱 4. Make sure the game works smoothly on mobile: Touch controls must be responsive. Game elements should be scaled and centered correctly on small screens. Shooting should work by tapping the screen anywhere. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
Code edit (1 edits merged)
Please save this source code
User prompt
Retro Duck Shooter
Initial prompt
Game Title: Retro Duck Shooter Gameplay Overview: The player is a hunter who must shoot flying ducks on the screen using a tap (mobile) or mouse click (desktop). Ducks appear from the sides or bottom of the screen and fly in random directions. The player must shoot a certain number of ducks within a time limit to proceed to the next level. If the player misses too many ducks, the game ends. The game includes multiple levels with increasing difficulty (speed of ducks, number of ducks, etc.). Controls: Mobile: Tap anywhere on the screen to shoot. Desktop: Click anywhere with the mouse to shoot. Only one shot per tap/click. Limited number of bullets per round (e.g., 3 shots per wave). Game Elements: 1. Player Gun: Static crosshair or moving scope that follows tap/click. Retro pixel-art shotgun sound when fired. 2. Ducks: Different colored ducks (yellow, red, blue). Ducks fly with flapping animation in random directions and speeds. Some ducks fly faster (harder to hit). Ducks make a flapping sound and fall down with a funny animation when shot. 3. Dog (optional, like in original Duck Hunt): Appears at the bottom of the screen to laugh if player misses. Pops up with a laugh animation and sound. Optional: dog picks up ducks that fall. 4. UI Elements: Score counter (ducks hit). Bullet counter (number of shots remaining). Timer for each level (e.g., 30 seconds). "Level Complete" and "Game Over" screens. Retro 8-bit style fonts and buttons. 5. Levels: Level 1: 5 ducks, slow speed, 3 bullets per wave. Level 2: 7 ducks, medium speed, 3 bullets per wave. Level 3: 10 ducks, fast speed, 3 bullets per wave. Add up to 5 levels or more, with difficulty increasing each time. After final level, show “You Win!” screen. 6. Sound Effects: Shooting sound (retro pixel shotgun). Duck flapping and falling. Dog laughing. Level start and complete sound jingles. 7. Graphics Style: All sprites should be retro-style pixel art (8-bit or 16-bit). Use an old-school Atari color palette. Background can be a blue sky with pixelated trees or grass. 8. Game Logic: Player must hit at least 70% of ducks to pass each level. If player runs out of bullets or misses too many ducks, show “Game Over”. Add a restart option. Save the highest score (local storage). Additional Notes: Ensure the game scales properly on mobile screen sizes (responsive layout). Use touch-friendly controls and optimize for performance on mobile. Include a simple main menu with “Start Game” button.
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { highScore: 0 }); /**** * Classes ****/ // Dog class var Dog = Container.expand(function () { var self = Container.call(this); var dogAsset = self.attachAsset('dog', { anchorX: 0.5, anchorY: 1 }); self.visible = false; // Show dog at (x, y) self.show = function (x, y) { self.x = x; self.y = y; self.visible = true; dogAsset.visible = true; }; // Hide dog self.hide = function () { self.visible = false; dogAsset.visible = false; }; // Show laugh animation self.laugh = function (x, y) { self.x = x; self.y = y; self.visible = true; dogAsset.visible = false; if (!self.laughAsset) { self.laughAsset = self.attachAsset('dog_laugh', { anchorX: 0.5, anchorY: 1 }); } self.laughAsset.visible = true; LK.getSound('dog_laugh').play(); // Hide after 1.2s LK.setTimeout(function () { self.laughAsset.visible = false; self.hide(); }, 1200); }; return self; }); // Duck class var Duck = Container.expand(function () { var self = Container.call(this); // Choose color randomly var duckColors = ['duck_green', 'duck_blue', 'duck_red']; var colorIdx = Math.floor(Math.random() * duckColors.length); var duckAsset = self.attachAsset(duckColors[colorIdx], { anchorX: 0.5, anchorY: 0.5 }); // Set initial position and movement self.speed = 6 + Math.random() * 4; // Will be set by level self.angle = 0; // radians, will be set by level self.alive = true; self.hit = false; self.escaped = false; // For animation self.flyTween = null; // Called every tick self.update = function () { if (!self.alive) return; self.x += Math.cos(self.angle) * self.speed; self.y += Math.sin(self.angle) * self.speed; // If out of bounds, mark as escaped if (self.x < -100 || self.x > 2048 + 100 || self.y < -100 || self.y > 2732 + 100) { self.escaped = true; self.alive = false; } }; // Animate duck falling when hit self.fall = function (_onFinish) { self.alive = false; self.hit = true; tween(self, { rotation: Math.PI * 1.5, y: self.y + 400 }, { duration: 700, easing: tween.cubicIn, onFinish: function onFinish() { if (_onFinish) _onFinish(); } }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x87ceeb // sky blue }); /**** * Game Code ****/ // Music // Sounds // sky blue // Ducks: 3 colors, 1 dog, 1 bullet, 1 background, 1 crosshair, 1 "laugh" dog // Game state variables var ducks = []; var bullets = []; var level = 1; var ducksPerLevel = 5; var ducksToHit = 0; var ducksHit = 0; var ducksEscaped = 0; var maxBullets = 3; var bulletsLeft = 3; var timeLimit = 15; // seconds var timeLeft = 15; var gameActive = false; var waveActive = false; var highScore = storage.highScore || 0; var dog = null; var crosshair = null; var timerInterval = null; var levelText = null; var scoreText = null; var timerText = null; var bulletIcons = []; var waveResultTimeout = null; // Background var bg = LK.getAsset('bg', { anchorX: 0, anchorY: 0, x: 0, y: 0 }); game.addChild(bg); // Dog dog = new Dog(); game.addChild(dog); // Crosshair crosshair = LK.getAsset('crosshair', { anchorX: 0.5, anchorY: 0.5, x: 1024, y: 1366 }); crosshair.visible = false; game.addChild(crosshair); // GUI: Level, Score, Timer, Bullets levelText = new Text2('Level 1', { size: 90, fill: 0xFFF000 }); levelText.anchor.set(0.5, 0); LK.gui.top.addChild(levelText); scoreText = new Text2('Score: 0', { size: 90, fill: 0xFFFFFF }); scoreText.anchor.set(0.5, 0); LK.gui.top.addChild(scoreText); timerText = new Text2('Time: 15', { size: 90, fill: 0xFFFFFF }); timerText.anchor.set(0.5, 0); LK.gui.top.addChild(timerText); // Position GUI levelText.x = 2048 / 4; scoreText.x = 2048 / 2; timerText.x = 2048 * 3 / 4; // Bullets GUI (bottom left, avoid top left 100x100) function updateBulletIcons() { // Remove old for (var i = 0; i < bulletIcons.length; i++) { if (bulletIcons[i].parent) bulletIcons[i].parent.removeChild(bulletIcons[i]); } bulletIcons = []; // Draw new for (var i = 0; i < bulletsLeft; i++) { var icon = LK.getAsset('bullet_icon', { anchorX: 0.5, anchorY: 0.5, x: 80 + i * 60, y: 2732 - 120 }); LK.gui.bottomLeft.addChild(icon); bulletIcons.push(icon); } } // Start a new level function startLevel() { ducks = []; bullets = []; ducksHit = 0; ducksEscaped = 0; ducksPerLevel = 5 + (level - 1) * 2; ducksToHit = Math.ceil(ducksPerLevel * 0.7); maxBullets = Math.max(3, Math.ceil(ducksPerLevel * 1.2)); bulletsLeft = maxBullets; timeLimit = Math.max(8, 15 - (level - 1)); timeLeft = timeLimit; gameActive = true; waveActive = true; updateBulletIcons(); levelText.setText('Level ' + level); scoreText.setText('Score: ' + highScore); timerText.setText('Time: ' + timeLeft); // Spawn ducks for (var i = 0; i < ducksPerLevel; i++) { var duck = new Duck(); // Randomize start edge: 0=left, 1=right, 2=bottom var edge = Math.floor(Math.random() * 3); var startX, startY, angle; if (edge === 0) { // left startX = -60; startY = 400 + Math.random() * (2732 - 800); angle = Math.random() * Math.PI / 3 - Math.PI / 6; // -30 to +30 deg } else if (edge === 1) { // right startX = 2048 + 60; startY = 400 + Math.random() * (2732 - 800); angle = Math.PI + (Math.random() * Math.PI / 3 - Math.PI / 6); // 150 to 210 deg } else { // bottom startX = 200 + Math.random() * (2048 - 400); startY = 2732 + 60; angle = -Math.PI / 2 + (Math.random() * Math.PI / 4 - Math.PI / 8); // -67 to -23 deg } duck.x = startX; duck.y = startY; duck.angle = angle; duck.speed = 6 + Math.random() * (2 + level * 0.7); ducks.push(duck); game.addChild(duck); LK.getSound('duck_fly').play(); } // Start timer if (timerInterval) LK.clearInterval(timerInterval); timerInterval = LK.setInterval(function () { if (!gameActive) return; timeLeft--; timerText.setText('Time: ' + timeLeft); if (timeLeft <= 0) { endWave(); } }, 1000); } // End wave: check results, show dog if needed, advance or game over function endWave() { if (!waveActive) return; waveActive = false; gameActive = false; if (timerInterval) LK.clearInterval(timerInterval); // Remove remaining ducks for (var i = 0; i < ducks.length; i++) { if (ducks[i].parent) ducks[i].parent.removeChild(ducks[i]); } ducks = []; // Show dog if not enough ducks hit if (ducksHit < ducksToHit) { dog.laugh(2048 / 2, 2732 - 100); LK.effects.flashScreen(0xff0000, 800); // Game over after laugh waveResultTimeout = LK.setTimeout(function () { LK.showGameOver(); }, 1300); } else { // Advance to next level after short pause LK.effects.flashObject(levelText, 0x00ff00, 700); waveResultTimeout = LK.setTimeout(function () { level++; startLevel(); }, 900); } } // Handle tap/click to shoot game.down = function (x, y, obj) { if (!gameActive || !waveActive) return; // Don't allow shooting if out of bullets if (bulletsLeft <= 0) { LK.getSound('miss').play(); LK.effects.flashScreen(0x888888, 200); return; } bulletsLeft--; updateBulletIcons(); LK.getSound('shoot').play(); // Show crosshair at tap crosshair.x = x; crosshair.y = y; crosshair.visible = true; tween(crosshair, { alpha: 0 }, { duration: 200, onFinish: function onFinish() { crosshair.visible = false; crosshair.alpha = 1; } }); // Check if a duck is hit (closest duck under tap, not already hit) var hitDuck = null; var minDist = 99999; for (var i = 0; i < ducks.length; i++) { var duck = ducks[i]; if (!duck.alive) continue; var dx = duck.x - x; var dy = duck.y - y; var dist = Math.sqrt(dx * dx + dy * dy); if (dist < 80 && dist < minDist) { minDist = dist; hitDuck = duck; } } if (hitDuck) { hitDuck.fall(function () { if (hitDuck.parent) hitDuck.parent.removeChild(hitDuck); }); ducksHit++; LK.getSound('hit').play(); LK.effects.flashObject(hitDuck, 0xffff00, 300); // Update high score if (ducksHit > highScore) { highScore = ducksHit; storage.highScore = highScore; } scoreText.setText('Score: ' + highScore); } else { LK.getSound('miss').play(); LK.effects.flashScreen(0x888888, 120); } // If all ducks shot or out of bullets, end wave var aliveDucks = 0; for (var i = 0; i < ducks.length; i++) { if (ducks[i].alive) aliveDucks++; } if (aliveDucks === 0 || bulletsLeft === 0) { endWave(); } }; // Move handler for crosshair (optional, for desktop) game.move = function (x, y, obj) { // Optionally show crosshair following finger/mouse // crosshair.x = x; // crosshair.y = y; }; // Main update loop game.update = function () { if (!gameActive || !waveActive) return; // Update ducks for (var i = ducks.length - 1; i >= 0; i--) { var duck = ducks[i]; duck.update(); if (duck.escaped && !duck.hit) { ducksEscaped++; if (duck.parent) duck.parent.removeChild(duck); ducks.splice(i, 1); } } // If all ducks gone, end wave var aliveDucks = 0; for (var i = 0; i < ducks.length; i++) { if (ducks[i].alive) aliveDucks++; } if (aliveDucks === 0) { endWave(); } }; // On game over, reset everything LK.on('gameover', function () { if (timerInterval) LK.clearInterval(timerInterval); if (waveResultTimeout) LK.clearTimeout(waveResultTimeout); gameActive = false; waveActive = false; level = 1; ducks = []; bullets = []; ducksHit = 0; ducksEscaped = 0; bulletsLeft = 3; updateBulletIcons(); levelText.setText('Level 1'); scoreText.setText('Score: ' + highScore); timerText.setText('Time: 15'); if (dog) dog.hide(); // Start again after short delay LK.setTimeout(function () { startLevel(); }, 1200); }); // On you win (if you want to add a win condition, e.g. after level 10) LK.on('youwin', function () { if (timerInterval) LK.clearInterval(timerInterval); if (waveResultTimeout) LK.clearTimeout(waveResultTimeout); gameActive = false; waveActive = false; // Show win, then reset LK.setTimeout(function () { level = 1; ducks = []; bullets = []; ducksHit = 0; ducksEscaped = 0; bulletsLeft = 3; updateBulletIcons(); levelText.setText('Level 1'); scoreText.setText('Score: ' + highScore); timerText.setText('Time: 15'); if (dog) dog.hide(); startLevel(); }, 1800); }); // Start music LK.playMusic('bgm', { fade: { start: 0, end: 0.5, duration: 1200 } }); // Start first level startLevel();
===================================================================
--- original.js
+++ change.js
@@ -1,6 +1,433 @@
-/****
+/****
+* Plugins
+****/
+var tween = LK.import("@upit/tween.v1");
+var storage = LK.import("@upit/storage.v1", {
+ highScore: 0
+});
+
+/****
+* Classes
+****/
+// Dog class
+var Dog = Container.expand(function () {
+ var self = Container.call(this);
+ var dogAsset = self.attachAsset('dog', {
+ anchorX: 0.5,
+ anchorY: 1
+ });
+ self.visible = false;
+ // Show dog at (x, y)
+ self.show = function (x, y) {
+ self.x = x;
+ self.y = y;
+ self.visible = true;
+ dogAsset.visible = true;
+ };
+ // Hide dog
+ self.hide = function () {
+ self.visible = false;
+ dogAsset.visible = false;
+ };
+ // Show laugh animation
+ self.laugh = function (x, y) {
+ self.x = x;
+ self.y = y;
+ self.visible = true;
+ dogAsset.visible = false;
+ if (!self.laughAsset) {
+ self.laughAsset = self.attachAsset('dog_laugh', {
+ anchorX: 0.5,
+ anchorY: 1
+ });
+ }
+ self.laughAsset.visible = true;
+ LK.getSound('dog_laugh').play();
+ // Hide after 1.2s
+ LK.setTimeout(function () {
+ self.laughAsset.visible = false;
+ self.hide();
+ }, 1200);
+ };
+ return self;
+});
+// Duck class
+var Duck = Container.expand(function () {
+ var self = Container.call(this);
+ // Choose color randomly
+ var duckColors = ['duck_green', 'duck_blue', 'duck_red'];
+ var colorIdx = Math.floor(Math.random() * duckColors.length);
+ var duckAsset = self.attachAsset(duckColors[colorIdx], {
+ anchorX: 0.5,
+ anchorY: 0.5
+ });
+ // Set initial position and movement
+ self.speed = 6 + Math.random() * 4; // Will be set by level
+ self.angle = 0; // radians, will be set by level
+ self.alive = true;
+ self.hit = false;
+ self.escaped = false;
+ // For animation
+ self.flyTween = null;
+ // Called every tick
+ self.update = function () {
+ if (!self.alive) return;
+ self.x += Math.cos(self.angle) * self.speed;
+ self.y += Math.sin(self.angle) * self.speed;
+ // If out of bounds, mark as escaped
+ if (self.x < -100 || self.x > 2048 + 100 || self.y < -100 || self.y > 2732 + 100) {
+ self.escaped = true;
+ self.alive = false;
+ }
+ };
+ // Animate duck falling when hit
+ self.fall = function (_onFinish) {
+ self.alive = false;
+ self.hit = true;
+ tween(self, {
+ rotation: Math.PI * 1.5,
+ y: self.y + 400
+ }, {
+ duration: 700,
+ easing: tween.cubicIn,
+ onFinish: function onFinish() {
+ if (_onFinish) _onFinish();
+ }
+ });
+ };
+ return self;
+});
+
+/****
* Initialize Game
-****/
+****/
var game = new LK.Game({
- backgroundColor: 0x000000
-});
\ No newline at end of file
+ backgroundColor: 0x87ceeb // sky blue
+});
+
+/****
+* Game Code
+****/
+// Music
+// Sounds
+// sky blue
+// Ducks: 3 colors, 1 dog, 1 bullet, 1 background, 1 crosshair, 1 "laugh" dog
+// Game state variables
+var ducks = [];
+var bullets = [];
+var level = 1;
+var ducksPerLevel = 5;
+var ducksToHit = 0;
+var ducksHit = 0;
+var ducksEscaped = 0;
+var maxBullets = 3;
+var bulletsLeft = 3;
+var timeLimit = 15; // seconds
+var timeLeft = 15;
+var gameActive = false;
+var waveActive = false;
+var highScore = storage.highScore || 0;
+var dog = null;
+var crosshair = null;
+var timerInterval = null;
+var levelText = null;
+var scoreText = null;
+var timerText = null;
+var bulletIcons = [];
+var waveResultTimeout = null;
+// Background
+var bg = LK.getAsset('bg', {
+ anchorX: 0,
+ anchorY: 0,
+ x: 0,
+ y: 0
+});
+game.addChild(bg);
+// Dog
+dog = new Dog();
+game.addChild(dog);
+// Crosshair
+crosshair = LK.getAsset('crosshair', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 1024,
+ y: 1366
+});
+crosshair.visible = false;
+game.addChild(crosshair);
+// GUI: Level, Score, Timer, Bullets
+levelText = new Text2('Level 1', {
+ size: 90,
+ fill: 0xFFF000
+});
+levelText.anchor.set(0.5, 0);
+LK.gui.top.addChild(levelText);
+scoreText = new Text2('Score: 0', {
+ size: 90,
+ fill: 0xFFFFFF
+});
+scoreText.anchor.set(0.5, 0);
+LK.gui.top.addChild(scoreText);
+timerText = new Text2('Time: 15', {
+ size: 90,
+ fill: 0xFFFFFF
+});
+timerText.anchor.set(0.5, 0);
+LK.gui.top.addChild(timerText);
+// Position GUI
+levelText.x = 2048 / 4;
+scoreText.x = 2048 / 2;
+timerText.x = 2048 * 3 / 4;
+// Bullets GUI (bottom left, avoid top left 100x100)
+function updateBulletIcons() {
+ // Remove old
+ for (var i = 0; i < bulletIcons.length; i++) {
+ if (bulletIcons[i].parent) bulletIcons[i].parent.removeChild(bulletIcons[i]);
+ }
+ bulletIcons = [];
+ // Draw new
+ for (var i = 0; i < bulletsLeft; i++) {
+ var icon = LK.getAsset('bullet_icon', {
+ anchorX: 0.5,
+ anchorY: 0.5,
+ x: 80 + i * 60,
+ y: 2732 - 120
+ });
+ LK.gui.bottomLeft.addChild(icon);
+ bulletIcons.push(icon);
+ }
+}
+// Start a new level
+function startLevel() {
+ ducks = [];
+ bullets = [];
+ ducksHit = 0;
+ ducksEscaped = 0;
+ ducksPerLevel = 5 + (level - 1) * 2;
+ ducksToHit = Math.ceil(ducksPerLevel * 0.7);
+ maxBullets = Math.max(3, Math.ceil(ducksPerLevel * 1.2));
+ bulletsLeft = maxBullets;
+ timeLimit = Math.max(8, 15 - (level - 1));
+ timeLeft = timeLimit;
+ gameActive = true;
+ waveActive = true;
+ updateBulletIcons();
+ levelText.setText('Level ' + level);
+ scoreText.setText('Score: ' + highScore);
+ timerText.setText('Time: ' + timeLeft);
+ // Spawn ducks
+ for (var i = 0; i < ducksPerLevel; i++) {
+ var duck = new Duck();
+ // Randomize start edge: 0=left, 1=right, 2=bottom
+ var edge = Math.floor(Math.random() * 3);
+ var startX, startY, angle;
+ if (edge === 0) {
+ // left
+ startX = -60;
+ startY = 400 + Math.random() * (2732 - 800);
+ angle = Math.random() * Math.PI / 3 - Math.PI / 6; // -30 to +30 deg
+ } else if (edge === 1) {
+ // right
+ startX = 2048 + 60;
+ startY = 400 + Math.random() * (2732 - 800);
+ angle = Math.PI + (Math.random() * Math.PI / 3 - Math.PI / 6); // 150 to 210 deg
+ } else {
+ // bottom
+ startX = 200 + Math.random() * (2048 - 400);
+ startY = 2732 + 60;
+ angle = -Math.PI / 2 + (Math.random() * Math.PI / 4 - Math.PI / 8); // -67 to -23 deg
+ }
+ duck.x = startX;
+ duck.y = startY;
+ duck.angle = angle;
+ duck.speed = 6 + Math.random() * (2 + level * 0.7);
+ ducks.push(duck);
+ game.addChild(duck);
+ LK.getSound('duck_fly').play();
+ }
+ // Start timer
+ if (timerInterval) LK.clearInterval(timerInterval);
+ timerInterval = LK.setInterval(function () {
+ if (!gameActive) return;
+ timeLeft--;
+ timerText.setText('Time: ' + timeLeft);
+ if (timeLeft <= 0) {
+ endWave();
+ }
+ }, 1000);
+}
+// End wave: check results, show dog if needed, advance or game over
+function endWave() {
+ if (!waveActive) return;
+ waveActive = false;
+ gameActive = false;
+ if (timerInterval) LK.clearInterval(timerInterval);
+ // Remove remaining ducks
+ for (var i = 0; i < ducks.length; i++) {
+ if (ducks[i].parent) ducks[i].parent.removeChild(ducks[i]);
+ }
+ ducks = [];
+ // Show dog if not enough ducks hit
+ if (ducksHit < ducksToHit) {
+ dog.laugh(2048 / 2, 2732 - 100);
+ LK.effects.flashScreen(0xff0000, 800);
+ // Game over after laugh
+ waveResultTimeout = LK.setTimeout(function () {
+ LK.showGameOver();
+ }, 1300);
+ } else {
+ // Advance to next level after short pause
+ LK.effects.flashObject(levelText, 0x00ff00, 700);
+ waveResultTimeout = LK.setTimeout(function () {
+ level++;
+ startLevel();
+ }, 900);
+ }
+}
+// Handle tap/click to shoot
+game.down = function (x, y, obj) {
+ if (!gameActive || !waveActive) return;
+ // Don't allow shooting if out of bullets
+ if (bulletsLeft <= 0) {
+ LK.getSound('miss').play();
+ LK.effects.flashScreen(0x888888, 200);
+ return;
+ }
+ bulletsLeft--;
+ updateBulletIcons();
+ LK.getSound('shoot').play();
+ // Show crosshair at tap
+ crosshair.x = x;
+ crosshair.y = y;
+ crosshair.visible = true;
+ tween(crosshair, {
+ alpha: 0
+ }, {
+ duration: 200,
+ onFinish: function onFinish() {
+ crosshair.visible = false;
+ crosshair.alpha = 1;
+ }
+ });
+ // Check if a duck is hit (closest duck under tap, not already hit)
+ var hitDuck = null;
+ var minDist = 99999;
+ for (var i = 0; i < ducks.length; i++) {
+ var duck = ducks[i];
+ if (!duck.alive) continue;
+ var dx = duck.x - x;
+ var dy = duck.y - y;
+ var dist = Math.sqrt(dx * dx + dy * dy);
+ if (dist < 80 && dist < minDist) {
+ minDist = dist;
+ hitDuck = duck;
+ }
+ }
+ if (hitDuck) {
+ hitDuck.fall(function () {
+ if (hitDuck.parent) hitDuck.parent.removeChild(hitDuck);
+ });
+ ducksHit++;
+ LK.getSound('hit').play();
+ LK.effects.flashObject(hitDuck, 0xffff00, 300);
+ // Update high score
+ if (ducksHit > highScore) {
+ highScore = ducksHit;
+ storage.highScore = highScore;
+ }
+ scoreText.setText('Score: ' + highScore);
+ } else {
+ LK.getSound('miss').play();
+ LK.effects.flashScreen(0x888888, 120);
+ }
+ // If all ducks shot or out of bullets, end wave
+ var aliveDucks = 0;
+ for (var i = 0; i < ducks.length; i++) {
+ if (ducks[i].alive) aliveDucks++;
+ }
+ if (aliveDucks === 0 || bulletsLeft === 0) {
+ endWave();
+ }
+};
+// Move handler for crosshair (optional, for desktop)
+game.move = function (x, y, obj) {
+ // Optionally show crosshair following finger/mouse
+ // crosshair.x = x;
+ // crosshair.y = y;
+};
+// Main update loop
+game.update = function () {
+ if (!gameActive || !waveActive) return;
+ // Update ducks
+ for (var i = ducks.length - 1; i >= 0; i--) {
+ var duck = ducks[i];
+ duck.update();
+ if (duck.escaped && !duck.hit) {
+ ducksEscaped++;
+ if (duck.parent) duck.parent.removeChild(duck);
+ ducks.splice(i, 1);
+ }
+ }
+ // If all ducks gone, end wave
+ var aliveDucks = 0;
+ for (var i = 0; i < ducks.length; i++) {
+ if (ducks[i].alive) aliveDucks++;
+ }
+ if (aliveDucks === 0) {
+ endWave();
+ }
+};
+// On game over, reset everything
+LK.on('gameover', function () {
+ if (timerInterval) LK.clearInterval(timerInterval);
+ if (waveResultTimeout) LK.clearTimeout(waveResultTimeout);
+ gameActive = false;
+ waveActive = false;
+ level = 1;
+ ducks = [];
+ bullets = [];
+ ducksHit = 0;
+ ducksEscaped = 0;
+ bulletsLeft = 3;
+ updateBulletIcons();
+ levelText.setText('Level 1');
+ scoreText.setText('Score: ' + highScore);
+ timerText.setText('Time: 15');
+ if (dog) dog.hide();
+ // Start again after short delay
+ LK.setTimeout(function () {
+ startLevel();
+ }, 1200);
+});
+// On you win (if you want to add a win condition, e.g. after level 10)
+LK.on('youwin', function () {
+ if (timerInterval) LK.clearInterval(timerInterval);
+ if (waveResultTimeout) LK.clearTimeout(waveResultTimeout);
+ gameActive = false;
+ waveActive = false;
+ // Show win, then reset
+ LK.setTimeout(function () {
+ level = 1;
+ ducks = [];
+ bullets = [];
+ ducksHit = 0;
+ ducksEscaped = 0;
+ bulletsLeft = 3;
+ updateBulletIcons();
+ levelText.setText('Level 1');
+ scoreText.setText('Score: ' + highScore);
+ timerText.setText('Time: 15');
+ if (dog) dog.hide();
+ startLevel();
+ }, 1800);
+});
+// Start music
+LK.playMusic('bgm', {
+ fade: {
+ start: 0,
+ end: 0.5,
+ duration: 1200
+ }
+});
+// Start first level
+startLevel();
\ No newline at end of file
bullet. In-Game asset. 2d. High contrast. No shadows
crosshair. In-Game asset. 2d. High contrast. No shadows
pixart jungle. In-Game asset. 2d. High contrast. No shadows
pixart hunting brown dog with black ears and white mouth holding a gun. In-Game asset. 2d. High contrast. No shadows
pixart brown hunting dog with black ears and white mouth laughing. In-Game asset. 2d. High contrast. No shadows
pixart blue duck flying. In-Game asset. 2d. High contrast. No shadows
pixart green duck flying. In-Game asset. 2d. High contrast. No shadows
pixart red duck flying. In-Game asset. 2d. High contrast. No shadows
pigeon flying. In-Game asset. 2d. High contrast. No shadows
black wall. In-Game asset. 2d. High contrast. No shadows
empty beer glass. In-Game asset. 2d. High contrast. No shadows
pixart sand watch. In-Game asset. 2d. High contrast. No shadows
dalmation dog holding a gun. In-Game asset. 2d. High contrast. No shadows. hunting
labrador dog hold a hunt gun. In-Game asset. 2d. High contrast. No shadows
dalmatian dog laugh. In-Game asset. 2d. High contrast. No shadows
labrador laugh. In-Game asset. 2d. High contrast. No shadows