/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.damage = 5;
self.directionX = 0;
self.directionY = 1;
self.update = function () {
self.x += self.directionX * self.speed;
self.y += self.directionY * self.speed;
};
return self;
});
var EnemyTank = Container.expand(function () {
var self = Container.call(this);
var hull = self.attachAsset('enemyTank', {
anchorX: 0.5,
anchorY: 0.5
});
var turret = self.attachAsset('enemyTurret', {
anchorX: 0.1,
anchorY: 0.5
});
self.health = 60;
self.maxHealth = 60;
self.speed = 1.5 + (Math.random() * 2 - 1); // Random speed between 0.5 and 2.5
self.lastFireTime = 0;
self.fireRate = 5000;
self.lastMoveTime = 0;
self.moveInterval = 2000;
self.targetX = self.x;
self.targetY = self.y;
// Create health bar
self.healthBarBg = self.attachAsset('enemyTank', {
anchorX: 0.5,
anchorY: 0.5,
width: 80,
height: 8
});
self.healthBarBg.tint = 0xFF0000;
self.healthBarBg.x = 0;
self.healthBarBg.y = -50;
self.healthBarFg = self.attachAsset('enemyTank', {
anchorX: 0,
anchorY: 0.5,
width: 80,
height: 6
});
self.healthBarFg.tint = 0x00FF00;
self.healthBarFg.x = -40;
self.healthBarFg.y = -50;
self.update = function () {
// Move towards target position
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
hull.rotation = Math.atan2(dy, dx);
}
// Set new random target occasionally
if (Date.now() - self.lastMoveTime > self.moveInterval) {
self.lastMoveTime = Date.now();
self.targetX = Math.random() * 1800 + 124;
self.targetY = Math.random() * 2400 + 166;
}
// Aim at player
if (playerTank) {
var playerDx = playerTank.x - self.x;
var playerDy = playerTank.y - self.y;
var playerDistance = Math.sqrt(playerDx * playerDx + playerDy * playerDy);
if (playerDistance < 800) {
turret.rotation = Math.atan2(playerDy, playerDx);
// Fire at player
if (Date.now() - self.lastFireTime > self.fireRate) {
self.lastFireTime = Date.now();
var bullet = new EnemyBullet();
// Position bullet at turret tip
var turretLength = 70;
bullet.x = self.x + Math.cos(turret.rotation) * turretLength;
bullet.y = self.y + Math.sin(turret.rotation) * turretLength;
// Set bullet direction towards player
bullet.directionX = playerDx / playerDistance;
bullet.directionY = playerDy / playerDistance;
enemyBullets.push(bullet);
game.addChild(bullet);
}
}
}
// Update health bar
var healthPercent = self.health / self.maxHealth;
self.healthBarFg.width = 80 * healthPercent;
if (healthPercent > 0.6) {
self.healthBarFg.tint = 0x00FF00; // Green
} else if (healthPercent > 0.3) {
self.healthBarFg.tint = 0xFFFF00; // Yellow
} else {
self.healthBarFg.tint = 0xFF0000; // Red
}
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xff0000, 200);
if (self.health <= 0) {
// Create explosion
var explosion = game.addChild(LK.getAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5
}));
explosion.x = self.x;
explosion.y = self.y;
tween(explosion, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
explosion.destroy();
}
});
LK.getSound('explosion').play();
LK.setScore(LK.getScore() + 100);
scoreText.setText(LK.getScore());
// Remove from parent and mark for removal
self.destroy();
return true; // Tank destroyed
}
return false;
};
return self;
});
var GroundMarker = Container.expand(function () {
var self = Container.call(this);
var arrowGraphics = self.attachAsset('arrow', {
anchorX: 0.5,
anchorY: 1.0
});
// Rotate to point downward
arrowGraphics.rotation = Math.PI;
// Start with full opacity
self.alpha = 1.0;
// Animate the marker to fade out over 1 second
tween(self, {
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
self.destroy();
}
});
return self;
});
var PlayerBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('playerBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.damage = 25;
self.directionX = 0;
self.directionY = -1;
self.update = function () {
self.x += self.directionX * self.speed;
self.y += self.directionY * self.speed;
};
return self;
});
var PlayerTank = Container.expand(function () {
var self = Container.call(this);
var hull = self.attachAsset('playerTank', {
anchorX: 0.5,
anchorY: 0.5
});
var turret = self.attachAsset('playerTurret', {
anchorX: 0.1,
anchorY: 0.5
});
self.health = 100;
self.maxHealth = 100;
self.speed = 3;
self.turretRotation = 0;
self.lastFireTime = 0;
self.fireRate = 5000; // milliseconds between shots
self.moveTo = function (targetX, targetY) {
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
// Rotate hull to face movement direction
hull.rotation = Math.atan2(dy, dx);
}
};
self.aimTurret = function (targetX, targetY) {
var dx = targetX - self.x;
var dy = targetY - self.y;
self.turretRotation = Math.atan2(dy, dx);
turret.rotation = self.turretRotation;
};
self.canFire = function () {
return Date.now() - self.lastFireTime > self.fireRate;
};
self.fire = function () {
if (self.canFire()) {
self.lastFireTime = Date.now();
var bullet = new PlayerBullet();
// Position bullet at turret tip
var turretLength = 80;
bullet.x = self.x + Math.cos(self.turretRotation) * turretLength;
bullet.y = self.y + Math.sin(self.turretRotation) * turretLength;
// Set bullet direction based on turret rotation
bullet.directionX = Math.cos(self.turretRotation);
bullet.directionY = Math.sin(self.turretRotation);
playerBullets.push(bullet);
game.addChild(bullet);
LK.getSound('tankFire').play();
}
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xff0000, 300);
if (self.health <= 0) {
self.destroy();
LK.showGameOver();
}
};
return self;
});
var ReloadIndicator = Container.expand(function () {
var self = Container.call(this);
// Create background circle
self.bgCircle = self.attachAsset('enemyTank', {
anchorX: 0.5,
anchorY: 0.5,
width: 100,
height: 100
});
self.bgCircle.tint = 0x444444;
// Create progress circle
self.progressCircle = self.attachAsset('enemyTank', {
anchorX: 0.5,
anchorY: 0.5,
width: 92,
height: 92
});
self.progressCircle.tint = 0x00FF00;
// Create ready text
self.readyText = new Text2('READY', {
size: 40,
fill: 0x00FF00
});
self.readyText.anchor.set(0.5, 0.5);
self.addChild(self.readyText);
self.updateProgress = function (progress, isReady) {
if (isReady) {
self.progressCircle.visible = false;
self.readyText.visible = true;
self.bgCircle.tint = 0x00AA00;
} else {
self.progressCircle.visible = true;
self.readyText.visible = false;
self.bgCircle.tint = 0x444444;
// Scale progress circle based on reload progress
var scale = progress;
self.progressCircle.scaleX = scale;
self.progressCircle.scaleY = scale;
// Color transition from red to green
var red = Math.floor(255 * (1 - progress));
var green = Math.floor(255 * progress);
self.progressCircle.tint = red << 16 | green << 8 | 0;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x3d5a27
});
/****
* Game Code
****/
var playerTank = null;
var enemyTanks = [];
var playerBullets = [];
var enemyBullets = [];
var gameStartTime = Date.now();
var lastEnemySpawn = 0;
var enemySpawnRate = 3000;
var maxEnemies = 4;
// UI Elements
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreText);
scoreText.x = -200;
scoreText.y = 20;
var healthText = new Text2('Health: 100', {
size: 60,
fill: 0xFF0000
});
healthText.anchor.set(0, 0);
LK.gui.bottomLeft.addChild(healthText);
healthText.x = 20;
healthText.y = -80;
// Reload indicator that follows cursor
var reloadIndicator = game.addChild(new ReloadIndicator());
var periscopeText = new Text2('Periscope: --', {
size: 50,
fill: 0x00FFFF
});
periscopeText.anchor.set(0, 0);
LK.gui.bottomLeft.addChild(periscopeText);
periscopeText.x = 20;
periscopeText.y = -140;
// Create player tank
playerTank = game.addChild(new PlayerTank());
playerTank.x = 1024;
playerTank.y = 2200;
// Touch controls
var targetX = playerTank.x;
var targetY = playerTank.y;
var aimX = playerTank.x;
var aimY = playerTank.y;
game.down = function (x, y, obj) {
targetX = x;
targetY = y;
aimX = x;
aimY = y;
// Create ground marker at click position
var marker = new GroundMarker();
marker.x = x;
marker.y = y;
game.addChild(marker);
};
game.move = function (x, y, obj) {
aimX = x;
aimY = y;
};
game.up = function (x, y, obj) {
if (playerTank) {
playerTank.fire();
}
};
game.update = function () {
if (!playerTank) return;
// Update player tank
playerTank.moveTo(targetX, targetY);
playerTank.aimTurret(aimX, aimY);
// Update health display
healthText.setText('Health: ' + playerTank.health);
// Update reload indicator position and progress
reloadIndicator.x = aimX - 80; // Position to the left of cursor
reloadIndicator.y = aimY - 30; // Slightly above cursor
// Keep indicator within screen bounds
reloadIndicator.x = Math.max(50, Math.min(1998, reloadIndicator.x));
reloadIndicator.y = Math.max(50, Math.min(2682, reloadIndicator.y));
var timeSinceLastFire = Date.now() - playerTank.lastFireTime;
var remainingCooldown = Math.max(0, playerTank.fireRate - timeSinceLastFire);
var progress = 1 - remainingCooldown / playerTank.fireRate;
var isReady = remainingCooldown <= 0;
reloadIndicator.updateProgress(progress, isReady);
// Update periscope display - calculate bullet travel time to target
var distanceToTarget = Math.sqrt((aimX - playerTank.x) * (aimX - playerTank.x) + (aimY - playerTank.y) * (aimY - playerTank.y));
var bulletSpeed = 8; // PlayerBullet speed
var travelTime = distanceToTarget / bulletSpeed / 60; // Convert to seconds (60 FPS)
periscopeText.setText('Periscope: ' + travelTime.toFixed(1) + 's');
// Spawn enemies
if (Date.now() - lastEnemySpawn > enemySpawnRate && enemyTanks.length < maxEnemies) {
lastEnemySpawn = Date.now();
var enemy = new EnemyTank();
// Spawn at random edge
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
// Top
enemy.x = Math.random() * 1800 + 124;
enemy.y = 100;
break;
case 1:
// Right
enemy.x = 1900;
enemy.y = Math.random() * 2400 + 166;
break;
case 2:
// Bottom
enemy.x = Math.random() * 1800 + 124;
enemy.y = 2600;
break;
case 3:
// Left
enemy.x = 148;
enemy.y = Math.random() * 2400 + 166;
break;
}
enemyTanks.push(enemy);
game.addChild(enemy);
// Increase difficulty over time
var timeElapsed = Date.now() - gameStartTime;
if (timeElapsed > 30000) {
// After 30 seconds
enemySpawnRate = Math.max(1500, enemySpawnRate - 50);
maxEnemies = Math.min(8, maxEnemies + 1);
}
}
// Update player bullets
for (var i = playerBullets.length - 1; i >= 0; i--) {
var bullet = playerBullets[i];
// Check if bullet is off screen
if (bullet.x < 0 || bullet.x > 2048 || bullet.y < 0 || bullet.y > 2732) {
bullet.destroy();
playerBullets.splice(i, 1);
continue;
}
// Check collision with enemies
var hitEnemy = false;
for (var j = enemyTanks.length - 1; j >= 0; j--) {
var enemy = enemyTanks[j];
if (bullet.intersects(enemy)) {
if (enemy.takeDamage(bullet.damage)) {
enemyTanks.splice(j, 1);
}
bullet.destroy();
playerBullets.splice(i, 1);
hitEnemy = true;
break;
}
}
}
// Update enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var bullet = enemyBullets[i];
// Check if bullet is off screen
if (bullet.x < 0 || bullet.x > 2048 || bullet.y < 0 || bullet.y > 2732) {
bullet.destroy();
enemyBullets.splice(i, 1);
continue;
}
// Check collision with player
if (bullet.intersects(playerTank)) {
playerTank.takeDamage(bullet.damage);
bullet.destroy();
enemyBullets.splice(i, 1);
}
}
// Remove destroyed enemy tanks
for (var i = enemyTanks.length - 1; i >= 0; i--) {
var enemy = enemyTanks[i];
if (!enemy.parent) {
enemyTanks.splice(i, 1);
}
}
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 6;
self.damage = 5;
self.directionX = 0;
self.directionY = 1;
self.update = function () {
self.x += self.directionX * self.speed;
self.y += self.directionY * self.speed;
};
return self;
});
var EnemyTank = Container.expand(function () {
var self = Container.call(this);
var hull = self.attachAsset('enemyTank', {
anchorX: 0.5,
anchorY: 0.5
});
var turret = self.attachAsset('enemyTurret', {
anchorX: 0.1,
anchorY: 0.5
});
self.health = 60;
self.maxHealth = 60;
self.speed = 1.5 + (Math.random() * 2 - 1); // Random speed between 0.5 and 2.5
self.lastFireTime = 0;
self.fireRate = 5000;
self.lastMoveTime = 0;
self.moveInterval = 2000;
self.targetX = self.x;
self.targetY = self.y;
// Create health bar
self.healthBarBg = self.attachAsset('enemyTank', {
anchorX: 0.5,
anchorY: 0.5,
width: 80,
height: 8
});
self.healthBarBg.tint = 0xFF0000;
self.healthBarBg.x = 0;
self.healthBarBg.y = -50;
self.healthBarFg = self.attachAsset('enemyTank', {
anchorX: 0,
anchorY: 0.5,
width: 80,
height: 6
});
self.healthBarFg.tint = 0x00FF00;
self.healthBarFg.x = -40;
self.healthBarFg.y = -50;
self.update = function () {
// Move towards target position
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
hull.rotation = Math.atan2(dy, dx);
}
// Set new random target occasionally
if (Date.now() - self.lastMoveTime > self.moveInterval) {
self.lastMoveTime = Date.now();
self.targetX = Math.random() * 1800 + 124;
self.targetY = Math.random() * 2400 + 166;
}
// Aim at player
if (playerTank) {
var playerDx = playerTank.x - self.x;
var playerDy = playerTank.y - self.y;
var playerDistance = Math.sqrt(playerDx * playerDx + playerDy * playerDy);
if (playerDistance < 800) {
turret.rotation = Math.atan2(playerDy, playerDx);
// Fire at player
if (Date.now() - self.lastFireTime > self.fireRate) {
self.lastFireTime = Date.now();
var bullet = new EnemyBullet();
// Position bullet at turret tip
var turretLength = 70;
bullet.x = self.x + Math.cos(turret.rotation) * turretLength;
bullet.y = self.y + Math.sin(turret.rotation) * turretLength;
// Set bullet direction towards player
bullet.directionX = playerDx / playerDistance;
bullet.directionY = playerDy / playerDistance;
enemyBullets.push(bullet);
game.addChild(bullet);
}
}
}
// Update health bar
var healthPercent = self.health / self.maxHealth;
self.healthBarFg.width = 80 * healthPercent;
if (healthPercent > 0.6) {
self.healthBarFg.tint = 0x00FF00; // Green
} else if (healthPercent > 0.3) {
self.healthBarFg.tint = 0xFFFF00; // Yellow
} else {
self.healthBarFg.tint = 0xFF0000; // Red
}
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xff0000, 200);
if (self.health <= 0) {
// Create explosion
var explosion = game.addChild(LK.getAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5
}));
explosion.x = self.x;
explosion.y = self.y;
tween(explosion, {
scaleX: 2,
scaleY: 2,
alpha: 0
}, {
duration: 500,
onFinish: function onFinish() {
explosion.destroy();
}
});
LK.getSound('explosion').play();
LK.setScore(LK.getScore() + 100);
scoreText.setText(LK.getScore());
// Remove from parent and mark for removal
self.destroy();
return true; // Tank destroyed
}
return false;
};
return self;
});
var GroundMarker = Container.expand(function () {
var self = Container.call(this);
var arrowGraphics = self.attachAsset('arrow', {
anchorX: 0.5,
anchorY: 1.0
});
// Rotate to point downward
arrowGraphics.rotation = Math.PI;
// Start with full opacity
self.alpha = 1.0;
// Animate the marker to fade out over 1 second
tween(self, {
alpha: 0
}, {
duration: 1000,
onFinish: function onFinish() {
self.destroy();
}
});
return self;
});
var PlayerBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('playerBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 8;
self.damage = 25;
self.directionX = 0;
self.directionY = -1;
self.update = function () {
self.x += self.directionX * self.speed;
self.y += self.directionY * self.speed;
};
return self;
});
var PlayerTank = Container.expand(function () {
var self = Container.call(this);
var hull = self.attachAsset('playerTank', {
anchorX: 0.5,
anchorY: 0.5
});
var turret = self.attachAsset('playerTurret', {
anchorX: 0.1,
anchorY: 0.5
});
self.health = 100;
self.maxHealth = 100;
self.speed = 3;
self.turretRotation = 0;
self.lastFireTime = 0;
self.fireRate = 5000; // milliseconds between shots
self.moveTo = function (targetX, targetY) {
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
// Rotate hull to face movement direction
hull.rotation = Math.atan2(dy, dx);
}
};
self.aimTurret = function (targetX, targetY) {
var dx = targetX - self.x;
var dy = targetY - self.y;
self.turretRotation = Math.atan2(dy, dx);
turret.rotation = self.turretRotation;
};
self.canFire = function () {
return Date.now() - self.lastFireTime > self.fireRate;
};
self.fire = function () {
if (self.canFire()) {
self.lastFireTime = Date.now();
var bullet = new PlayerBullet();
// Position bullet at turret tip
var turretLength = 80;
bullet.x = self.x + Math.cos(self.turretRotation) * turretLength;
bullet.y = self.y + Math.sin(self.turretRotation) * turretLength;
// Set bullet direction based on turret rotation
bullet.directionX = Math.cos(self.turretRotation);
bullet.directionY = Math.sin(self.turretRotation);
playerBullets.push(bullet);
game.addChild(bullet);
LK.getSound('tankFire').play();
}
};
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xff0000, 300);
if (self.health <= 0) {
self.destroy();
LK.showGameOver();
}
};
return self;
});
var ReloadIndicator = Container.expand(function () {
var self = Container.call(this);
// Create background circle
self.bgCircle = self.attachAsset('enemyTank', {
anchorX: 0.5,
anchorY: 0.5,
width: 100,
height: 100
});
self.bgCircle.tint = 0x444444;
// Create progress circle
self.progressCircle = self.attachAsset('enemyTank', {
anchorX: 0.5,
anchorY: 0.5,
width: 92,
height: 92
});
self.progressCircle.tint = 0x00FF00;
// Create ready text
self.readyText = new Text2('READY', {
size: 40,
fill: 0x00FF00
});
self.readyText.anchor.set(0.5, 0.5);
self.addChild(self.readyText);
self.updateProgress = function (progress, isReady) {
if (isReady) {
self.progressCircle.visible = false;
self.readyText.visible = true;
self.bgCircle.tint = 0x00AA00;
} else {
self.progressCircle.visible = true;
self.readyText.visible = false;
self.bgCircle.tint = 0x444444;
// Scale progress circle based on reload progress
var scale = progress;
self.progressCircle.scaleX = scale;
self.progressCircle.scaleY = scale;
// Color transition from red to green
var red = Math.floor(255 * (1 - progress));
var green = Math.floor(255 * progress);
self.progressCircle.tint = red << 16 | green << 8 | 0;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x3d5a27
});
/****
* Game Code
****/
var playerTank = null;
var enemyTanks = [];
var playerBullets = [];
var enemyBullets = [];
var gameStartTime = Date.now();
var lastEnemySpawn = 0;
var enemySpawnRate = 3000;
var maxEnemies = 4;
// UI Elements
var scoreText = new Text2('Score: 0', {
size: 60,
fill: 0xFFFFFF
});
scoreText.anchor.set(0, 0);
LK.gui.topRight.addChild(scoreText);
scoreText.x = -200;
scoreText.y = 20;
var healthText = new Text2('Health: 100', {
size: 60,
fill: 0xFF0000
});
healthText.anchor.set(0, 0);
LK.gui.bottomLeft.addChild(healthText);
healthText.x = 20;
healthText.y = -80;
// Reload indicator that follows cursor
var reloadIndicator = game.addChild(new ReloadIndicator());
var periscopeText = new Text2('Periscope: --', {
size: 50,
fill: 0x00FFFF
});
periscopeText.anchor.set(0, 0);
LK.gui.bottomLeft.addChild(periscopeText);
periscopeText.x = 20;
periscopeText.y = -140;
// Create player tank
playerTank = game.addChild(new PlayerTank());
playerTank.x = 1024;
playerTank.y = 2200;
// Touch controls
var targetX = playerTank.x;
var targetY = playerTank.y;
var aimX = playerTank.x;
var aimY = playerTank.y;
game.down = function (x, y, obj) {
targetX = x;
targetY = y;
aimX = x;
aimY = y;
// Create ground marker at click position
var marker = new GroundMarker();
marker.x = x;
marker.y = y;
game.addChild(marker);
};
game.move = function (x, y, obj) {
aimX = x;
aimY = y;
};
game.up = function (x, y, obj) {
if (playerTank) {
playerTank.fire();
}
};
game.update = function () {
if (!playerTank) return;
// Update player tank
playerTank.moveTo(targetX, targetY);
playerTank.aimTurret(aimX, aimY);
// Update health display
healthText.setText('Health: ' + playerTank.health);
// Update reload indicator position and progress
reloadIndicator.x = aimX - 80; // Position to the left of cursor
reloadIndicator.y = aimY - 30; // Slightly above cursor
// Keep indicator within screen bounds
reloadIndicator.x = Math.max(50, Math.min(1998, reloadIndicator.x));
reloadIndicator.y = Math.max(50, Math.min(2682, reloadIndicator.y));
var timeSinceLastFire = Date.now() - playerTank.lastFireTime;
var remainingCooldown = Math.max(0, playerTank.fireRate - timeSinceLastFire);
var progress = 1 - remainingCooldown / playerTank.fireRate;
var isReady = remainingCooldown <= 0;
reloadIndicator.updateProgress(progress, isReady);
// Update periscope display - calculate bullet travel time to target
var distanceToTarget = Math.sqrt((aimX - playerTank.x) * (aimX - playerTank.x) + (aimY - playerTank.y) * (aimY - playerTank.y));
var bulletSpeed = 8; // PlayerBullet speed
var travelTime = distanceToTarget / bulletSpeed / 60; // Convert to seconds (60 FPS)
periscopeText.setText('Periscope: ' + travelTime.toFixed(1) + 's');
// Spawn enemies
if (Date.now() - lastEnemySpawn > enemySpawnRate && enemyTanks.length < maxEnemies) {
lastEnemySpawn = Date.now();
var enemy = new EnemyTank();
// Spawn at random edge
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
// Top
enemy.x = Math.random() * 1800 + 124;
enemy.y = 100;
break;
case 1:
// Right
enemy.x = 1900;
enemy.y = Math.random() * 2400 + 166;
break;
case 2:
// Bottom
enemy.x = Math.random() * 1800 + 124;
enemy.y = 2600;
break;
case 3:
// Left
enemy.x = 148;
enemy.y = Math.random() * 2400 + 166;
break;
}
enemyTanks.push(enemy);
game.addChild(enemy);
// Increase difficulty over time
var timeElapsed = Date.now() - gameStartTime;
if (timeElapsed > 30000) {
// After 30 seconds
enemySpawnRate = Math.max(1500, enemySpawnRate - 50);
maxEnemies = Math.min(8, maxEnemies + 1);
}
}
// Update player bullets
for (var i = playerBullets.length - 1; i >= 0; i--) {
var bullet = playerBullets[i];
// Check if bullet is off screen
if (bullet.x < 0 || bullet.x > 2048 || bullet.y < 0 || bullet.y > 2732) {
bullet.destroy();
playerBullets.splice(i, 1);
continue;
}
// Check collision with enemies
var hitEnemy = false;
for (var j = enemyTanks.length - 1; j >= 0; j--) {
var enemy = enemyTanks[j];
if (bullet.intersects(enemy)) {
if (enemy.takeDamage(bullet.damage)) {
enemyTanks.splice(j, 1);
}
bullet.destroy();
playerBullets.splice(i, 1);
hitEnemy = true;
break;
}
}
}
// Update enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var bullet = enemyBullets[i];
// Check if bullet is off screen
if (bullet.x < 0 || bullet.x > 2048 || bullet.y < 0 || bullet.y > 2732) {
bullet.destroy();
enemyBullets.splice(i, 1);
continue;
}
// Check collision with player
if (bullet.intersects(playerTank)) {
playerTank.takeDamage(bullet.damage);
bullet.destroy();
enemyBullets.splice(i, 1);
}
}
// Remove destroyed enemy tanks
for (var i = enemyTanks.length - 1; i >= 0; i--) {
var enemy = enemyTanks[i];
if (!enemy.parent) {
enemyTanks.splice(i, 1);
}
}
};
its the view of a tank turret, but from its top. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
its a tanks hulls top view. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
cartoony explosion effect . No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
a turretless tank, colour:#f5deb3. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat