User prompt
Increase the distance between difficulty buttons
User prompt
menuBtn3 size is 700x700
User prompt
menuBtn3 size is 700x600
User prompt
make it menuBtn2 size is 700x300
Code edit (4 edits merged)
Please save this source code
User prompt
make it menuBtn2 size is changeable
User prompt
menuBtn2 make it size 700x400
Code edit (1 edits merged)
Please save this source code
User prompt
add assests for difficulty buttons
User prompt
Add the menü (title: BİRD SHOOTİNG) and bellow dificulties
User prompt
fix the eror
User prompt
Add a sound for successful hit, start, end and best score.
User prompt
birdMoving Don't do a somersault, he should make a mirror reflection when he returns, and he can move up and down.
User prompt
Let the birdMoving look in the direction it is moving so it can move freely
User prompt
Give me new images for all birds
User prompt
Let all birds have different appearances
User prompt
More different birds(targets)(moving bird, small bird, big bird)
User prompt
All game in the square
User prompt
Make background size is a square
User prompt
Add a background To the back
User prompt
Make half the size of the target
User prompt
Increase the size of the target by 5 times
Code edit (1 edits merged)
Please save this source code
User prompt
Target Blitz: Reflex Challenge
Initial prompt
Let random targets appear in screen. Let it be the difficulty setting, it is the most difficult, difficult, medium and easy, so let the targets disappear at this time (0.250 0.400 0.600 0.800). Let's count how many were shot at the top. Let there be a total of 20 targets each time. When it's over, go back to the menu so that the difficulty setting can be selected again. See the best number of shots for each challenge separately (best score).
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
// BigBirdTarget: larger, easier to tap, unique image with orange beak
var BigBirdTarget = Container.expand(function () {
var self = Container.call(this);
var targetAsset = self.attachAsset('birdBig', {
anchorX: 0.5,
anchorY: 0.5,
width: 180 * 4.0,
height: 180 * 4.0
});
// Add a "beak" using a small orange ellipse overlay
var beak = self.attachAsset('targetCircle', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 60,
width: 60,
height: 30,
color: 0xff9900,
shape: 'ellipse'
});
self.isHit = false;
self.down = function (x, y, obj) {
if (self.isHit) {
return;
}
self.isHit = true;
tween(self, {
scaleX: 1.4,
scaleY: 1.4,
alpha: 0
}, {
duration: 120,
easing: tween.cubicOut,
onFinish: function onFinish() {
self.destroy();
}
});
if (typeof onTargetHit === 'function') {
onTargetHit(self);
}
};
self.alpha = 0;
self.scaleX = self.scaleY = 0.7;
tween(self, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 120,
easing: tween.cubicOut
});
return self;
});
// MovingBirdTarget: moves horizontally and vertically, mirrors on direction change, unique image with white "wing"
var MovingBirdTarget = Container.expand(function () {
var self = Container.call(this);
var targetAsset = self.attachAsset('birdMoving', {
anchorX: 0.5,
anchorY: 0.5,
width: 180 * 2.0,
height: 180 * 2.0
});
// Add a "wing" using a white ellipse overlay
var wing = self.attachAsset('targetCircle', {
anchorX: 0.5,
anchorY: 0.5,
x: 40,
y: 0,
width: 60,
height: 30,
color: 0xffffff,
shape: 'ellipse'
});
self.isHit = false;
// Movement direction: horizontal and vertical
self._direction = Math.random() < 0.5 ? 1 : -1; // left or right
self._verticalDir = Math.random() < 0.5 ? 1 : -1; // up or down
self._speed = 8 + Math.random() * 6; // px per frame (horizontal)
self._verticalSpeed = 3 + Math.random() * 3; // px per frame (vertical)
self._minX = 120 + targetAsset.width / 2;
self._maxX = 2048 - 120 - targetAsset.width / 2;
self._minY = 120 + targetAsset.height / 2;
self._maxY = 2732 - 120 - targetAsset.height / 2;
self.update = function () {
if (self.isHit) {
return;
}
if (typeof self.lastX === "undefined") {
self.lastX = self.x;
}
if (typeof self.lastY === "undefined") {
self.lastY = self.y;
}
var prevX = self.x;
var prevY = self.y;
// Move horizontally and vertically
self.x += self._direction * self._speed;
self.y += self._verticalDir * self._verticalSpeed;
// Mirror horizontally based on direction
targetAsset.scaleX = self._direction > 0 ? 1 : -1;
// Bounce at horizontal edges
if (self._direction > 0 && self.x > self._maxX || self._direction < 0 && self.x < self._minX) {
self._direction *= -1;
self.x = Math.max(Math.min(self.x, self._maxX), self._minX);
// Mirror handled above
}
// Bounce at vertical edges
if (self._verticalDir > 0 && self.y > self._maxY || self._verticalDir < 0 && self.y < self._minY) {
self._verticalDir *= -1;
self.y = Math.max(Math.min(self.y, self._maxY), self._minY);
}
self.lastX = self.x;
self.lastY = self.y;
};
self.down = function (x, y, obj) {
if (self.isHit) {
return;
}
self.isHit = true;
tween(self, {
scaleX: 1.4,
scaleY: 1.4,
alpha: 0
}, {
duration: 120,
easing: tween.cubicOut,
onFinish: function onFinish() {
self.destroy();
}
});
if (typeof onTargetHit === 'function') {
onTargetHit(self);
}
};
self.alpha = 0;
self.scaleX = self.scaleY = 0.7;
tween(self, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 120,
easing: tween.cubicOut
});
return self;
});
// SmallBirdTarget: smaller, harder to tap, unique image with pink "tail"
var SmallBirdTarget = Container.expand(function () {
var self = Container.call(this);
var targetAsset = self.attachAsset('birdSmall', {
anchorX: 0.5,
anchorY: 0.5,
width: 180 * 1.2,
height: 180 * 1.2
});
// Add a "tail" using a pink ellipse overlay
var tail = self.attachAsset('targetCircle', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 40,
width: 30,
height: 60,
color: 0xff66cc,
shape: 'ellipse'
});
self.isHit = false;
self.down = function (x, y, obj) {
if (self.isHit) {
return;
}
self.isHit = true;
tween(self, {
scaleX: 1.4,
scaleY: 1.4,
alpha: 0
}, {
duration: 120,
easing: tween.cubicOut,
onFinish: function onFinish() {
self.destroy();
}
});
if (typeof onTargetHit === 'function') {
onTargetHit(self);
}
};
self.alpha = 0;
self.scaleX = self.scaleY = 0.7;
tween(self, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 120,
easing: tween.cubicOut
});
return self;
});
// Target class: a tappable target that appears and disappears after a timeout, normal bird with unique image and white "eye"
var Target = Container.expand(function () {
var self = Container.call(this);
// Attach a unique image for normal bird
var targetAsset = self.attachAsset('birdNormal', {
anchorX: 0.5,
anchorY: 0.5,
width: 180 * 2.5,
height: 180 * 2.5
});
// Add a "white eye" using a small white ellipse overlay
var eye = self.attachAsset('targetCircle', {
anchorX: 0.5,
anchorY: 0.5,
x: 40,
y: -40,
width: 40,
height: 40,
color: 0xffffff,
shape: 'ellipse'
});
// Mark as not yet hit
self.isHit = false;
// Called when the target is tapped
self.down = function (x, y, obj) {
if (self.isHit) {
return;
}
self.isHit = true;
// Animate: scale up and fade out
tween(self, {
scaleX: 1.4,
scaleY: 1.4,
alpha: 0
}, {
duration: 120,
easing: tween.cubicOut,
onFinish: function onFinish() {
self.destroy();
}
});
// Notify game that this target was hit
if (typeof onTargetHit === 'function') {
onTargetHit(self);
}
};
// For tap feedback, animate in
self.alpha = 0;
self.scaleX = self.scaleY = 0.7;
tween(self, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 120,
easing: tween.cubicOut
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x181818
});
/****
* Game Code
****/
// Add background shape first so it is always behind all menu buttons and UI elements
// Dedicated image asset for the menu title (replace id with any photo you want)
// Difficulty button assets
// Unique images for each bird type
// Add a background shape behind all game elements
// Sound assets for game events
var backgroundShape = LK.getAsset('backgroundShape', {
width: 2048,
height: 2048,
color: 0x222a38,
shape: 'box',
anchorX: 0,
anchorY: 0,
x: 0,
// Center the square background vertically in 2732px canvas
y: (2732 - 2048) / 2
});
game.addChild(backgroundShape);
// --- Difficulty settings ---
var difficulties = [{
name: "Easy",
key: "easy",
time: 800
}, {
name: "Medium",
key: "medium",
time: 600
}, {
name: "Difficult",
key: "hard",
time: 400
}, {
name: "Most Difficult",
key: "insane",
time: 250
}];
// --- State variables ---
var currentDifficulty = null; // {name, key, time}
var roundTargets = 20;
var targetsSpawned = 0;
var targetsHit = 0;
var targetTimeout = null;
var activeTarget = null;
var inGame = false;
// --- Best scores ---
if (!storage.bestScores) {
storage.bestScores = {};
}
var bestScores = storage.bestScores;
// --- UI elements ---
var scoreTxt = new Text2('0', {
size: 120,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var menuContainer = new Container();
LK.gui.center.addChild(menuContainer);
var bestScoreTxts = []; // Array of Text2 for best scores per difficulty
// --- Helper: Show menu ---
function showMenu() {
inGame = false;
// Clear any active target
if (activeTarget) {
activeTarget.destroy();
activeTarget = null;
}
if (targetTimeout) {
LK.clearTimeout(targetTimeout);
targetTimeout = null;
}
// Reset score display
scoreTxt.setText('');
// Remove previous menu items
while (menuContainer.children.length) {
menuContainer.removeChild(menuContainer.children[0]);
}
bestScoreTxts = [];
// Move menuContainer up so all buttons are higher on the screen
menuContainer.y = -220;
// Move scoreTxt to the top of the square area (move further up)
scoreTxt.y = -10;
// Title at the very top, visually separated from difficulty (now as a unique asset)
// Use a dedicated image asset for the title, so any photo can be used
// Remove any previous menuTitlePhoto asset from LK.gui.top before adding a new one
for (var i = LK.gui.top.children.length - 1; i >= 0; i--) {
var child = LK.gui.top.children[i];
if (child && child.assetId === 'menuTitlePhoto') {
LK.gui.top.removeChild(child);
}
}
var titleAsset = LK.getAsset('menuTitlePhoto', {
anchorX: 0.5,
anchorY: 0,
x: 0,
y: 380,
// Lowered by 400 units from previous 80
width: 800,
height: 240
});
titleAsset.assetId = 'menuTitlePhoto';
LK.gui.top.addChild(titleAsset);
// All difficulty buttons: visible, non-overlapping, distributed vertically under the menu title photo
var btnSizes = [{
width: 300,
height: 300
},
// Easy
{
width: 300,
height: 300
},
// Medium
{
width: 500,
height: 500
},
// Hard
{
width: 500,
height: 500
} // Most Difficult
];
// Layout parameters
var spacingY = 60;
var centerX = 0;
var underTitleY = 380 + 240 + 60; // title y + title height + margin
// --- Add main menu button to open/close difficulty buttons ---
var menuMainBtn = LK.getAsset('choseDifficultyButton', {
anchorX: 0.5,
anchorY: 0.5,
x: centerX,
y: underTitleY + 80,
// visually centered under title
width: 700,
height: 180
});
menuContainer.addChild(menuMainBtn);
var menuMainLabel = new Text2("Choose Difficulty", {
size: 70,
fill: "#fff"
});
menuMainLabel.anchor.set(0.5, 0.5);
menuMainLabel.x = menuMainBtn.x;
menuMainLabel.y = menuMainBtn.y;
menuContainer.addChild(menuMainLabel);
// Track if difficulty buttons are open
var difficultyButtonsOpen = false;
var difficultyBtns = [];
var difficultyLabels = [];
var difficultyBestTxts = [];
// Helper to show/hide difficulty buttons
function setDifficultyButtonsVisible(visible) {
for (var i = 0; i < difficultyBtns.length; i++) {
difficultyBtns[i].visible = visible;
difficultyLabels[i].visible = visible;
difficultyBestTxts[i].visible = visible;
}
}
// Pre-create difficulty buttons, but don't show them yet
var btnYs = [];
var yCursor = underTitleY + 180 + 40; // below the main menu button
for (var i = 0; i < difficulties.length; i++) {
btnYs.push(yCursor + btnSizes[i].height / 2);
yCursor += btnSizes[i].height + spacingY;
}
for (var i = 0; i < difficulties.length; i++) {
// Assign menuBtn0-3 asset for each difficulty button
var btnAssetId = 'menuBtn' + i;
var btn = LK.getAsset(btnAssetId, {
anchorX: 0.5,
anchorY: 0.5,
x: centerX,
y: btnYs[i],
width: btnSizes[i].width,
height: btnSizes[i].height
});
btn.visible = false;
menuContainer.addChild(btn);
var label = new Text2(difficulties[i].name, {
size: 70,
fill: "#fff"
});
label.anchor.set(0.5, 0.5);
label.x = btn.x;
label.y = btn.y;
label.visible = false;
menuContainer.addChild(label);
var best = bestScores[difficulties[i].key] || 0;
var bestTxt = new Text2("Best: " + best + " / " + roundTargets, {
size: 40,
fill: 0xFFEC00
});
bestTxt.anchor.set(0.5, 0.5);
bestTxt.x = btn.x + 220;
bestTxt.y = btn.y + 38;
bestTxt.visible = false;
menuContainer.addChild(bestTxt);
bestScoreTxts.push(bestTxt);
difficultyBtns.push(btn);
difficultyLabels.push(label);
difficultyBestTxts.push(bestTxt);
(function (idx, button) {
button.down = function (x, y, obj) {
startGame(difficulties[idx]);
};
})(i, btn);
}
// Main menu button toggles difficulty buttons
menuMainBtn.down = function (x, y, obj) {
// Hide the main menu button and its label
menuMainBtn.visible = false;
menuMainLabel.visible = false;
difficultyButtonsOpen = true;
// Hide menuTitlePhoto if present
for (var i = LK.gui.top.children.length - 1; i >= 0; i--) {
var child = LK.gui.top.children[i];
if (child && child.assetId === 'menuTitlePhoto') {
child.visible = false;
}
}
// Place difficulty buttons closer to the center and show them
// New positions: all buttons are closer to the center (±420 px from center)
var btnOffset = 420;
var bestOffsetX = 180;
var bestOffsetY = 38;
// Top left (closer to center)
difficultyBtns[0].x = -btnOffset;
difficultyBtns[0].y = -btnOffset;
difficultyLabels[0].x = -btnOffset;
difficultyLabels[0].y = -btnOffset;
difficultyBestTxts[0].x = -btnOffset + bestOffsetX;
difficultyBestTxts[0].y = -btnOffset + bestOffsetY;
// Lower left (closer to center)
difficultyBtns[1].x = -btnOffset;
difficultyBtns[1].y = btnOffset;
difficultyLabels[1].x = -btnOffset;
difficultyLabels[1].y = btnOffset;
difficultyBestTxts[1].x = -btnOffset + bestOffsetX;
difficultyBestTxts[1].y = btnOffset + bestOffsetY;
// Top right (closer to center)
difficultyBtns[2].x = btnOffset;
difficultyBtns[2].y = -btnOffset;
difficultyLabels[2].x = btnOffset;
difficultyLabels[2].y = -btnOffset;
difficultyBestTxts[2].x = btnOffset + bestOffsetX;
difficultyBestTxts[2].y = -btnOffset + bestOffsetY;
// Lower right (closer to center)
difficultyBtns[3].x = btnOffset;
difficultyBtns[3].y = btnOffset;
difficultyLabels[3].x = btnOffset;
difficultyLabels[3].y = btnOffset;
difficultyBestTxts[3].x = btnOffset + bestOffsetX;
difficultyBestTxts[3].y = btnOffset + bestOffsetY;
setDifficultyButtonsVisible(true);
};
setDifficultyButtonsVisible(false);
}
// --- Helper: Start game with selected difficulty ---
function startGame(diff) {
inGame = true;
currentDifficulty = diff;
targetsSpawned = 0;
targetsHit = 0;
scoreTxt.setText("0 / " + roundTargets);
// Play start sound
LK.getSound('start').play();
// Remove menu
while (menuContainer.children.length) {
menuContainer.removeChild(menuContainer.children[0]);
}
// Remove menuTitlePhoto from LK.gui.top if present
for (var i = LK.gui.top.children.length - 1; i >= 0; i--) {
var child = LK.gui.top.children[i];
if (child && child.assetId === 'menuTitlePhoto') {
LK.gui.top.removeChild(child);
}
}
// Start first target
spawnNextTarget();
}
// --- Helper: Spawn a target at a random position ---
function spawnNextTarget() {
if (!inGame) {
return;
}
if (activeTarget) {
activeTarget.destroy();
activeTarget = null;
}
if (targetsSpawned >= roundTargets) {
endGame();
return;
}
targetsSpawned++;
// Randomly choose a target type: 0=normal, 1=small, 2=big, 3=moving
var margin = 120;
var type = Math.floor(Math.random() * 4);
var x, y, target;
if (type === 1) {
// Small bird
x = margin + 60 + Math.random() * (2048 - 2 * (margin + 60));
y = margin + 60 + Math.random() * (2048 - 2 * (margin + 60));
target = new SmallBirdTarget();
target.x = x;
target.y = y;
} else if (type === 2) {
// Big bird
x = margin + 180 + Math.random() * (2048 - 2 * (margin + 180));
y = margin + 180 + Math.random() * (2048 - 2 * (margin + 180));
target = new BigBirdTarget();
target.x = x;
target.y = y;
} else if (type === 3) {
// Moving bird
y = margin + Math.random() * (2048 - 2 * margin);
// Start at left or right edge
if (Math.random() < 0.5) {
x = margin + 180;
} else {
x = 2048 - margin - 180;
}
target = new MovingBirdTarget();
target.x = x;
target.y = y;
} else {
// Normal
x = margin + Math.random() * (2048 - 2 * margin);
y = margin + Math.random() * (2048 - 2 * margin);
target = new Target();
target.x = x;
target.y = y;
}
activeTarget = target;
game.addChild(target);
// Timeout: if not hit in time, remove and spawn next
targetTimeout = LK.setTimeout(function () {
if (activeTarget === target && !target.isHit) {
// Animate out
tween(target, {
alpha: 0
}, {
duration: 100,
onFinish: function onFinish() {
target.destroy();
}
});
activeTarget = null;
spawnNextTarget();
}
}, currentDifficulty.time);
}
// --- Helper: Called when a target is hit ---
function onTargetHit(target) {
if (!inGame) {
return;
}
if (activeTarget === target) {
targetsHit++;
scoreTxt.setText(targetsHit + " / " + roundTargets);
// Play hit sound
LK.getSound('hit').play();
activeTarget = null;
if (targetTimeout) {
LK.clearTimeout(targetTimeout);
targetTimeout = null;
}
// Next target after a short delay for feedback
LK.setTimeout(spawnNextTarget, 80);
}
}
// --- Helper: End of round ---
function endGame() {
inGame = false;
// Play end sound
LK.getSound('end').play();
// Update best score if needed
var key = currentDifficulty.key;
var isBest = false;
if (!bestScores[key] || targetsHit > bestScores[key]) {
bestScores[key] = targetsHit;
storage.bestScores = bestScores;
isBest = true;
}
// Play best score sound if new best
if (isBest) {
LK.getSound('best').play();
}
// Show result popup
var resultTxt = new Text2("You hit " + targetsHit + " / " + roundTargets + "!", {
size: 100,
fill: "#fff"
});
resultTxt.anchor.set(0.5, 0.5);
resultTxt.y = -120;
menuContainer.addChild(resultTxt);
var best = bestScores[key] || 0;
var bestTxt = new Text2("Best: " + best + " / " + roundTargets, {
size: 60,
fill: 0xFFEC00
});
bestTxt.anchor.set(0.5, 0.5);
bestTxt.y = 0;
menuContainer.addChild(bestTxt);
var againBtn = LK.getAsset('againBtn', {
width: 500,
height: 120,
color: 0x44bb44,
shape: 'box',
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 180
});
menuContainer.addChild(againBtn);
var againLabel = new Text2("Menu", {
size: 60,
fill: "#fff"
});
againLabel.anchor.set(0.5, 0.5);
againLabel.x = againBtn.x;
againLabel.y = againBtn.y;
menuContainer.addChild(againLabel);
againBtn.down = function (x, y, obj) {
// Remove result elements
while (menuContainer.children.length) {
menuContainer.removeChild(menuContainer.children[0]);
}
// Show menuTitlePhoto if present, or add it if not present
var foundTitlePhoto = false;
for (var i = LK.gui.top.children.length - 1; i >= 0; i--) {
var child = LK.gui.top.children[i];
if (child && child.assetId === 'menuTitlePhoto') {
child.visible = true;
foundTitlePhoto = true;
}
}
if (!foundTitlePhoto) {
var titleAsset = LK.getAsset('menuTitlePhoto', {
anchorX: 0.5,
anchorY: 0,
x: 0,
y: 380,
width: 800,
height: 240
});
titleAsset.assetId = 'menuTitlePhoto';
LK.gui.top.addChild(titleAsset);
}
showMenu();
};
}
// Animate moving bird targets (if any)
game.update = function () {
if (activeTarget && typeof activeTarget.update === "function") {
activeTarget.update();
}
};
// --- Game move handler (no drag, but required for touch compatibility) ---
game.move = function (x, y, obj) {};
// --- Start with menu ---
showMenu(); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
// BigBirdTarget: larger, easier to tap, unique image with orange beak
var BigBirdTarget = Container.expand(function () {
var self = Container.call(this);
var targetAsset = self.attachAsset('birdBig', {
anchorX: 0.5,
anchorY: 0.5,
width: 180 * 4.0,
height: 180 * 4.0
});
// Add a "beak" using a small orange ellipse overlay
var beak = self.attachAsset('targetCircle', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 60,
width: 60,
height: 30,
color: 0xff9900,
shape: 'ellipse'
});
self.isHit = false;
self.down = function (x, y, obj) {
if (self.isHit) {
return;
}
self.isHit = true;
tween(self, {
scaleX: 1.4,
scaleY: 1.4,
alpha: 0
}, {
duration: 120,
easing: tween.cubicOut,
onFinish: function onFinish() {
self.destroy();
}
});
if (typeof onTargetHit === 'function') {
onTargetHit(self);
}
};
self.alpha = 0;
self.scaleX = self.scaleY = 0.7;
tween(self, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 120,
easing: tween.cubicOut
});
return self;
});
// MovingBirdTarget: moves horizontally and vertically, mirrors on direction change, unique image with white "wing"
var MovingBirdTarget = Container.expand(function () {
var self = Container.call(this);
var targetAsset = self.attachAsset('birdMoving', {
anchorX: 0.5,
anchorY: 0.5,
width: 180 * 2.0,
height: 180 * 2.0
});
// Add a "wing" using a white ellipse overlay
var wing = self.attachAsset('targetCircle', {
anchorX: 0.5,
anchorY: 0.5,
x: 40,
y: 0,
width: 60,
height: 30,
color: 0xffffff,
shape: 'ellipse'
});
self.isHit = false;
// Movement direction: horizontal and vertical
self._direction = Math.random() < 0.5 ? 1 : -1; // left or right
self._verticalDir = Math.random() < 0.5 ? 1 : -1; // up or down
self._speed = 8 + Math.random() * 6; // px per frame (horizontal)
self._verticalSpeed = 3 + Math.random() * 3; // px per frame (vertical)
self._minX = 120 + targetAsset.width / 2;
self._maxX = 2048 - 120 - targetAsset.width / 2;
self._minY = 120 + targetAsset.height / 2;
self._maxY = 2732 - 120 - targetAsset.height / 2;
self.update = function () {
if (self.isHit) {
return;
}
if (typeof self.lastX === "undefined") {
self.lastX = self.x;
}
if (typeof self.lastY === "undefined") {
self.lastY = self.y;
}
var prevX = self.x;
var prevY = self.y;
// Move horizontally and vertically
self.x += self._direction * self._speed;
self.y += self._verticalDir * self._verticalSpeed;
// Mirror horizontally based on direction
targetAsset.scaleX = self._direction > 0 ? 1 : -1;
// Bounce at horizontal edges
if (self._direction > 0 && self.x > self._maxX || self._direction < 0 && self.x < self._minX) {
self._direction *= -1;
self.x = Math.max(Math.min(self.x, self._maxX), self._minX);
// Mirror handled above
}
// Bounce at vertical edges
if (self._verticalDir > 0 && self.y > self._maxY || self._verticalDir < 0 && self.y < self._minY) {
self._verticalDir *= -1;
self.y = Math.max(Math.min(self.y, self._maxY), self._minY);
}
self.lastX = self.x;
self.lastY = self.y;
};
self.down = function (x, y, obj) {
if (self.isHit) {
return;
}
self.isHit = true;
tween(self, {
scaleX: 1.4,
scaleY: 1.4,
alpha: 0
}, {
duration: 120,
easing: tween.cubicOut,
onFinish: function onFinish() {
self.destroy();
}
});
if (typeof onTargetHit === 'function') {
onTargetHit(self);
}
};
self.alpha = 0;
self.scaleX = self.scaleY = 0.7;
tween(self, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 120,
easing: tween.cubicOut
});
return self;
});
// SmallBirdTarget: smaller, harder to tap, unique image with pink "tail"
var SmallBirdTarget = Container.expand(function () {
var self = Container.call(this);
var targetAsset = self.attachAsset('birdSmall', {
anchorX: 0.5,
anchorY: 0.5,
width: 180 * 1.2,
height: 180 * 1.2
});
// Add a "tail" using a pink ellipse overlay
var tail = self.attachAsset('targetCircle', {
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 40,
width: 30,
height: 60,
color: 0xff66cc,
shape: 'ellipse'
});
self.isHit = false;
self.down = function (x, y, obj) {
if (self.isHit) {
return;
}
self.isHit = true;
tween(self, {
scaleX: 1.4,
scaleY: 1.4,
alpha: 0
}, {
duration: 120,
easing: tween.cubicOut,
onFinish: function onFinish() {
self.destroy();
}
});
if (typeof onTargetHit === 'function') {
onTargetHit(self);
}
};
self.alpha = 0;
self.scaleX = self.scaleY = 0.7;
tween(self, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 120,
easing: tween.cubicOut
});
return self;
});
// Target class: a tappable target that appears and disappears after a timeout, normal bird with unique image and white "eye"
var Target = Container.expand(function () {
var self = Container.call(this);
// Attach a unique image for normal bird
var targetAsset = self.attachAsset('birdNormal', {
anchorX: 0.5,
anchorY: 0.5,
width: 180 * 2.5,
height: 180 * 2.5
});
// Add a "white eye" using a small white ellipse overlay
var eye = self.attachAsset('targetCircle', {
anchorX: 0.5,
anchorY: 0.5,
x: 40,
y: -40,
width: 40,
height: 40,
color: 0xffffff,
shape: 'ellipse'
});
// Mark as not yet hit
self.isHit = false;
// Called when the target is tapped
self.down = function (x, y, obj) {
if (self.isHit) {
return;
}
self.isHit = true;
// Animate: scale up and fade out
tween(self, {
scaleX: 1.4,
scaleY: 1.4,
alpha: 0
}, {
duration: 120,
easing: tween.cubicOut,
onFinish: function onFinish() {
self.destroy();
}
});
// Notify game that this target was hit
if (typeof onTargetHit === 'function') {
onTargetHit(self);
}
};
// For tap feedback, animate in
self.alpha = 0;
self.scaleX = self.scaleY = 0.7;
tween(self, {
alpha: 1,
scaleX: 1,
scaleY: 1
}, {
duration: 120,
easing: tween.cubicOut
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x181818
});
/****
* Game Code
****/
// Add background shape first so it is always behind all menu buttons and UI elements
// Dedicated image asset for the menu title (replace id with any photo you want)
// Difficulty button assets
// Unique images for each bird type
// Add a background shape behind all game elements
// Sound assets for game events
var backgroundShape = LK.getAsset('backgroundShape', {
width: 2048,
height: 2048,
color: 0x222a38,
shape: 'box',
anchorX: 0,
anchorY: 0,
x: 0,
// Center the square background vertically in 2732px canvas
y: (2732 - 2048) / 2
});
game.addChild(backgroundShape);
// --- Difficulty settings ---
var difficulties = [{
name: "Easy",
key: "easy",
time: 800
}, {
name: "Medium",
key: "medium",
time: 600
}, {
name: "Difficult",
key: "hard",
time: 400
}, {
name: "Most Difficult",
key: "insane",
time: 250
}];
// --- State variables ---
var currentDifficulty = null; // {name, key, time}
var roundTargets = 20;
var targetsSpawned = 0;
var targetsHit = 0;
var targetTimeout = null;
var activeTarget = null;
var inGame = false;
// --- Best scores ---
if (!storage.bestScores) {
storage.bestScores = {};
}
var bestScores = storage.bestScores;
// --- UI elements ---
var scoreTxt = new Text2('0', {
size: 120,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var menuContainer = new Container();
LK.gui.center.addChild(menuContainer);
var bestScoreTxts = []; // Array of Text2 for best scores per difficulty
// --- Helper: Show menu ---
function showMenu() {
inGame = false;
// Clear any active target
if (activeTarget) {
activeTarget.destroy();
activeTarget = null;
}
if (targetTimeout) {
LK.clearTimeout(targetTimeout);
targetTimeout = null;
}
// Reset score display
scoreTxt.setText('');
// Remove previous menu items
while (menuContainer.children.length) {
menuContainer.removeChild(menuContainer.children[0]);
}
bestScoreTxts = [];
// Move menuContainer up so all buttons are higher on the screen
menuContainer.y = -220;
// Move scoreTxt to the top of the square area (move further up)
scoreTxt.y = -10;
// Title at the very top, visually separated from difficulty (now as a unique asset)
// Use a dedicated image asset for the title, so any photo can be used
// Remove any previous menuTitlePhoto asset from LK.gui.top before adding a new one
for (var i = LK.gui.top.children.length - 1; i >= 0; i--) {
var child = LK.gui.top.children[i];
if (child && child.assetId === 'menuTitlePhoto') {
LK.gui.top.removeChild(child);
}
}
var titleAsset = LK.getAsset('menuTitlePhoto', {
anchorX: 0.5,
anchorY: 0,
x: 0,
y: 380,
// Lowered by 400 units from previous 80
width: 800,
height: 240
});
titleAsset.assetId = 'menuTitlePhoto';
LK.gui.top.addChild(titleAsset);
// All difficulty buttons: visible, non-overlapping, distributed vertically under the menu title photo
var btnSizes = [{
width: 300,
height: 300
},
// Easy
{
width: 300,
height: 300
},
// Medium
{
width: 500,
height: 500
},
// Hard
{
width: 500,
height: 500
} // Most Difficult
];
// Layout parameters
var spacingY = 60;
var centerX = 0;
var underTitleY = 380 + 240 + 60; // title y + title height + margin
// --- Add main menu button to open/close difficulty buttons ---
var menuMainBtn = LK.getAsset('choseDifficultyButton', {
anchorX: 0.5,
anchorY: 0.5,
x: centerX,
y: underTitleY + 80,
// visually centered under title
width: 700,
height: 180
});
menuContainer.addChild(menuMainBtn);
var menuMainLabel = new Text2("Choose Difficulty", {
size: 70,
fill: "#fff"
});
menuMainLabel.anchor.set(0.5, 0.5);
menuMainLabel.x = menuMainBtn.x;
menuMainLabel.y = menuMainBtn.y;
menuContainer.addChild(menuMainLabel);
// Track if difficulty buttons are open
var difficultyButtonsOpen = false;
var difficultyBtns = [];
var difficultyLabels = [];
var difficultyBestTxts = [];
// Helper to show/hide difficulty buttons
function setDifficultyButtonsVisible(visible) {
for (var i = 0; i < difficultyBtns.length; i++) {
difficultyBtns[i].visible = visible;
difficultyLabels[i].visible = visible;
difficultyBestTxts[i].visible = visible;
}
}
// Pre-create difficulty buttons, but don't show them yet
var btnYs = [];
var yCursor = underTitleY + 180 + 40; // below the main menu button
for (var i = 0; i < difficulties.length; i++) {
btnYs.push(yCursor + btnSizes[i].height / 2);
yCursor += btnSizes[i].height + spacingY;
}
for (var i = 0; i < difficulties.length; i++) {
// Assign menuBtn0-3 asset for each difficulty button
var btnAssetId = 'menuBtn' + i;
var btn = LK.getAsset(btnAssetId, {
anchorX: 0.5,
anchorY: 0.5,
x: centerX,
y: btnYs[i],
width: btnSizes[i].width,
height: btnSizes[i].height
});
btn.visible = false;
menuContainer.addChild(btn);
var label = new Text2(difficulties[i].name, {
size: 70,
fill: "#fff"
});
label.anchor.set(0.5, 0.5);
label.x = btn.x;
label.y = btn.y;
label.visible = false;
menuContainer.addChild(label);
var best = bestScores[difficulties[i].key] || 0;
var bestTxt = new Text2("Best: " + best + " / " + roundTargets, {
size: 40,
fill: 0xFFEC00
});
bestTxt.anchor.set(0.5, 0.5);
bestTxt.x = btn.x + 220;
bestTxt.y = btn.y + 38;
bestTxt.visible = false;
menuContainer.addChild(bestTxt);
bestScoreTxts.push(bestTxt);
difficultyBtns.push(btn);
difficultyLabels.push(label);
difficultyBestTxts.push(bestTxt);
(function (idx, button) {
button.down = function (x, y, obj) {
startGame(difficulties[idx]);
};
})(i, btn);
}
// Main menu button toggles difficulty buttons
menuMainBtn.down = function (x, y, obj) {
// Hide the main menu button and its label
menuMainBtn.visible = false;
menuMainLabel.visible = false;
difficultyButtonsOpen = true;
// Hide menuTitlePhoto if present
for (var i = LK.gui.top.children.length - 1; i >= 0; i--) {
var child = LK.gui.top.children[i];
if (child && child.assetId === 'menuTitlePhoto') {
child.visible = false;
}
}
// Place difficulty buttons closer to the center and show them
// New positions: all buttons are closer to the center (±420 px from center)
var btnOffset = 420;
var bestOffsetX = 180;
var bestOffsetY = 38;
// Top left (closer to center)
difficultyBtns[0].x = -btnOffset;
difficultyBtns[0].y = -btnOffset;
difficultyLabels[0].x = -btnOffset;
difficultyLabels[0].y = -btnOffset;
difficultyBestTxts[0].x = -btnOffset + bestOffsetX;
difficultyBestTxts[0].y = -btnOffset + bestOffsetY;
// Lower left (closer to center)
difficultyBtns[1].x = -btnOffset;
difficultyBtns[1].y = btnOffset;
difficultyLabels[1].x = -btnOffset;
difficultyLabels[1].y = btnOffset;
difficultyBestTxts[1].x = -btnOffset + bestOffsetX;
difficultyBestTxts[1].y = btnOffset + bestOffsetY;
// Top right (closer to center)
difficultyBtns[2].x = btnOffset;
difficultyBtns[2].y = -btnOffset;
difficultyLabels[2].x = btnOffset;
difficultyLabels[2].y = -btnOffset;
difficultyBestTxts[2].x = btnOffset + bestOffsetX;
difficultyBestTxts[2].y = -btnOffset + bestOffsetY;
// Lower right (closer to center)
difficultyBtns[3].x = btnOffset;
difficultyBtns[3].y = btnOffset;
difficultyLabels[3].x = btnOffset;
difficultyLabels[3].y = btnOffset;
difficultyBestTxts[3].x = btnOffset + bestOffsetX;
difficultyBestTxts[3].y = btnOffset + bestOffsetY;
setDifficultyButtonsVisible(true);
};
setDifficultyButtonsVisible(false);
}
// --- Helper: Start game with selected difficulty ---
function startGame(diff) {
inGame = true;
currentDifficulty = diff;
targetsSpawned = 0;
targetsHit = 0;
scoreTxt.setText("0 / " + roundTargets);
// Play start sound
LK.getSound('start').play();
// Remove menu
while (menuContainer.children.length) {
menuContainer.removeChild(menuContainer.children[0]);
}
// Remove menuTitlePhoto from LK.gui.top if present
for (var i = LK.gui.top.children.length - 1; i >= 0; i--) {
var child = LK.gui.top.children[i];
if (child && child.assetId === 'menuTitlePhoto') {
LK.gui.top.removeChild(child);
}
}
// Start first target
spawnNextTarget();
}
// --- Helper: Spawn a target at a random position ---
function spawnNextTarget() {
if (!inGame) {
return;
}
if (activeTarget) {
activeTarget.destroy();
activeTarget = null;
}
if (targetsSpawned >= roundTargets) {
endGame();
return;
}
targetsSpawned++;
// Randomly choose a target type: 0=normal, 1=small, 2=big, 3=moving
var margin = 120;
var type = Math.floor(Math.random() * 4);
var x, y, target;
if (type === 1) {
// Small bird
x = margin + 60 + Math.random() * (2048 - 2 * (margin + 60));
y = margin + 60 + Math.random() * (2048 - 2 * (margin + 60));
target = new SmallBirdTarget();
target.x = x;
target.y = y;
} else if (type === 2) {
// Big bird
x = margin + 180 + Math.random() * (2048 - 2 * (margin + 180));
y = margin + 180 + Math.random() * (2048 - 2 * (margin + 180));
target = new BigBirdTarget();
target.x = x;
target.y = y;
} else if (type === 3) {
// Moving bird
y = margin + Math.random() * (2048 - 2 * margin);
// Start at left or right edge
if (Math.random() < 0.5) {
x = margin + 180;
} else {
x = 2048 - margin - 180;
}
target = new MovingBirdTarget();
target.x = x;
target.y = y;
} else {
// Normal
x = margin + Math.random() * (2048 - 2 * margin);
y = margin + Math.random() * (2048 - 2 * margin);
target = new Target();
target.x = x;
target.y = y;
}
activeTarget = target;
game.addChild(target);
// Timeout: if not hit in time, remove and spawn next
targetTimeout = LK.setTimeout(function () {
if (activeTarget === target && !target.isHit) {
// Animate out
tween(target, {
alpha: 0
}, {
duration: 100,
onFinish: function onFinish() {
target.destroy();
}
});
activeTarget = null;
spawnNextTarget();
}
}, currentDifficulty.time);
}
// --- Helper: Called when a target is hit ---
function onTargetHit(target) {
if (!inGame) {
return;
}
if (activeTarget === target) {
targetsHit++;
scoreTxt.setText(targetsHit + " / " + roundTargets);
// Play hit sound
LK.getSound('hit').play();
activeTarget = null;
if (targetTimeout) {
LK.clearTimeout(targetTimeout);
targetTimeout = null;
}
// Next target after a short delay for feedback
LK.setTimeout(spawnNextTarget, 80);
}
}
// --- Helper: End of round ---
function endGame() {
inGame = false;
// Play end sound
LK.getSound('end').play();
// Update best score if needed
var key = currentDifficulty.key;
var isBest = false;
if (!bestScores[key] || targetsHit > bestScores[key]) {
bestScores[key] = targetsHit;
storage.bestScores = bestScores;
isBest = true;
}
// Play best score sound if new best
if (isBest) {
LK.getSound('best').play();
}
// Show result popup
var resultTxt = new Text2("You hit " + targetsHit + " / " + roundTargets + "!", {
size: 100,
fill: "#fff"
});
resultTxt.anchor.set(0.5, 0.5);
resultTxt.y = -120;
menuContainer.addChild(resultTxt);
var best = bestScores[key] || 0;
var bestTxt = new Text2("Best: " + best + " / " + roundTargets, {
size: 60,
fill: 0xFFEC00
});
bestTxt.anchor.set(0.5, 0.5);
bestTxt.y = 0;
menuContainer.addChild(bestTxt);
var againBtn = LK.getAsset('againBtn', {
width: 500,
height: 120,
color: 0x44bb44,
shape: 'box',
anchorX: 0.5,
anchorY: 0.5,
x: 0,
y: 180
});
menuContainer.addChild(againBtn);
var againLabel = new Text2("Menu", {
size: 60,
fill: "#fff"
});
againLabel.anchor.set(0.5, 0.5);
againLabel.x = againBtn.x;
againLabel.y = againBtn.y;
menuContainer.addChild(againLabel);
againBtn.down = function (x, y, obj) {
// Remove result elements
while (menuContainer.children.length) {
menuContainer.removeChild(menuContainer.children[0]);
}
// Show menuTitlePhoto if present, or add it if not present
var foundTitlePhoto = false;
for (var i = LK.gui.top.children.length - 1; i >= 0; i--) {
var child = LK.gui.top.children[i];
if (child && child.assetId === 'menuTitlePhoto') {
child.visible = true;
foundTitlePhoto = true;
}
}
if (!foundTitlePhoto) {
var titleAsset = LK.getAsset('menuTitlePhoto', {
anchorX: 0.5,
anchorY: 0,
x: 0,
y: 380,
width: 800,
height: 240
});
titleAsset.assetId = 'menuTitlePhoto';
LK.gui.top.addChild(titleAsset);
}
showMenu();
};
}
// Animate moving bird targets (if any)
game.update = function () {
if (activeTarget && typeof activeTarget.update === "function") {
activeTarget.update();
}
};
// --- Game move handler (no drag, but required for touch compatibility) ---
game.move = function (x, y, obj) {};
// --- Start with menu ---
showMenu();
Sunset between the mountains ( natural) piksel art. In-Game asset. 2d. High contrast. No shadows
Big fat flaying bird ( Piksel art). Colorful In-Game asset. 2d. High contrast.
Rectangle
Big fat flaying bird ( Piksel art). Colorful. Cute. In-Game asset. 2d. High contrast.
Big fat flaying bird ( Piksel art). Cute. Colorful In-Game asset. 2d. High contrast.
Fastest flaying bird ( Piksel art). Cute. Colorful In-Game asset. 2d. High contrast.
Target for weapon.(piksel art) In-Game asset. 2d. High contrast.
(700x140) button (cute pixel art). no writing No shadows
A pixel art sign that says BIRDS SHOOTING.(800x240 size) No shadows
700x700(total size) black red button (like hell fire around and into button) (cute pixel art). no writing No shadows