/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var BarrierButton = Container.expand(function () {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('barrierButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.isActive = true;
self.usesRemaining = 3;
self.maxUses = 3;
// Visual indicator for uses remaining
var usesText = new Text2('3', {
size: 40,
fill: 0xffffff
});
usesText.anchor.set(0.5, 0.5);
usesText.x = 0;
usesText.y = -50;
self.addChild(usesText);
// Pulse animation when active
var scale = 1;
var scaleDirection = 1;
self.update = function () {
if (self.isActive && self.usesRemaining > 0) {
scale += 0.01 * scaleDirection;
if (scale > 1.2) scaleDirection = -1;
if (scale < 0.8) scaleDirection = 1;
buttonGraphics.scaleX = scale;
buttonGraphics.scaleY = scale;
} else {
// Inactive state
buttonGraphics.tint = 0x666666;
buttonGraphics.alpha = 0.5;
}
};
self.down = function (x, y, obj) {
if (self.isActive && self.usesRemaining > 0) {
self.activateBarrierBreaker();
}
};
self.activateBarrierBreaker = function () {
if (self.usesRemaining <= 0) return;
self.usesRemaining--;
usesText.setText(self.usesRemaining.toString());
// Visual feedback
LK.effects.flashObject(self, 0xff00ff, 300);
LK.getSound('barrierBreak').play();
// Apply barrier breaker to next bullet
if (cannon) {
cannon.nextBulletBarrierBreaker = true;
}
// Deactivate if no uses left
if (self.usesRemaining <= 0) {
self.isActive = false;
buttonGraphics.tint = 0x666666;
buttonGraphics.alpha = 0.5;
}
};
self.resetUses = function () {
self.usesRemaining = self.maxUses;
self.isActive = true;
buttonGraphics.tint = 0xffffff;
buttonGraphics.alpha = 1;
usesText.setText(self.usesRemaining.toString());
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.speed = 8;
self.boostedSpeed = 16;
self.isSpeedBoosted = false;
self.isBarrierBreaker = false;
self.bounces = 0;
self.maxBounces = 15;
self.active = true;
self.update = function () {
if (!self.active) return;
// Store previous position for collision detection
self.prevX = self.x;
self.prevY = self.y;
// Apply velocity with speed boost if applicable
var currentSpeed = self.isSpeedBoosted ? self.boostedSpeed : self.speed;
var speedMultiplier = currentSpeed / self.speed;
self.x += self.velocityX * speedMultiplier;
self.y += self.velocityY * speedMultiplier;
// Check wall collisions
for (var i = 0; i < walls.length; i++) {
var wall = walls[i];
if (self.intersects(wall)) {
self.handleWallCollision(wall);
break;
}
}
// Check boundary wall collisions
for (var i = 0; i < boundaryWalls.length; i++) {
var boundaryWall = boundaryWalls[i];
if (self.intersects(boundaryWall)) {
self.handleWallCollision(boundaryWall);
break;
}
}
// Check target collisions
for (var i = targets.length - 1; i >= 0; i--) {
var target = targets[i];
if (self.intersects(target)) {
self.hitTarget(target, i);
return;
}
}
// Remove if out of bounds or too many bounces
if (self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782 || self.bounces > self.maxBounces) {
self.removeBullet();
}
};
self.handleWallCollision = function (wall) {
// Barrier breaker bullets destroy walls and obstacles
if (self.isBarrierBreaker) {
// Don't destroy boundary walls
var isBoundaryWall = false;
for (var j = 0; j < boundaryWalls.length; j++) {
if (boundaryWalls[j] === wall) {
isBoundaryWall = true;
break;
}
}
if (!isBoundaryWall) {
// Destroy the wall
for (var k = walls.length - 1; k >= 0; k--) {
if (walls[k] === wall) {
walls[k].destroy();
walls.splice(k, 1);
break;
}
}
// Continue moving without bouncing
return;
}
}
if (self.bounces >= self.maxBounces) {
self.removeBullet();
return;
}
// Calculate collision normal
var bulletCenterX = self.x;
var bulletCenterY = self.y;
var wallCenterX = wall.x + wall.width / 2;
var wallCenterY = wall.y + wall.height / 2;
var dx = bulletCenterX - wallCenterX;
var dy = bulletCenterY - wallCenterY;
// Determine which side of the wall was hit
var wallHalfWidth = wall.width / 2;
var wallHalfHeight = wall.height / 2;
if (Math.abs(dx) / wallHalfWidth > Math.abs(dy) / wallHalfHeight) {
// Hit left or right side
self.velocityX = -self.velocityX;
self.x = dx > 0 ? wall.x + wall.width + 10 : wall.x - 10;
} else {
// Hit top or bottom side
self.velocityY = -self.velocityY;
self.y = dy > 0 ? wall.y + wall.height + 10 : wall.y - 10;
}
self.bounces++;
LK.getSound('ricochet').play();
// Flash effect on bounce
LK.effects.flashObject(self, 0xffffff, 200);
};
self.hitTarget = function (target, index) {
LK.getSound('hit').play();
LK.effects.flashObject(target, 0xffffff, 300);
// Remove target
target.destroy();
targets.splice(index, 1);
// Update score
LK.setScore(LK.getScore() + 100);
updateUI();
// Remove bullet
self.removeBullet();
// Check win condition
if (targets.length === 0) {
levelComplete();
}
};
self.applySpeedBoost = function () {
self.isSpeedBoosted = true;
// Add visual effect for boosted bullet
bulletGraphics.tint = 0xffaa00;
};
self.applyBarrierBreaker = function () {
self.isBarrierBreaker = true;
// Add visual effect for barrier breaker bullet - purple glow
bulletGraphics.tint = 0xff00ff;
// Make it slightly larger
bulletGraphics.scaleX = 1.5;
bulletGraphics.scaleY = 1.5;
};
self.removeBullet = function () {
self.active = false;
self.destroy();
for (var i = bullets.length - 1; i >= 0; i--) {
if (bullets[i] === self) {
bullets.splice(i, 1);
break;
}
}
// Check if no more bullets and targets remain
if (bullets.length === 0 && targets.length > 0 && bulletsRemaining <= 0) {
gameOver();
}
};
return self;
});
var Cannon = Container.expand(function () {
var self = Container.call(this);
var cannonGraphics = self.attachAsset('cannon', {
anchorX: 0.5,
anchorY: 0.5
});
var aimLine = self.attachAsset('aimLine', {
anchorX: 0.5,
anchorY: 0,
alpha: 0
});
self.isAiming = false;
self.aimAngle = 0;
self.aimTargetX = 0;
self.aimTargetY = 0;
self.startAiming = function (targetX, targetY) {
self.isAiming = true;
self.aimTargetX = targetX;
self.aimTargetY = targetY;
self.updateAim(targetX, targetY);
aimLine.alpha = 0.7;
};
self.updateAim = function (targetX, targetY) {
if (!self.isAiming) return;
self.aimTargetX = targetX;
self.aimTargetY = targetY;
var dx = targetX - self.x;
var dy = targetY - self.y;
self.aimAngle = Math.atan2(dy, dx);
aimLine.rotation = self.aimAngle + Math.PI / 2;
cannonGraphics.rotation = self.aimAngle;
};
self.speedBoostActive = false;
self.speedBoostTime = 0;
self.maxSpeedBoostTime = 180; // 3 seconds at 60fps
self.nextBulletBarrierBreaker = false;
self.applySpeedBoost = function () {
self.speedBoostActive = true;
self.speedBoostTime = self.maxSpeedBoostTime;
cannonGraphics.tint = 0xffaa00; // Orange tint during boost
};
self.updateSpeedBoost = function () {
if (self.speedBoostActive) {
self.speedBoostTime--;
if (self.speedBoostTime <= 0) {
self.speedBoostActive = false;
cannonGraphics.tint = 0xffffff; // Reset to normal color
}
}
};
self.shoot = function () {
if (!self.isAiming || bulletsRemaining <= 0) return;
self.isAiming = false;
aimLine.alpha = 0;
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
// Apply speed boost to bullet if cannon has speed boost active
if (self.speedBoostActive) {
bullet.applySpeedBoost();
}
// Apply barrier breaker to bullet if activated
if (self.nextBulletBarrierBreaker) {
bullet.applyBarrierBreaker();
self.nextBulletBarrierBreaker = false;
}
// Calculate direction vector to exact aim position
var dx = self.aimTargetX - self.x;
var dy = self.aimTargetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Normalize and apply base speed
bullet.velocityX = dx / distance * bullet.speed;
bullet.velocityY = dy / distance * bullet.speed;
bullets.push(bullet);
game.addChild(bullet);
bulletsRemaining--;
updateUI();
LK.getSound('shoot').play();
// Enhanced recoil effect during speed boost
var recoilScale = self.speedBoostActive ? 0.6 : 0.8;
// Recoil effect
tween(cannonGraphics, {
scaleX: recoilScale,
scaleY: recoilScale
}, {
duration: 100
});
tween(cannonGraphics, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
};
return self;
});
var SpeedButton = Container.expand(function () {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('speedButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.isActive = true;
self.cooldownTime = 0;
self.maxCooldown = 300; // 5 seconds at 60fps
// Pulse animation
var scale = 1;
var scaleDirection = 1;
self.update = function () {
if (self.isActive) {
scale += 0.01 * scaleDirection;
if (scale > 1.2) scaleDirection = -1;
if (scale < 0.8) scaleDirection = 1;
buttonGraphics.scaleX = scale;
buttonGraphics.scaleY = scale;
} else {
// Cooldown mode - grey out and countdown
self.cooldownTime--;
if (self.cooldownTime <= 0) {
self.isActive = true;
buttonGraphics.tint = 0xffffff;
buttonGraphics.alpha = 1;
}
}
};
self.down = function (x, y, obj) {
if (self.isActive && cannon) {
self.activateSpeedBoost();
}
};
self.activateSpeedBoost = function () {
if (!self.isActive) return;
self.isActive = false;
self.cooldownTime = self.maxCooldown;
buttonGraphics.tint = 0x666666;
buttonGraphics.alpha = 0.5;
// Apply speed boost to cannon
cannon.applySpeedBoost();
LK.getSound('speedBoost').play();
LK.effects.flashObject(self, 0xffff00, 300);
};
return self;
});
var Target = Container.expand(function () {
var self = Container.call(this);
var targetGraphics = self.attachAsset('target', {
anchorX: 0.5,
anchorY: 0.5
});
// Gentle pulse animation
var scale = 1;
var scaleDirection = 1;
self.update = function () {
scale += 0.005 * scaleDirection;
if (scale > 1.1) scaleDirection = -1;
if (scale < 0.9) scaleDirection = 1;
targetGraphics.scaleX = scale;
targetGraphics.scaleY = scale;
};
return self;
});
var TurboButton = Container.expand(function () {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('turboButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.isActive = true;
self.cooldownTime = 0;
self.maxCooldown = 600; // 10 seconds at 60fps
// Pulse animation
var scale = 1;
var scaleDirection = 1;
self.update = function () {
if (self.isActive) {
scale += 0.015 * scaleDirection;
if (scale > 1.3) scaleDirection = -1;
if (scale < 0.7) scaleDirection = 1;
buttonGraphics.scaleX = scale;
buttonGraphics.scaleY = scale;
// Turbo button glows
buttonGraphics.tint = 0x00ffff;
} else {
// Cooldown mode - grey out and countdown
self.cooldownTime--;
if (self.cooldownTime <= 0) {
self.isActive = true;
buttonGraphics.tint = 0x00ffff;
buttonGraphics.alpha = 1;
}
}
};
self.down = function (x, y, obj) {
if (self.isActive) {
self.activateTurbo();
}
};
self.activateTurbo = function () {
if (!self.isActive) return;
self.isActive = false;
self.cooldownTime = self.maxCooldown;
buttonGraphics.tint = 0x666666;
buttonGraphics.alpha = 0.5;
// Activate game-wide turbo mode
activateGameTurbo();
LK.getSound('turboActivate').play();
LK.effects.flashObject(self, 0x00ffff, 300);
};
return self;
});
var Wall = Container.expand(function () {
var self = Container.call(this);
var wallGraphics = self.attachAsset('wall', {
anchorX: 0,
anchorY: 0
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a1a
});
/****
* Game Code
****/
// Game variables
var bullets = [];
var targets = [];
var walls = [];
var boundaryWalls = [];
var cannon;
var speedButton;
var barrierButton;
var turboButton;
var bulletsRemaining = 5;
var currentLevel = 1;
var gameSpeedMultiplier = 1;
var turboActive = false;
var turboTimeRemaining = 0;
// UI elements
var bulletCountText;
var levelText;
var scoreText;
// Initialize UI
function createBoundaryWalls() {
// Clear existing boundary walls
for (var i = 0; i < boundaryWalls.length; i++) {
boundaryWalls[i].destroy();
}
boundaryWalls = [];
// Top wall
var topWall = new Wall();
topWall.x = 0;
topWall.y = 0;
topWall.width = 2048;
topWall.height = 50;
boundaryWalls.push(topWall);
game.addChild(topWall);
// Bottom wall
var bottomWall = new Wall();
bottomWall.x = 0;
bottomWall.y = 2682;
bottomWall.width = 2048;
bottomWall.height = 50;
boundaryWalls.push(bottomWall);
game.addChild(bottomWall);
// Left wall
var leftWall = new Wall();
leftWall.x = 0;
leftWall.y = 0;
leftWall.width = 50;
leftWall.height = 2732;
boundaryWalls.push(leftWall);
game.addChild(leftWall);
// Right wall
var rightWall = new Wall();
rightWall.x = 1998;
rightWall.y = 0;
rightWall.width = 50;
rightWall.height = 2732;
boundaryWalls.push(rightWall);
game.addChild(rightWall);
}
function initializeUI() {
bulletCountText = new Text2('Bullets: ' + bulletsRemaining, {
size: 80,
fill: 0xFFFFFF
});
bulletCountText.anchor.set(0, 0);
bulletCountText.x = 120;
bulletCountText.y = 20;
LK.gui.topLeft.addChild(bulletCountText);
levelText = new Text2('Level ' + currentLevel, {
size: 80,
fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(1, 0);
scoreText.x = -20;
scoreText.y = 20;
LK.gui.topRight.addChild(scoreText);
// Create turbo button
turboButton = new TurboButton();
turboButton.x = 1800;
turboButton.y = 400;
game.addChild(turboButton);
}
function updateUI() {
bulletCountText.setText('Bullets: ' + bulletsRemaining);
scoreText.setText('Score: ' + LK.getScore());
}
// Level creation
function createLevel1() {
// Clear existing elements
clearLevel();
// Create cannon at bottom center
cannon = new Cannon();
cannon.x = 1024;
cannon.y = 2500;
game.addChild(cannon);
// No walls in this level - enemies are closer to player
// Create targets closer to player
var target1 = new Target();
target1.x = 800;
target1.y = 2200;
targets.push(target1);
game.addChild(target1);
var target2 = new Target();
target2.x = 1200;
target2.y = 2000;
targets.push(target2);
game.addChild(target2);
var target3 = new Target();
target3.x = 600;
target3.y = 1800;
targets.push(target3);
game.addChild(target3);
// Create turbo button for this level
turboButton = new TurboButton();
turboButton.x = 1800;
turboButton.y = 400;
game.addChild(turboButton);
// Reset game state
bulletsRemaining = 5;
updateUI();
}
function clearLevel() {
// Clear bullets
for (var i = 0; i < bullets.length; i++) {
bullets[i].destroy();
}
bullets = [];
// Clear targets
for (var i = 0; i < targets.length; i++) {
targets[i].destroy();
}
targets = [];
// Clear walls
for (var i = 0; i < walls.length; i++) {
walls[i].destroy();
}
walls = [];
// Clear cannon
if (cannon) {
cannon.destroy();
cannon = null;
}
// Clear speed button
if (speedButton) {
speedButton.destroy();
speedButton = null;
}
// Clear barrier button
if (barrierButton) {
barrierButton.destroy();
barrierButton = null;
}
// Clear turbo button
if (turboButton) {
turboButton.destroy();
turboButton = null;
}
}
function levelComplete() {
LK.effects.flashScreen(0x00ff00, 500);
LK.setTimeout(function () {
currentLevel++;
if (currentLevel <= 10) {
createNextLevel();
} else {
LK.showYouWin();
}
}, 1000);
}
function createNextLevel() {
levelText.setText('Level ' + currentLevel);
if (currentLevel === 2) {
createLevel2();
} else if (currentLevel === 3) {
createLevel3();
} else if (currentLevel === 4) {
createLevel4();
} else if (currentLevel === 5) {
createLevel5();
} else if (currentLevel === 6) {
createLevel6();
} else if (currentLevel === 7) {
createLevel7();
} else if (currentLevel === 8) {
createLevel8();
} else if (currentLevel === 9) {
createLevel9();
} else if (currentLevel === 10) {
createLevel10();
}
}
function createLevel2() {
clearLevel();
cannon = new Cannon();
cannon.x = 200;
cannon.y = 2500;
game.addChild(cannon);
// No walls - targets closer to player
var target1 = new Target();
target1.x = 500;
target1.y = 2000;
targets.push(target1);
game.addChild(target1);
var target2 = new Target();
target2.x = 1000;
target2.y = 2200;
targets.push(target2);
game.addChild(target2);
var target3 = new Target();
target3.x = 1500;
target3.y = 1900;
targets.push(target3);
game.addChild(target3);
var target4 = new Target();
target4.x = 700;
target4.y = 1700;
targets.push(target4);
game.addChild(target4);
// Create turbo button for this level
turboButton = new TurboButton();
turboButton.x = 1800;
turboButton.y = 400;
game.addChild(turboButton);
// Create turbo button for this level
turboButton = new TurboButton();
turboButton.x = 1800;
turboButton.y = 400;
game.addChild(turboButton);
bulletsRemaining = 6;
updateUI();
}
function createLevel3() {
clearLevel();
cannon = new Cannon();
cannon.x = 1024;
cannon.y = 2600;
game.addChild(cannon);
// No walls - many targets closer to player
var target1 = new Target();
target1.x = 400;
target1.y = 2100;
targets.push(target1);
game.addChild(target1);
var target2 = new Target();
target2.x = 800;
target2.y = 2000;
targets.push(target2);
game.addChild(target2);
var target3 = new Target();
target3.x = 1200;
target3.y = 1900;
targets.push(target3);
game.addChild(target3);
var target4 = new Target();
target4.x = 600;
target4.y = 1700;
targets.push(target4);
game.addChild(target4);
var target5 = new Target();
target5.x = 1000;
target5.y = 1600;
targets.push(target5);
game.addChild(target5);
// Create turbo button for this level
turboButton = new TurboButton();
turboButton.x = 1800;
turboButton.y = 400;
game.addChild(turboButton);
// Create turbo button for this level
turboButton = new TurboButton();
turboButton.x = 1800;
turboButton.y = 400;
game.addChild(turboButton);
bulletsRemaining = 7;
updateUI();
}
function createLevel4() {
clearLevel();
cannon = new Cannon();
cannon.x = 100;
cannon.y = 2400;
game.addChild(cannon);
// Circle formation of targets
var centerX = 1024;
var centerY = 1800;
var radius = 300;
for (var i = 0; i < 6; i++) {
var angle = i / 6 * 2 * Math.PI;
var target = new Target();
target.x = centerX + Math.cos(angle) * radius;
target.y = centerY + Math.sin(angle) * radius;
targets.push(target);
game.addChild(target);
}
// Additional center target
var centerTarget = new Target();
centerTarget.x = centerX;
centerTarget.y = centerY;
targets.push(centerTarget);
game.addChild(centerTarget);
// Create turbo button for this level
turboButton = new TurboButton();
turboButton.x = 1800;
turboButton.y = 400;
game.addChild(turboButton);
// Create turbo button for this level
turboButton = new TurboButton();
turboButton.x = 1800;
turboButton.y = 400;
game.addChild(turboButton);
bulletsRemaining = 8;
updateUI();
}
function createLevel5() {
clearLevel();
cannon = new Cannon();
cannon.x = 1700;
cannon.y = 2500;
game.addChild(cannon);
// Zigzag pattern of targets
var targets_positions = [{
x: 300,
y: 2200
}, {
x: 600,
y: 1900
}, {
x: 900,
y: 2100
}, {
x: 1200,
y: 1800
}, {
x: 1500,
y: 2000
}, {
x: 400,
y: 1600
}, {
x: 800,
y: 1400
}, {
x: 1100,
y: 1500
}, {
x: 1400,
y: 1300
}];
for (var i = 0; i < targets_positions.length; i++) {
var target = new Target();
target.x = targets_positions[i].x;
target.y = targets_positions[i].y;
targets.push(target);
game.addChild(target);
}
// Create turbo button for this level
turboButton = new TurboButton();
turboButton.x = 1800;
turboButton.y = 400;
game.addChild(turboButton);
bulletsRemaining = 10;
updateUI();
}
function activateGameTurbo() {
turboActive = true;
turboTimeRemaining = 180; // 3 seconds at 60fps
gameSpeedMultiplier = 2.5;
// Screen effect to indicate turbo mode
LK.effects.flashScreen(0x00ffff, 500);
// Use tween to smoothly transition speed back to normal
LK.setTimeout(function () {
tween(game, {
gameSpeedMultiplier: 1
}, {
duration: 500,
onFinish: function onFinish() {
turboActive = false;
gameSpeedMultiplier = 1;
}
});
}, 2500);
}
function gameOver() {
LK.effects.flashScreen(0xff0000, 1000);
LK.setTimeout(function () {
LK.showGameOver();
}, 1500);
}
// Touch controls
game.down = function (x, y, obj) {
if (cannon && bulletsRemaining > 0) {
cannon.startAiming(x, y);
}
};
game.move = function (x, y, obj) {
if (cannon && cannon.isAiming) {
cannon.updateAim(x, y);
}
};
game.up = function (x, y, obj) {
if (cannon && cannon.isAiming) {
cannon.shoot();
}
};
game.update = function () {
// Update turbo mode
if (turboActive && turboTimeRemaining > 0) {
turboTimeRemaining--;
}
// Update all bullets with speed multiplier
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
if (bullet && bullet.active) {
// Apply turbo speed to bullets
if (turboActive) {
for (var j = 0; j < gameSpeedMultiplier; j++) {
bullet.update();
}
} else {
bullet.update();
}
}
}
// Update all targets with speed multiplier
for (var i = 0; i < targets.length; i++) {
if (turboActive) {
for (var j = 0; j < gameSpeedMultiplier; j++) {
targets[i].update();
}
} else {
targets[i].update();
}
}
// Update cannon speed boost
if (cannon) {
if (turboActive) {
for (var j = 0; j < gameSpeedMultiplier; j++) {
cannon.updateSpeedBoost();
}
} else {
cannon.updateSpeedBoost();
}
}
// Update turbo button
if (turboButton) {
turboButton.update();
}
};
// Initialize the game
initializeUI();
createBoundaryWalls();
createLevel1();
function createLevel6() {
clearLevel();
cannon = new Cannon();
cannon.x = 1024;
cannon.y = 2600;
game.addChild(cannon);
// Create wall barriers
var wall1 = new Wall();
wall1.x = 600;
wall1.y = 2200;
walls.push(wall1);
game.addChild(wall1);
var wall2 = new Wall();
wall2.x = 1200;
wall2.y = 2000;
walls.push(wall2);
game.addChild(wall2);
var wall3 = new Wall();
wall3.x = 400;
wall3.y = 1800;
walls.push(wall3);
game.addChild(wall3);
// Targets behind walls requiring ricochet
var target1 = new Target();
target1.x = 700;
target1.y = 2100;
targets.push(target1);
game.addChild(target1);
var target2 = new Target();
target2.x = 1300;
target2.y = 1900;
targets.push(target2);
game.addChild(target2);
var target3 = new Target();
target3.x = 500;
target3.y = 1700;
targets.push(target3);
game.addChild(target3);
bulletsRemaining = 6;
updateUI();
}
function createLevel7() {
clearLevel();
cannon = new Cannon();
cannon.x = 200;
cannon.y = 2400;
game.addChild(cannon);
// Create L-shaped wall formations
var wall1 = new Wall();
wall1.x = 800;
wall1.y = 2200;
walls.push(wall1);
game.addChild(wall1);
var wall2 = new Wall();
wall2.x = 800;
wall2.y = 2000;
walls.push(wall2);
game.addChild(wall2);
var wall3 = new Wall();
wall3.x = 1000;
wall3.y = 2000;
walls.push(wall3);
game.addChild(wall3);
var wall4 = new Wall();
wall4.x = 400;
wall4.y = 1600;
walls.push(wall4);
game.addChild(wall4);
var wall5 = new Wall();
wall5.x = 600;
wall5.y = 1600;
walls.push(wall5);
game.addChild(wall5);
// Targets in corners requiring multiple bounces
var target1 = new Target();
target1.x = 900;
target1.y = 2100;
targets.push(target1);
game.addChild(target1);
var target2 = new Target();
target2.x = 1100;
target2.y = 1900;
targets.push(target2);
game.addChild(target2);
var target3 = new Target();
target3.x = 500;
target3.y = 1500;
targets.push(target3);
game.addChild(target3);
var target4 = new Target();
target4.x = 700;
target4.y = 1500;
targets.push(target4);
game.addChild(target4);
bulletsRemaining = 7;
updateUI();
}
function createLevel8() {
clearLevel();
cannon = new Cannon();
cannon.x = 100;
cannon.y = 2300;
game.addChild(cannon);
// Create maze walls
var wall1 = new Wall();
wall1.x = 400;
wall1.y = 2200;
walls.push(wall1);
game.addChild(wall1);
var wall2 = new Wall();
wall2.x = 800;
wall2.y = 2300;
walls.push(wall2);
game.addChild(wall2);
var wall3 = new Wall();
wall3.x = 1200;
wall3.y = 2100;
walls.push(wall3);
game.addChild(wall3);
var wall4 = new Wall();
wall4.x = 600;
wall4.y = 1900;
walls.push(wall4);
game.addChild(wall4);
var wall5 = new Wall();
wall5.x = 1000;
wall5.y = 1800;
walls.push(wall5);
game.addChild(wall5);
var wall6 = new Wall();
wall6.x = 300;
wall6.y = 1600;
walls.push(wall6);
game.addChild(wall6);
var wall7 = new Wall();
wall7.x = 700;
wall7.y = 1500;
walls.push(wall7);
game.addChild(wall7);
// Targets requiring complex ricochet paths
var target1 = new Target();
target1.x = 500;
target1.y = 2100;
targets.push(target1);
game.addChild(target1);
var target2 = new Target();
target2.x = 900;
target2.y = 2200;
targets.push(target2);
game.addChild(target2);
var target3 = new Target();
target3.x = 1300;
target3.y = 2000;
targets.push(target3);
game.addChild(target3);
var target4 = new Target();
target4.x = 700;
target4.y = 1800;
targets.push(target4);
game.addChild(target4);
var target5 = new Target();
target5.x = 1100;
target5.y = 1700;
targets.push(target5);
game.addChild(target5);
bulletsRemaining = 8;
updateUI();
}
function createLevel9() {
clearLevel();
cannon = new Cannon();
cannon.x = 1800;
cannon.y = 2500;
game.addChild(cannon);
// Create narrow corridor walls
var wall1 = new Wall();
wall1.x = 400;
wall1.y = 2300;
walls.push(wall1);
game.addChild(wall1);
var wall2 = new Wall();
wall2.x = 400;
wall2.y = 1800;
walls.push(wall2);
game.addChild(wall2);
var wall3 = new Wall();
wall3.x = 800;
wall3.y = 2100;
walls.push(wall3);
game.addChild(wall3);
var wall4 = new Wall();
wall4.x = 800;
wall4.y = 1600;
walls.push(wall4);
game.addChild(wall4);
var wall5 = new Wall();
wall5.x = 1200;
wall5.y = 2200;
walls.push(wall5);
game.addChild(wall5);
var wall6 = new Wall();
wall6.x = 1200;
wall6.y = 1500;
walls.push(wall6);
game.addChild(wall6);
// Targets in narrow spaces
var target1 = new Target();
target1.x = 500;
target1.y = 2000;
targets.push(target1);
game.addChild(target1);
var target2 = new Target();
target2.x = 900;
target2.y = 1900;
targets.push(target2);
game.addChild(target2);
var target3 = new Target();
target3.x = 1300;
target3.y = 1800;
targets.push(target3);
game.addChild(target3);
var target4 = new Target();
target4.x = 700;
target4.y = 1400;
targets.push(target4);
game.addChild(target4);
var target5 = new Target();
target5.x = 1100;
target5.y = 1300;
targets.push(target5);
game.addChild(target5);
var target6 = new Target();
target6.x = 500;
target6.y = 1200;
targets.push(target6);
game.addChild(target6);
// Create turbo button for this level
turboButton = new TurboButton();
turboButton.x = 1800;
turboButton.y = 400;
game.addChild(turboButton);
bulletsRemaining = 9;
updateUI();
}
function createLevel10() {
clearLevel();
cannon = new Cannon();
cannon.x = 1024;
cannon.y = 2650;
game.addChild(cannon);
// Create complex wall structure
var wall1 = new Wall();
wall1.x = 300;
wall1.y = 2400;
walls.push(wall1);
game.addChild(wall1);
var wall2 = new Wall();
wall2.x = 700;
wall2.y = 2400;
walls.push(wall2);
game.addChild(wall2);
var wall3 = new Wall();
wall3.x = 1100;
wall3.y = 2400;
walls.push(wall3);
game.addChild(wall3);
var wall4 = new Wall();
wall4.x = 1500;
wall4.y = 2400;
walls.push(wall4);
game.addChild(wall4);
var wall5 = new Wall();
wall5.x = 200;
wall5.y = 2000;
walls.push(wall5);
game.addChild(wall5);
var wall6 = new Wall();
wall6.x = 600;
wall6.y = 2100;
walls.push(wall6);
game.addChild(wall6);
var wall7 = new Wall();
wall7.x = 1000;
wall7.y = 2000;
walls.push(wall7);
game.addChild(wall7);
var wall8 = new Wall();
wall8.x = 1400;
wall8.y = 2100;
walls.push(wall8);
game.addChild(wall8);
var wall9 = new Wall();
wall9.x = 400;
wall9.y = 1700;
walls.push(wall9);
game.addChild(wall9);
var wall10 = new Wall();
wall10.x = 800;
wall10.y = 1600;
walls.push(wall10);
game.addChild(wall10);
var wall11 = new Wall();
wall11.x = 1200;
wall11.y = 1700;
walls.push(wall11);
game.addChild(wall11);
// Final challenge targets
var target1 = new Target();
target1.x = 400;
target1.y = 2300;
targets.push(target1);
game.addChild(target1);
var target2 = new Target();
target2.x = 800;
target2.y = 2300;
targets.push(target2);
game.addChild(target2);
var target3 = new Target();
target3.x = 1200;
target3.y = 2300;
targets.push(target3);
game.addChild(target3);
var target4 = new Target();
target4.x = 300;
target4.y = 1900;
targets.push(target4);
game.addChild(target4);
var target5 = new Target();
target5.x = 700;
target5.y = 2000;
targets.push(target5);
game.addChild(target5);
var target6 = new Target();
target6.x = 1100;
target6.y = 1900;
targets.push(target6);
game.addChild(target6);
var target7 = new Target();
target7.x = 1500;
target7.y = 2000;
targets.push(target7);
game.addChild(target7);
var target8 = new Target();
target8.x = 500;
target8.y = 1600;
targets.push(target8);
game.addChild(target8);
var target9 = new Target();
target9.x = 900;
target9.y = 1500;
targets.push(target9);
game.addChild(target9);
var target10 = new Target();
target10.x = 1300;
target10.y = 1600;
targets.push(target10);
game.addChild(target10);
// Create turbo button for this level
turboButton = new TurboButton();
turboButton.x = 1800;
turboButton.y = 400;
game.addChild(turboButton);
bulletsRemaining = 12;
updateUI();
}
; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var BarrierButton = Container.expand(function () {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('barrierButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.isActive = true;
self.usesRemaining = 3;
self.maxUses = 3;
// Visual indicator for uses remaining
var usesText = new Text2('3', {
size: 40,
fill: 0xffffff
});
usesText.anchor.set(0.5, 0.5);
usesText.x = 0;
usesText.y = -50;
self.addChild(usesText);
// Pulse animation when active
var scale = 1;
var scaleDirection = 1;
self.update = function () {
if (self.isActive && self.usesRemaining > 0) {
scale += 0.01 * scaleDirection;
if (scale > 1.2) scaleDirection = -1;
if (scale < 0.8) scaleDirection = 1;
buttonGraphics.scaleX = scale;
buttonGraphics.scaleY = scale;
} else {
// Inactive state
buttonGraphics.tint = 0x666666;
buttonGraphics.alpha = 0.5;
}
};
self.down = function (x, y, obj) {
if (self.isActive && self.usesRemaining > 0) {
self.activateBarrierBreaker();
}
};
self.activateBarrierBreaker = function () {
if (self.usesRemaining <= 0) return;
self.usesRemaining--;
usesText.setText(self.usesRemaining.toString());
// Visual feedback
LK.effects.flashObject(self, 0xff00ff, 300);
LK.getSound('barrierBreak').play();
// Apply barrier breaker to next bullet
if (cannon) {
cannon.nextBulletBarrierBreaker = true;
}
// Deactivate if no uses left
if (self.usesRemaining <= 0) {
self.isActive = false;
buttonGraphics.tint = 0x666666;
buttonGraphics.alpha = 0.5;
}
};
self.resetUses = function () {
self.usesRemaining = self.maxUses;
self.isActive = true;
buttonGraphics.tint = 0xffffff;
buttonGraphics.alpha = 1;
usesText.setText(self.usesRemaining.toString());
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.speed = 8;
self.boostedSpeed = 16;
self.isSpeedBoosted = false;
self.isBarrierBreaker = false;
self.bounces = 0;
self.maxBounces = 15;
self.active = true;
self.update = function () {
if (!self.active) return;
// Store previous position for collision detection
self.prevX = self.x;
self.prevY = self.y;
// Apply velocity with speed boost if applicable
var currentSpeed = self.isSpeedBoosted ? self.boostedSpeed : self.speed;
var speedMultiplier = currentSpeed / self.speed;
self.x += self.velocityX * speedMultiplier;
self.y += self.velocityY * speedMultiplier;
// Check wall collisions
for (var i = 0; i < walls.length; i++) {
var wall = walls[i];
if (self.intersects(wall)) {
self.handleWallCollision(wall);
break;
}
}
// Check boundary wall collisions
for (var i = 0; i < boundaryWalls.length; i++) {
var boundaryWall = boundaryWalls[i];
if (self.intersects(boundaryWall)) {
self.handleWallCollision(boundaryWall);
break;
}
}
// Check target collisions
for (var i = targets.length - 1; i >= 0; i--) {
var target = targets[i];
if (self.intersects(target)) {
self.hitTarget(target, i);
return;
}
}
// Remove if out of bounds or too many bounces
if (self.x < -50 || self.x > 2098 || self.y < -50 || self.y > 2782 || self.bounces > self.maxBounces) {
self.removeBullet();
}
};
self.handleWallCollision = function (wall) {
// Barrier breaker bullets destroy walls and obstacles
if (self.isBarrierBreaker) {
// Don't destroy boundary walls
var isBoundaryWall = false;
for (var j = 0; j < boundaryWalls.length; j++) {
if (boundaryWalls[j] === wall) {
isBoundaryWall = true;
break;
}
}
if (!isBoundaryWall) {
// Destroy the wall
for (var k = walls.length - 1; k >= 0; k--) {
if (walls[k] === wall) {
walls[k].destroy();
walls.splice(k, 1);
break;
}
}
// Continue moving without bouncing
return;
}
}
if (self.bounces >= self.maxBounces) {
self.removeBullet();
return;
}
// Calculate collision normal
var bulletCenterX = self.x;
var bulletCenterY = self.y;
var wallCenterX = wall.x + wall.width / 2;
var wallCenterY = wall.y + wall.height / 2;
var dx = bulletCenterX - wallCenterX;
var dy = bulletCenterY - wallCenterY;
// Determine which side of the wall was hit
var wallHalfWidth = wall.width / 2;
var wallHalfHeight = wall.height / 2;
if (Math.abs(dx) / wallHalfWidth > Math.abs(dy) / wallHalfHeight) {
// Hit left or right side
self.velocityX = -self.velocityX;
self.x = dx > 0 ? wall.x + wall.width + 10 : wall.x - 10;
} else {
// Hit top or bottom side
self.velocityY = -self.velocityY;
self.y = dy > 0 ? wall.y + wall.height + 10 : wall.y - 10;
}
self.bounces++;
LK.getSound('ricochet').play();
// Flash effect on bounce
LK.effects.flashObject(self, 0xffffff, 200);
};
self.hitTarget = function (target, index) {
LK.getSound('hit').play();
LK.effects.flashObject(target, 0xffffff, 300);
// Remove target
target.destroy();
targets.splice(index, 1);
// Update score
LK.setScore(LK.getScore() + 100);
updateUI();
// Remove bullet
self.removeBullet();
// Check win condition
if (targets.length === 0) {
levelComplete();
}
};
self.applySpeedBoost = function () {
self.isSpeedBoosted = true;
// Add visual effect for boosted bullet
bulletGraphics.tint = 0xffaa00;
};
self.applyBarrierBreaker = function () {
self.isBarrierBreaker = true;
// Add visual effect for barrier breaker bullet - purple glow
bulletGraphics.tint = 0xff00ff;
// Make it slightly larger
bulletGraphics.scaleX = 1.5;
bulletGraphics.scaleY = 1.5;
};
self.removeBullet = function () {
self.active = false;
self.destroy();
for (var i = bullets.length - 1; i >= 0; i--) {
if (bullets[i] === self) {
bullets.splice(i, 1);
break;
}
}
// Check if no more bullets and targets remain
if (bullets.length === 0 && targets.length > 0 && bulletsRemaining <= 0) {
gameOver();
}
};
return self;
});
var Cannon = Container.expand(function () {
var self = Container.call(this);
var cannonGraphics = self.attachAsset('cannon', {
anchorX: 0.5,
anchorY: 0.5
});
var aimLine = self.attachAsset('aimLine', {
anchorX: 0.5,
anchorY: 0,
alpha: 0
});
self.isAiming = false;
self.aimAngle = 0;
self.aimTargetX = 0;
self.aimTargetY = 0;
self.startAiming = function (targetX, targetY) {
self.isAiming = true;
self.aimTargetX = targetX;
self.aimTargetY = targetY;
self.updateAim(targetX, targetY);
aimLine.alpha = 0.7;
};
self.updateAim = function (targetX, targetY) {
if (!self.isAiming) return;
self.aimTargetX = targetX;
self.aimTargetY = targetY;
var dx = targetX - self.x;
var dy = targetY - self.y;
self.aimAngle = Math.atan2(dy, dx);
aimLine.rotation = self.aimAngle + Math.PI / 2;
cannonGraphics.rotation = self.aimAngle;
};
self.speedBoostActive = false;
self.speedBoostTime = 0;
self.maxSpeedBoostTime = 180; // 3 seconds at 60fps
self.nextBulletBarrierBreaker = false;
self.applySpeedBoost = function () {
self.speedBoostActive = true;
self.speedBoostTime = self.maxSpeedBoostTime;
cannonGraphics.tint = 0xffaa00; // Orange tint during boost
};
self.updateSpeedBoost = function () {
if (self.speedBoostActive) {
self.speedBoostTime--;
if (self.speedBoostTime <= 0) {
self.speedBoostActive = false;
cannonGraphics.tint = 0xffffff; // Reset to normal color
}
}
};
self.shoot = function () {
if (!self.isAiming || bulletsRemaining <= 0) return;
self.isAiming = false;
aimLine.alpha = 0;
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
// Apply speed boost to bullet if cannon has speed boost active
if (self.speedBoostActive) {
bullet.applySpeedBoost();
}
// Apply barrier breaker to bullet if activated
if (self.nextBulletBarrierBreaker) {
bullet.applyBarrierBreaker();
self.nextBulletBarrierBreaker = false;
}
// Calculate direction vector to exact aim position
var dx = self.aimTargetX - self.x;
var dy = self.aimTargetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Normalize and apply base speed
bullet.velocityX = dx / distance * bullet.speed;
bullet.velocityY = dy / distance * bullet.speed;
bullets.push(bullet);
game.addChild(bullet);
bulletsRemaining--;
updateUI();
LK.getSound('shoot').play();
// Enhanced recoil effect during speed boost
var recoilScale = self.speedBoostActive ? 0.6 : 0.8;
// Recoil effect
tween(cannonGraphics, {
scaleX: recoilScale,
scaleY: recoilScale
}, {
duration: 100
});
tween(cannonGraphics, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
};
return self;
});
var SpeedButton = Container.expand(function () {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('speedButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.isActive = true;
self.cooldownTime = 0;
self.maxCooldown = 300; // 5 seconds at 60fps
// Pulse animation
var scale = 1;
var scaleDirection = 1;
self.update = function () {
if (self.isActive) {
scale += 0.01 * scaleDirection;
if (scale > 1.2) scaleDirection = -1;
if (scale < 0.8) scaleDirection = 1;
buttonGraphics.scaleX = scale;
buttonGraphics.scaleY = scale;
} else {
// Cooldown mode - grey out and countdown
self.cooldownTime--;
if (self.cooldownTime <= 0) {
self.isActive = true;
buttonGraphics.tint = 0xffffff;
buttonGraphics.alpha = 1;
}
}
};
self.down = function (x, y, obj) {
if (self.isActive && cannon) {
self.activateSpeedBoost();
}
};
self.activateSpeedBoost = function () {
if (!self.isActive) return;
self.isActive = false;
self.cooldownTime = self.maxCooldown;
buttonGraphics.tint = 0x666666;
buttonGraphics.alpha = 0.5;
// Apply speed boost to cannon
cannon.applySpeedBoost();
LK.getSound('speedBoost').play();
LK.effects.flashObject(self, 0xffff00, 300);
};
return self;
});
var Target = Container.expand(function () {
var self = Container.call(this);
var targetGraphics = self.attachAsset('target', {
anchorX: 0.5,
anchorY: 0.5
});
// Gentle pulse animation
var scale = 1;
var scaleDirection = 1;
self.update = function () {
scale += 0.005 * scaleDirection;
if (scale > 1.1) scaleDirection = -1;
if (scale < 0.9) scaleDirection = 1;
targetGraphics.scaleX = scale;
targetGraphics.scaleY = scale;
};
return self;
});
var TurboButton = Container.expand(function () {
var self = Container.call(this);
var buttonGraphics = self.attachAsset('turboButton', {
anchorX: 0.5,
anchorY: 0.5
});
self.isActive = true;
self.cooldownTime = 0;
self.maxCooldown = 600; // 10 seconds at 60fps
// Pulse animation
var scale = 1;
var scaleDirection = 1;
self.update = function () {
if (self.isActive) {
scale += 0.015 * scaleDirection;
if (scale > 1.3) scaleDirection = -1;
if (scale < 0.7) scaleDirection = 1;
buttonGraphics.scaleX = scale;
buttonGraphics.scaleY = scale;
// Turbo button glows
buttonGraphics.tint = 0x00ffff;
} else {
// Cooldown mode - grey out and countdown
self.cooldownTime--;
if (self.cooldownTime <= 0) {
self.isActive = true;
buttonGraphics.tint = 0x00ffff;
buttonGraphics.alpha = 1;
}
}
};
self.down = function (x, y, obj) {
if (self.isActive) {
self.activateTurbo();
}
};
self.activateTurbo = function () {
if (!self.isActive) return;
self.isActive = false;
self.cooldownTime = self.maxCooldown;
buttonGraphics.tint = 0x666666;
buttonGraphics.alpha = 0.5;
// Activate game-wide turbo mode
activateGameTurbo();
LK.getSound('turboActivate').play();
LK.effects.flashObject(self, 0x00ffff, 300);
};
return self;
});
var Wall = Container.expand(function () {
var self = Container.call(this);
var wallGraphics = self.attachAsset('wall', {
anchorX: 0,
anchorY: 0
});
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1a1a1a
});
/****
* Game Code
****/
// Game variables
var bullets = [];
var targets = [];
var walls = [];
var boundaryWalls = [];
var cannon;
var speedButton;
var barrierButton;
var turboButton;
var bulletsRemaining = 5;
var currentLevel = 1;
var gameSpeedMultiplier = 1;
var turboActive = false;
var turboTimeRemaining = 0;
// UI elements
var bulletCountText;
var levelText;
var scoreText;
// Initialize UI
function createBoundaryWalls() {
// Clear existing boundary walls
for (var i = 0; i < boundaryWalls.length; i++) {
boundaryWalls[i].destroy();
}
boundaryWalls = [];
// Top wall
var topWall = new Wall();
topWall.x = 0;
topWall.y = 0;
topWall.width = 2048;
topWall.height = 50;
boundaryWalls.push(topWall);
game.addChild(topWall);
// Bottom wall
var bottomWall = new Wall();
bottomWall.x = 0;
bottomWall.y = 2682;
bottomWall.width = 2048;
bottomWall.height = 50;
boundaryWalls.push(bottomWall);
game.addChild(bottomWall);
// Left wall
var leftWall = new Wall();
leftWall.x = 0;
leftWall.y = 0;
leftWall.width = 50;
leftWall.height = 2732;
boundaryWalls.push(leftWall);
game.addChild(leftWall);
// Right wall
var rightWall = new Wall();
rightWall.x = 1998;
rightWall.y = 0;
rightWall.width = 50;
rightWall.height = 2732;
boundaryWalls.push(rightWall);
game.addChild(rightWall);
}
function initializeUI() {
bulletCountText = new Text2('Bullets: ' + bulletsRemaining, {
size: 80,
fill: 0xFFFFFF
});
bulletCountText.anchor.set(0, 0);
bulletCountText.x = 120;
bulletCountText.y = 20;
LK.gui.topLeft.addChild(bulletCountText);
levelText = new Text2('Level ' + currentLevel, {
size: 80,
fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0);
LK.gui.top.addChild(levelText);
scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(1, 0);
scoreText.x = -20;
scoreText.y = 20;
LK.gui.topRight.addChild(scoreText);
// Create turbo button
turboButton = new TurboButton();
turboButton.x = 1800;
turboButton.y = 400;
game.addChild(turboButton);
}
function updateUI() {
bulletCountText.setText('Bullets: ' + bulletsRemaining);
scoreText.setText('Score: ' + LK.getScore());
}
// Level creation
function createLevel1() {
// Clear existing elements
clearLevel();
// Create cannon at bottom center
cannon = new Cannon();
cannon.x = 1024;
cannon.y = 2500;
game.addChild(cannon);
// No walls in this level - enemies are closer to player
// Create targets closer to player
var target1 = new Target();
target1.x = 800;
target1.y = 2200;
targets.push(target1);
game.addChild(target1);
var target2 = new Target();
target2.x = 1200;
target2.y = 2000;
targets.push(target2);
game.addChild(target2);
var target3 = new Target();
target3.x = 600;
target3.y = 1800;
targets.push(target3);
game.addChild(target3);
// Create turbo button for this level
turboButton = new TurboButton();
turboButton.x = 1800;
turboButton.y = 400;
game.addChild(turboButton);
// Reset game state
bulletsRemaining = 5;
updateUI();
}
function clearLevel() {
// Clear bullets
for (var i = 0; i < bullets.length; i++) {
bullets[i].destroy();
}
bullets = [];
// Clear targets
for (var i = 0; i < targets.length; i++) {
targets[i].destroy();
}
targets = [];
// Clear walls
for (var i = 0; i < walls.length; i++) {
walls[i].destroy();
}
walls = [];
// Clear cannon
if (cannon) {
cannon.destroy();
cannon = null;
}
// Clear speed button
if (speedButton) {
speedButton.destroy();
speedButton = null;
}
// Clear barrier button
if (barrierButton) {
barrierButton.destroy();
barrierButton = null;
}
// Clear turbo button
if (turboButton) {
turboButton.destroy();
turboButton = null;
}
}
function levelComplete() {
LK.effects.flashScreen(0x00ff00, 500);
LK.setTimeout(function () {
currentLevel++;
if (currentLevel <= 10) {
createNextLevel();
} else {
LK.showYouWin();
}
}, 1000);
}
function createNextLevel() {
levelText.setText('Level ' + currentLevel);
if (currentLevel === 2) {
createLevel2();
} else if (currentLevel === 3) {
createLevel3();
} else if (currentLevel === 4) {
createLevel4();
} else if (currentLevel === 5) {
createLevel5();
} else if (currentLevel === 6) {
createLevel6();
} else if (currentLevel === 7) {
createLevel7();
} else if (currentLevel === 8) {
createLevel8();
} else if (currentLevel === 9) {
createLevel9();
} else if (currentLevel === 10) {
createLevel10();
}
}
function createLevel2() {
clearLevel();
cannon = new Cannon();
cannon.x = 200;
cannon.y = 2500;
game.addChild(cannon);
// No walls - targets closer to player
var target1 = new Target();
target1.x = 500;
target1.y = 2000;
targets.push(target1);
game.addChild(target1);
var target2 = new Target();
target2.x = 1000;
target2.y = 2200;
targets.push(target2);
game.addChild(target2);
var target3 = new Target();
target3.x = 1500;
target3.y = 1900;
targets.push(target3);
game.addChild(target3);
var target4 = new Target();
target4.x = 700;
target4.y = 1700;
targets.push(target4);
game.addChild(target4);
// Create turbo button for this level
turboButton = new TurboButton();
turboButton.x = 1800;
turboButton.y = 400;
game.addChild(turboButton);
// Create turbo button for this level
turboButton = new TurboButton();
turboButton.x = 1800;
turboButton.y = 400;
game.addChild(turboButton);
bulletsRemaining = 6;
updateUI();
}
function createLevel3() {
clearLevel();
cannon = new Cannon();
cannon.x = 1024;
cannon.y = 2600;
game.addChild(cannon);
// No walls - many targets closer to player
var target1 = new Target();
target1.x = 400;
target1.y = 2100;
targets.push(target1);
game.addChild(target1);
var target2 = new Target();
target2.x = 800;
target2.y = 2000;
targets.push(target2);
game.addChild(target2);
var target3 = new Target();
target3.x = 1200;
target3.y = 1900;
targets.push(target3);
game.addChild(target3);
var target4 = new Target();
target4.x = 600;
target4.y = 1700;
targets.push(target4);
game.addChild(target4);
var target5 = new Target();
target5.x = 1000;
target5.y = 1600;
targets.push(target5);
game.addChild(target5);
// Create turbo button for this level
turboButton = new TurboButton();
turboButton.x = 1800;
turboButton.y = 400;
game.addChild(turboButton);
// Create turbo button for this level
turboButton = new TurboButton();
turboButton.x = 1800;
turboButton.y = 400;
game.addChild(turboButton);
bulletsRemaining = 7;
updateUI();
}
function createLevel4() {
clearLevel();
cannon = new Cannon();
cannon.x = 100;
cannon.y = 2400;
game.addChild(cannon);
// Circle formation of targets
var centerX = 1024;
var centerY = 1800;
var radius = 300;
for (var i = 0; i < 6; i++) {
var angle = i / 6 * 2 * Math.PI;
var target = new Target();
target.x = centerX + Math.cos(angle) * radius;
target.y = centerY + Math.sin(angle) * radius;
targets.push(target);
game.addChild(target);
}
// Additional center target
var centerTarget = new Target();
centerTarget.x = centerX;
centerTarget.y = centerY;
targets.push(centerTarget);
game.addChild(centerTarget);
// Create turbo button for this level
turboButton = new TurboButton();
turboButton.x = 1800;
turboButton.y = 400;
game.addChild(turboButton);
// Create turbo button for this level
turboButton = new TurboButton();
turboButton.x = 1800;
turboButton.y = 400;
game.addChild(turboButton);
bulletsRemaining = 8;
updateUI();
}
function createLevel5() {
clearLevel();
cannon = new Cannon();
cannon.x = 1700;
cannon.y = 2500;
game.addChild(cannon);
// Zigzag pattern of targets
var targets_positions = [{
x: 300,
y: 2200
}, {
x: 600,
y: 1900
}, {
x: 900,
y: 2100
}, {
x: 1200,
y: 1800
}, {
x: 1500,
y: 2000
}, {
x: 400,
y: 1600
}, {
x: 800,
y: 1400
}, {
x: 1100,
y: 1500
}, {
x: 1400,
y: 1300
}];
for (var i = 0; i < targets_positions.length; i++) {
var target = new Target();
target.x = targets_positions[i].x;
target.y = targets_positions[i].y;
targets.push(target);
game.addChild(target);
}
// Create turbo button for this level
turboButton = new TurboButton();
turboButton.x = 1800;
turboButton.y = 400;
game.addChild(turboButton);
bulletsRemaining = 10;
updateUI();
}
function activateGameTurbo() {
turboActive = true;
turboTimeRemaining = 180; // 3 seconds at 60fps
gameSpeedMultiplier = 2.5;
// Screen effect to indicate turbo mode
LK.effects.flashScreen(0x00ffff, 500);
// Use tween to smoothly transition speed back to normal
LK.setTimeout(function () {
tween(game, {
gameSpeedMultiplier: 1
}, {
duration: 500,
onFinish: function onFinish() {
turboActive = false;
gameSpeedMultiplier = 1;
}
});
}, 2500);
}
function gameOver() {
LK.effects.flashScreen(0xff0000, 1000);
LK.setTimeout(function () {
LK.showGameOver();
}, 1500);
}
// Touch controls
game.down = function (x, y, obj) {
if (cannon && bulletsRemaining > 0) {
cannon.startAiming(x, y);
}
};
game.move = function (x, y, obj) {
if (cannon && cannon.isAiming) {
cannon.updateAim(x, y);
}
};
game.up = function (x, y, obj) {
if (cannon && cannon.isAiming) {
cannon.shoot();
}
};
game.update = function () {
// Update turbo mode
if (turboActive && turboTimeRemaining > 0) {
turboTimeRemaining--;
}
// Update all bullets with speed multiplier
for (var i = bullets.length - 1; i >= 0; i--) {
var bullet = bullets[i];
if (bullet && bullet.active) {
// Apply turbo speed to bullets
if (turboActive) {
for (var j = 0; j < gameSpeedMultiplier; j++) {
bullet.update();
}
} else {
bullet.update();
}
}
}
// Update all targets with speed multiplier
for (var i = 0; i < targets.length; i++) {
if (turboActive) {
for (var j = 0; j < gameSpeedMultiplier; j++) {
targets[i].update();
}
} else {
targets[i].update();
}
}
// Update cannon speed boost
if (cannon) {
if (turboActive) {
for (var j = 0; j < gameSpeedMultiplier; j++) {
cannon.updateSpeedBoost();
}
} else {
cannon.updateSpeedBoost();
}
}
// Update turbo button
if (turboButton) {
turboButton.update();
}
};
// Initialize the game
initializeUI();
createBoundaryWalls();
createLevel1();
function createLevel6() {
clearLevel();
cannon = new Cannon();
cannon.x = 1024;
cannon.y = 2600;
game.addChild(cannon);
// Create wall barriers
var wall1 = new Wall();
wall1.x = 600;
wall1.y = 2200;
walls.push(wall1);
game.addChild(wall1);
var wall2 = new Wall();
wall2.x = 1200;
wall2.y = 2000;
walls.push(wall2);
game.addChild(wall2);
var wall3 = new Wall();
wall3.x = 400;
wall3.y = 1800;
walls.push(wall3);
game.addChild(wall3);
// Targets behind walls requiring ricochet
var target1 = new Target();
target1.x = 700;
target1.y = 2100;
targets.push(target1);
game.addChild(target1);
var target2 = new Target();
target2.x = 1300;
target2.y = 1900;
targets.push(target2);
game.addChild(target2);
var target3 = new Target();
target3.x = 500;
target3.y = 1700;
targets.push(target3);
game.addChild(target3);
bulletsRemaining = 6;
updateUI();
}
function createLevel7() {
clearLevel();
cannon = new Cannon();
cannon.x = 200;
cannon.y = 2400;
game.addChild(cannon);
// Create L-shaped wall formations
var wall1 = new Wall();
wall1.x = 800;
wall1.y = 2200;
walls.push(wall1);
game.addChild(wall1);
var wall2 = new Wall();
wall2.x = 800;
wall2.y = 2000;
walls.push(wall2);
game.addChild(wall2);
var wall3 = new Wall();
wall3.x = 1000;
wall3.y = 2000;
walls.push(wall3);
game.addChild(wall3);
var wall4 = new Wall();
wall4.x = 400;
wall4.y = 1600;
walls.push(wall4);
game.addChild(wall4);
var wall5 = new Wall();
wall5.x = 600;
wall5.y = 1600;
walls.push(wall5);
game.addChild(wall5);
// Targets in corners requiring multiple bounces
var target1 = new Target();
target1.x = 900;
target1.y = 2100;
targets.push(target1);
game.addChild(target1);
var target2 = new Target();
target2.x = 1100;
target2.y = 1900;
targets.push(target2);
game.addChild(target2);
var target3 = new Target();
target3.x = 500;
target3.y = 1500;
targets.push(target3);
game.addChild(target3);
var target4 = new Target();
target4.x = 700;
target4.y = 1500;
targets.push(target4);
game.addChild(target4);
bulletsRemaining = 7;
updateUI();
}
function createLevel8() {
clearLevel();
cannon = new Cannon();
cannon.x = 100;
cannon.y = 2300;
game.addChild(cannon);
// Create maze walls
var wall1 = new Wall();
wall1.x = 400;
wall1.y = 2200;
walls.push(wall1);
game.addChild(wall1);
var wall2 = new Wall();
wall2.x = 800;
wall2.y = 2300;
walls.push(wall2);
game.addChild(wall2);
var wall3 = new Wall();
wall3.x = 1200;
wall3.y = 2100;
walls.push(wall3);
game.addChild(wall3);
var wall4 = new Wall();
wall4.x = 600;
wall4.y = 1900;
walls.push(wall4);
game.addChild(wall4);
var wall5 = new Wall();
wall5.x = 1000;
wall5.y = 1800;
walls.push(wall5);
game.addChild(wall5);
var wall6 = new Wall();
wall6.x = 300;
wall6.y = 1600;
walls.push(wall6);
game.addChild(wall6);
var wall7 = new Wall();
wall7.x = 700;
wall7.y = 1500;
walls.push(wall7);
game.addChild(wall7);
// Targets requiring complex ricochet paths
var target1 = new Target();
target1.x = 500;
target1.y = 2100;
targets.push(target1);
game.addChild(target1);
var target2 = new Target();
target2.x = 900;
target2.y = 2200;
targets.push(target2);
game.addChild(target2);
var target3 = new Target();
target3.x = 1300;
target3.y = 2000;
targets.push(target3);
game.addChild(target3);
var target4 = new Target();
target4.x = 700;
target4.y = 1800;
targets.push(target4);
game.addChild(target4);
var target5 = new Target();
target5.x = 1100;
target5.y = 1700;
targets.push(target5);
game.addChild(target5);
bulletsRemaining = 8;
updateUI();
}
function createLevel9() {
clearLevel();
cannon = new Cannon();
cannon.x = 1800;
cannon.y = 2500;
game.addChild(cannon);
// Create narrow corridor walls
var wall1 = new Wall();
wall1.x = 400;
wall1.y = 2300;
walls.push(wall1);
game.addChild(wall1);
var wall2 = new Wall();
wall2.x = 400;
wall2.y = 1800;
walls.push(wall2);
game.addChild(wall2);
var wall3 = new Wall();
wall3.x = 800;
wall3.y = 2100;
walls.push(wall3);
game.addChild(wall3);
var wall4 = new Wall();
wall4.x = 800;
wall4.y = 1600;
walls.push(wall4);
game.addChild(wall4);
var wall5 = new Wall();
wall5.x = 1200;
wall5.y = 2200;
walls.push(wall5);
game.addChild(wall5);
var wall6 = new Wall();
wall6.x = 1200;
wall6.y = 1500;
walls.push(wall6);
game.addChild(wall6);
// Targets in narrow spaces
var target1 = new Target();
target1.x = 500;
target1.y = 2000;
targets.push(target1);
game.addChild(target1);
var target2 = new Target();
target2.x = 900;
target2.y = 1900;
targets.push(target2);
game.addChild(target2);
var target3 = new Target();
target3.x = 1300;
target3.y = 1800;
targets.push(target3);
game.addChild(target3);
var target4 = new Target();
target4.x = 700;
target4.y = 1400;
targets.push(target4);
game.addChild(target4);
var target5 = new Target();
target5.x = 1100;
target5.y = 1300;
targets.push(target5);
game.addChild(target5);
var target6 = new Target();
target6.x = 500;
target6.y = 1200;
targets.push(target6);
game.addChild(target6);
// Create turbo button for this level
turboButton = new TurboButton();
turboButton.x = 1800;
turboButton.y = 400;
game.addChild(turboButton);
bulletsRemaining = 9;
updateUI();
}
function createLevel10() {
clearLevel();
cannon = new Cannon();
cannon.x = 1024;
cannon.y = 2650;
game.addChild(cannon);
// Create complex wall structure
var wall1 = new Wall();
wall1.x = 300;
wall1.y = 2400;
walls.push(wall1);
game.addChild(wall1);
var wall2 = new Wall();
wall2.x = 700;
wall2.y = 2400;
walls.push(wall2);
game.addChild(wall2);
var wall3 = new Wall();
wall3.x = 1100;
wall3.y = 2400;
walls.push(wall3);
game.addChild(wall3);
var wall4 = new Wall();
wall4.x = 1500;
wall4.y = 2400;
walls.push(wall4);
game.addChild(wall4);
var wall5 = new Wall();
wall5.x = 200;
wall5.y = 2000;
walls.push(wall5);
game.addChild(wall5);
var wall6 = new Wall();
wall6.x = 600;
wall6.y = 2100;
walls.push(wall6);
game.addChild(wall6);
var wall7 = new Wall();
wall7.x = 1000;
wall7.y = 2000;
walls.push(wall7);
game.addChild(wall7);
var wall8 = new Wall();
wall8.x = 1400;
wall8.y = 2100;
walls.push(wall8);
game.addChild(wall8);
var wall9 = new Wall();
wall9.x = 400;
wall9.y = 1700;
walls.push(wall9);
game.addChild(wall9);
var wall10 = new Wall();
wall10.x = 800;
wall10.y = 1600;
walls.push(wall10);
game.addChild(wall10);
var wall11 = new Wall();
wall11.x = 1200;
wall11.y = 1700;
walls.push(wall11);
game.addChild(wall11);
// Final challenge targets
var target1 = new Target();
target1.x = 400;
target1.y = 2300;
targets.push(target1);
game.addChild(target1);
var target2 = new Target();
target2.x = 800;
target2.y = 2300;
targets.push(target2);
game.addChild(target2);
var target3 = new Target();
target3.x = 1200;
target3.y = 2300;
targets.push(target3);
game.addChild(target3);
var target4 = new Target();
target4.x = 300;
target4.y = 1900;
targets.push(target4);
game.addChild(target4);
var target5 = new Target();
target5.x = 700;
target5.y = 2000;
targets.push(target5);
game.addChild(target5);
var target6 = new Target();
target6.x = 1100;
target6.y = 1900;
targets.push(target6);
game.addChild(target6);
var target7 = new Target();
target7.x = 1500;
target7.y = 2000;
targets.push(target7);
game.addChild(target7);
var target8 = new Target();
target8.x = 500;
target8.y = 1600;
targets.push(target8);
game.addChild(target8);
var target9 = new Target();
target9.x = 900;
target9.y = 1500;
targets.push(target9);
game.addChild(target9);
var target10 = new Target();
target10.x = 1300;
target10.y = 1600;
targets.push(target10);
game.addChild(target10);
// Create turbo button for this level
turboButton = new TurboButton();
turboButton.x = 1800;
turboButton.y = 400;
game.addChild(turboButton);
bulletsRemaining = 12;
updateUI();
}
;
Anormal human. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
A paintballer. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
A paintball ball. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat