/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -20;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Marksman = Container.expand(function () {
var self = Container.call(this);
var marksmanGraphics = self.attachAsset('marksman', {
anchorX: 0.5,
anchorY: 1
});
var rifleGraphics = self.attachAsset('rifle', {
anchorX: 0,
anchorY: 0.5,
y: -40
});
self.targetX = 2048 / 2;
self.targetY = 2732 - 150;
self.shoot = function (targetX, targetY) {
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y - 60;
// Calculate angle to target
var dx = targetX - bullet.x;
var dy = targetY - bullet.y;
var angle = Math.atan2(dy, dx);
// Set bullet velocity towards target
bullet.speed = -20;
bullet.velocityX = Math.cos(angle) * 20;
bullet.velocityY = Math.sin(angle) * 20;
// Override update to use velocity
bullet.update = function () {
bullet.x += bullet.velocityX;
bullet.y += bullet.velocityY;
};
bullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
};
self.update = function () {
// Smooth movement towards target position
var dx = self.targetX - self.x;
self.x += dx * 0.1;
// Update rifle rotation to aim at crosshair
if (aimX !== undefined && aimY !== undefined) {
var angle = Math.atan2(aimY - self.y + 40, aimX - self.x);
rifleGraphics.rotation = angle;
}
};
return self;
});
var Target = Container.expand(function () {
var self = Container.call(this);
var targetGraphics = self.attachAsset('target', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.hit = false;
self.update = function () {
if (!self.hit) {
self.y += self.speed;
}
};
self.destroy = function () {
Container.prototype.destroy.call(self);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb
});
/****
* Game Code
****/
var marksman = new Marksman();
marksman.x = 2048 / 2;
marksman.y = 2732 - 50;
game.addChild(marksman);
var targets = [];
var bullets = [];
var currentScore = 0;
var missedTargets = 0;
var maxMissedTargets = 5;
var lastTargetSpawn = 0;
var targetSpawnInterval = 2000; // 2 seconds
var aimX, aimY;
var consecutiveMisses = 0;
var globalTime = 10000; // 10 seconds initial time
var maxGlobalTime = 10000;
var activeTarget = null;
var lastShotTime = 0;
var shotCooldown = 500; // Half second cooldown
// Global timer bar background
var globalTimerBg = LK.getAsset('timerBackground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 1.5
});
globalTimerBg.x = 2048 / 2;
globalTimerBg.y = 137;
game.addChild(globalTimerBg);
// Global timer bar foreground
var globalTimerBar = LK.getAsset('timerBar', {
anchorX: 0,
anchorY: 0.5,
scaleX: 3,
scaleY: 1.5
});
globalTimerBar.x = 2048 / 2 - 150;
globalTimerBar.y = 137;
game.addChild(globalTimerBar);
// Score display
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Missed targets display
var missedTxt = new Text2('Missed: 0/5', {
size: 40,
fill: 0xFF4444
});
missedTxt.anchor.set(1, 0);
missedTxt.y = 80;
LK.gui.topRight.addChild(missedTxt);
// Crosshair
var crosshairH = LK.getAsset('timerBar', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.1,
tint: 0xffffff
});
var crosshairV = LK.getAsset('timerBar', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1,
scaleY: 0.3,
rotation: Math.PI / 2,
tint: 0xffffff
});
game.addChild(crosshairH);
game.addChild(crosshairV);
game.move = function (x, y, obj) {
aimX = x;
aimY = y;
marksman.targetX = x;
crosshairH.x = x;
crosshairH.y = y;
crosshairV.x = x;
crosshairV.y = y;
};
game.down = function (x, y, obj) {
aimX = x;
aimY = y;
// Check if enough time has passed since last shot
if (LK.ticks - lastShotTime > shotCooldown / 16.67) {
marksman.shoot(x, y);
lastShotTime = LK.ticks;
}
};
game.update = function () {
// Spawn more targets as score increases
if (LK.ticks - lastTargetSpawn > targetSpawnInterval / 16.67) {
var target = new Target();
target.x = Math.random() * (2048 - 160) + 80;
target.y = -50;
// Increase target speed based on score - much slower increase
target.speed = 2 + Math.floor(currentScore / 100) * 0.2;
targets.push(target);
game.addChild(target);
lastTargetSpawn = LK.ticks;
// Decrease spawn interval very gradually as score increases
targetSpawnInterval = Math.max(1000, 2000 - currentScore * 5);
}
// Update global timer if there's an active target
if (activeTarget && !activeTarget.hit) {
globalTime -= 16.67; // ~60fps
// Update timer bar
var timePercent = Math.max(0, globalTime / maxGlobalTime);
globalTimerBar.scaleX = timePercent * 3;
// Change color based on time remaining
if (timePercent > 0.5) {
globalTimerBar.tint = 0x00ff00; // Green
} else if (timePercent > 0.2) {
globalTimerBar.tint = 0xffff00; // Yellow
} else {
globalTimerBar.tint = 0xff0000; // Red
}
// Check if time expired
if (globalTime <= 0) {
// Game over immediately when timer expires
LK.showGameOver();
return;
}
}
// Set active target to first unhit target
if (!activeTarget || activeTarget.hit) {
for (var i = 0; i < targets.length; i++) {
if (!targets[i].hit) {
activeTarget = targets[i];
break;
}
}
}
// Update and check targets
for (var i = targets.length - 1; i >= 0; i--) {
var target = targets[i];
// Check if target is at same horizontal level as marksman (game over condition)
if (!target.hit && target.y >= marksman.y - 100 && target.y <= marksman.y + 100) {
// Game over when target reaches marksman level
LK.showGameOver();
return;
}
// Remove targets that are off screen
if (target.y > 2732 + 100) {
if (target === activeTarget) {
activeTarget = null;
}
target.destroy();
targets.splice(i, 1);
}
}
// Update and check bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
// Check bullet-target collisions
for (var j = targets.length - 1; j >= 0; j--) {
var target = targets[j];
if (!target.hit && bullet.intersects(target)) {
// Hit!
target.hit = true;
target.alpha = 0.3;
currentScore += Math.floor(globalTime / 100) + 10; // Bonus for faster shots
scoreTxt.setText('Score: ' + currentScore);
consecutiveMisses = 0; // Reset consecutive misses
// Calculate decreased timer based on score - decrease by 100ms per 10 points, minimum 1000ms
var scoreDecrease = Math.floor(currentScore / 10) * 100;
var decreasedMaxTime = Math.max(1000, 10000 - scoreDecrease);
// Reset global timer to decreased maximum
globalTime = decreasedMaxTime;
maxGlobalTime = decreasedMaxTime; // Update max time for future calculations
if (target === activeTarget) {
activeTarget = null;
}
LK.getSound('hit').play();
LK.effects.flashObject(target, 0xffffff, 300);
// Remove bullet
bullet.destroy();
bullets.splice(i, 1);
break;
}
}
// Remove bullets that are off screen
if (bullet && (bullet.y < -50 || bullet.y > 2732 + 50 || bullet.x < -50 || bullet.x > 2048 + 50)) {
bullet.destroy();
bullets.splice(i, 1);
}
}
// Game continues endlessly - no win condition
};
// Start background music
LK.playMusic('gameMusic'); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -20;
self.update = function () {
self.y += self.speed;
};
return self;
});
var Marksman = Container.expand(function () {
var self = Container.call(this);
var marksmanGraphics = self.attachAsset('marksman', {
anchorX: 0.5,
anchorY: 1
});
var rifleGraphics = self.attachAsset('rifle', {
anchorX: 0,
anchorY: 0.5,
y: -40
});
self.targetX = 2048 / 2;
self.targetY = 2732 - 150;
self.shoot = function (targetX, targetY) {
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y - 60;
// Calculate angle to target
var dx = targetX - bullet.x;
var dy = targetY - bullet.y;
var angle = Math.atan2(dy, dx);
// Set bullet velocity towards target
bullet.speed = -20;
bullet.velocityX = Math.cos(angle) * 20;
bullet.velocityY = Math.sin(angle) * 20;
// Override update to use velocity
bullet.update = function () {
bullet.x += bullet.velocityX;
bullet.y += bullet.velocityY;
};
bullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
};
self.update = function () {
// Smooth movement towards target position
var dx = self.targetX - self.x;
self.x += dx * 0.1;
// Update rifle rotation to aim at crosshair
if (aimX !== undefined && aimY !== undefined) {
var angle = Math.atan2(aimY - self.y + 40, aimX - self.x);
rifleGraphics.rotation = angle;
}
};
return self;
});
var Target = Container.expand(function () {
var self = Container.call(this);
var targetGraphics = self.attachAsset('target', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 2;
self.hit = false;
self.update = function () {
if (!self.hit) {
self.y += self.speed;
}
};
self.destroy = function () {
Container.prototype.destroy.call(self);
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x87ceeb
});
/****
* Game Code
****/
var marksman = new Marksman();
marksman.x = 2048 / 2;
marksman.y = 2732 - 50;
game.addChild(marksman);
var targets = [];
var bullets = [];
var currentScore = 0;
var missedTargets = 0;
var maxMissedTargets = 5;
var lastTargetSpawn = 0;
var targetSpawnInterval = 2000; // 2 seconds
var aimX, aimY;
var consecutiveMisses = 0;
var globalTime = 10000; // 10 seconds initial time
var maxGlobalTime = 10000;
var activeTarget = null;
var lastShotTime = 0;
var shotCooldown = 500; // Half second cooldown
// Global timer bar background
var globalTimerBg = LK.getAsset('timerBackground', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 1.5
});
globalTimerBg.x = 2048 / 2;
globalTimerBg.y = 137;
game.addChild(globalTimerBg);
// Global timer bar foreground
var globalTimerBar = LK.getAsset('timerBar', {
anchorX: 0,
anchorY: 0.5,
scaleX: 3,
scaleY: 1.5
});
globalTimerBar.x = 2048 / 2 - 150;
globalTimerBar.y = 137;
game.addChild(globalTimerBar);
// Score display
var scoreTxt = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Missed targets display
var missedTxt = new Text2('Missed: 0/5', {
size: 40,
fill: 0xFF4444
});
missedTxt.anchor.set(1, 0);
missedTxt.y = 80;
LK.gui.topRight.addChild(missedTxt);
// Crosshair
var crosshairH = LK.getAsset('timerBar', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.3,
scaleY: 0.1,
tint: 0xffffff
});
var crosshairV = LK.getAsset('timerBar', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 0.1,
scaleY: 0.3,
rotation: Math.PI / 2,
tint: 0xffffff
});
game.addChild(crosshairH);
game.addChild(crosshairV);
game.move = function (x, y, obj) {
aimX = x;
aimY = y;
marksman.targetX = x;
crosshairH.x = x;
crosshairH.y = y;
crosshairV.x = x;
crosshairV.y = y;
};
game.down = function (x, y, obj) {
aimX = x;
aimY = y;
// Check if enough time has passed since last shot
if (LK.ticks - lastShotTime > shotCooldown / 16.67) {
marksman.shoot(x, y);
lastShotTime = LK.ticks;
}
};
game.update = function () {
// Spawn more targets as score increases
if (LK.ticks - lastTargetSpawn > targetSpawnInterval / 16.67) {
var target = new Target();
target.x = Math.random() * (2048 - 160) + 80;
target.y = -50;
// Increase target speed based on score - much slower increase
target.speed = 2 + Math.floor(currentScore / 100) * 0.2;
targets.push(target);
game.addChild(target);
lastTargetSpawn = LK.ticks;
// Decrease spawn interval very gradually as score increases
targetSpawnInterval = Math.max(1000, 2000 - currentScore * 5);
}
// Update global timer if there's an active target
if (activeTarget && !activeTarget.hit) {
globalTime -= 16.67; // ~60fps
// Update timer bar
var timePercent = Math.max(0, globalTime / maxGlobalTime);
globalTimerBar.scaleX = timePercent * 3;
// Change color based on time remaining
if (timePercent > 0.5) {
globalTimerBar.tint = 0x00ff00; // Green
} else if (timePercent > 0.2) {
globalTimerBar.tint = 0xffff00; // Yellow
} else {
globalTimerBar.tint = 0xff0000; // Red
}
// Check if time expired
if (globalTime <= 0) {
// Game over immediately when timer expires
LK.showGameOver();
return;
}
}
// Set active target to first unhit target
if (!activeTarget || activeTarget.hit) {
for (var i = 0; i < targets.length; i++) {
if (!targets[i].hit) {
activeTarget = targets[i];
break;
}
}
}
// Update and check targets
for (var i = targets.length - 1; i >= 0; i--) {
var target = targets[i];
// Check if target is at same horizontal level as marksman (game over condition)
if (!target.hit && target.y >= marksman.y - 100 && target.y <= marksman.y + 100) {
// Game over when target reaches marksman level
LK.showGameOver();
return;
}
// Remove targets that are off screen
if (target.y > 2732 + 100) {
if (target === activeTarget) {
activeTarget = null;
}
target.destroy();
targets.splice(i, 1);
}
}
// Update and check bullets
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
// Check bullet-target collisions
for (var j = targets.length - 1; j >= 0; j--) {
var target = targets[j];
if (!target.hit && bullet.intersects(target)) {
// Hit!
target.hit = true;
target.alpha = 0.3;
currentScore += Math.floor(globalTime / 100) + 10; // Bonus for faster shots
scoreTxt.setText('Score: ' + currentScore);
consecutiveMisses = 0; // Reset consecutive misses
// Calculate decreased timer based on score - decrease by 100ms per 10 points, minimum 1000ms
var scoreDecrease = Math.floor(currentScore / 10) * 100;
var decreasedMaxTime = Math.max(1000, 10000 - scoreDecrease);
// Reset global timer to decreased maximum
globalTime = decreasedMaxTime;
maxGlobalTime = decreasedMaxTime; // Update max time for future calculations
if (target === activeTarget) {
activeTarget = null;
}
LK.getSound('hit').play();
LK.effects.flashObject(target, 0xffffff, 300);
// Remove bullet
bullet.destroy();
bullets.splice(i, 1);
break;
}
}
// Remove bullets that are off screen
if (bullet && (bullet.y < -50 || bullet.y > 2732 + 50 || bullet.x < -50 || bullet.x > 2048 + 50)) {
bullet.destroy();
bullets.splice(i, 1);
}
}
// Game continues endlessly - no win condition
};
// Start background music
LK.playMusic('gameMusic');
hedef tahtası. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
tüfek. In-Game asset. 2d. High contrast. No shadows
kovboy. In-Game asset. 2d. High contrast. No shadows
mermi. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat