/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Building = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('building', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 100;
self.takeDamage = function (damage) {
self.health -= damage;
graphics.alpha = self.health / 100;
if (self.health <= 0) {
return true;
}
return false;
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 10;
self.damage = 20;
self.vx = 0;
self.vy = 0;
self.setDirection = function (angle) {
self.vx = Math.cos(angle) * self.speed;
self.vy = Math.sin(angle) * self.speed;
graphics.rotation = angle + Math.PI / 2;
};
self.update = function () {
self.x += self.vx;
self.y += self.vy;
};
return self;
});
var EnemyTank = Container.expand(function () {
var self = Container.call(this);
var body = self.attachAsset('enemyTank', {
anchorX: 0.5,
anchorY: 0.5
});
var turret = self.attachAsset('enemyTurret', {
anchorX: 0.5,
anchorY: 0.8
});
self.speed = 2;
self.health = 50;
self.fireRate = 60;
self.fireTimer = 0;
self.targetX = 0;
self.targetY = 0;
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xffffff, 200);
if (self.health <= 0) {
return true;
}
return false;
};
self.update = function () {
if (!playerTank) return;
var dx = playerTank.x - self.x;
var dy = playerTank.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 300) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
var angle = Math.atan2(dy, dx);
body.rotation = angle + Math.PI / 2;
turret.rotation = angle + Math.PI / 2;
if (self.fireTimer > 0) self.fireTimer--;
if (self.fireTimer <= 0 && distance < 800) {
var bullet = new EnemyBullet();
bullet.x = self.x;
bullet.y = self.y;
bullet.setDirection(angle);
enemyBullets.push(bullet);
game.addChild(bullet);
self.fireTimer = self.fireRate;
}
};
return self;
});
var ExplosiveBarrel = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('explosiveBarrel', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 20;
self.exploded = false;
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xffff00, 200);
if (self.health <= 0 && !self.exploded) {
self.explode();
return true;
}
return false;
};
self.explode = function () {
self.exploded = true;
LK.getSound('explosion').play();
LK.effects.flashScreen(0xff6347, 300);
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 200) {
if (enemy.takeDamage(50)) {
enemy.destroy();
enemies.splice(i, 1);
score += 100;
}
}
}
for (var i = turrets.length - 1; i >= 0; i--) {
var turret = turrets[i];
var dx = turret.x - self.x;
var dy = turret.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 200) {
if (turret.takeDamage(50)) {
turret.destroy();
turrets.splice(i, 1);
score += 150;
}
}
}
};
return self;
});
var PlayerBullet = Container.expand(function () {
var self = Container.call(this);
var graphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 15;
self.damage = 25;
self.vx = 0;
self.vy = 0;
self.setDirection = function (angle) {
self.vx = Math.cos(angle) * self.speed;
self.vy = Math.sin(angle) * self.speed;
graphics.rotation = angle + Math.PI / 2;
};
self.update = function () {
self.x += self.vx;
self.y += self.vy;
};
return self;
});
var PlayerTank = Container.expand(function () {
var self = Container.call(this);
var body = self.attachAsset('playerTank', {
anchorX: 0.5,
anchorY: 0.5
});
var turret = self.attachAsset('tankTurret', {
anchorX: 0.5,
anchorY: 0.8
});
self.speed = 5;
self.health = 100;
self.maxHealth = 100;
self.fireRate = 20;
self.fireTimer = 0;
self.rapidFireTimer = 0;
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xff0000, 300);
if (self.health <= 0) {
self.health = 0;
return true;
}
return false;
};
self.heal = function (amount) {
self.health = Math.min(self.health + amount, self.maxHealth);
};
self.enableRapidFire = function () {
self.rapidFireTimer = 300;
};
self.update = function () {
if (self.fireTimer > 0) self.fireTimer--;
if (self.rapidFireTimer > 0) self.rapidFireTimer--;
var effectiveFireRate = self.rapidFireTimer > 0 ? 5 : self.fireRate;
if (self.fireTimer <= 0) {
var nearestEnemy = findNearestEnemy(self.x, self.y);
if (nearestEnemy) {
var angle = Math.atan2(nearestEnemy.y - self.y, nearestEnemy.x - self.x);
turret.rotation = angle + Math.PI / 2;
var bullet = new PlayerBullet();
bullet.x = self.x;
bullet.y = self.y;
bullet.setDirection(angle);
playerBullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
self.fireTimer = effectiveFireRate;
}
}
};
return self;
});
var PowerUp = Container.expand(function (type) {
var self = Container.call(this);
self.type = type;
var graphics = self.attachAsset(type === 'health' ? 'powerupHealth' : 'powerupRapidFire', {
anchorX: 0.5,
anchorY: 0.5
});
self.collected = false;
self.lifetime = 600;
self.update = function () {
self.lifetime--;
if (self.lifetime < 120) {
graphics.alpha = 0.5 + 0.5 * Math.sin(self.lifetime * 0.2);
}
};
return self;
});
var Turret = Container.expand(function () {
var self = Container.call(this);
var base = self.attachAsset('turret', {
anchorX: 0.5,
anchorY: 0.5
});
var barrel = self.attachAsset('enemyTurret', {
anchorX: 0.5,
anchorY: 0.8
});
self.health = 75;
self.fireRate = 90;
self.fireTimer = 0;
self.range = 600;
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xffffff, 200);
if (self.health <= 0) {
return true;
}
return false;
};
self.update = function () {
if (!playerTank) return;
var dx = playerTank.x - self.x;
var dy = playerTank.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < self.range) {
var angle = Math.atan2(dy, dx);
barrel.rotation = angle + Math.PI / 2;
if (self.fireTimer > 0) self.fireTimer--;
if (self.fireTimer <= 0) {
var bullet = new EnemyBullet();
bullet.x = self.x;
bullet.y = self.y;
bullet.setDirection(angle);
enemyBullets.push(bullet);
game.addChild(bullet);
self.fireTimer = self.fireRate;
}
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x228B22
});
/****
* Game Code
****/
var playerTank;
var enemies = [];
var turrets = [];
var playerBullets = [];
var enemyBullets = [];
var powerUps = [];
var buildings = [];
var barrels = [];
var score = 0;
var wave = 1;
var enemiesPerWave = 3;
var enemiesSpawned = 0;
var waveTimer = 0;
var highScore = storage.highScore || 0;
var scoreTxt = new Text2('Score: 0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var waveTxt = new Text2('Wave 1', {
size: 100,
fill: 0xFFFF00
});
waveTxt.anchor.set(0.5, 0);
waveTxt.y = 100;
LK.gui.top.addChild(waveTxt);
var healthBar = new Container();
healthBar.x = 150;
healthBar.y = 50;
LK.gui.topRight.addChild(healthBar);
var healthBarBg = LK.getAsset('building', {
width: 200,
height: 30,
tint: 0x333333
});
healthBar.addChild(healthBarBg);
var healthBarFill = LK.getAsset('powerupHealth', {
width: 200,
height: 30,
tint: 0x00ff00
});
healthBar.addChild(healthBarFill);
function updateHealthBar() {
if (playerTank) {
var healthPercent = playerTank.health / playerTank.maxHealth;
healthBarFill.width = 200 * healthPercent;
if (healthPercent < 0.3) {
healthBarFill.tint = 0xff0000;
} else if (healthPercent < 0.6) {
healthBarFill.tint = 0xffff00;
} else {
healthBarFill.tint = 0x00ff00;
}
}
}
function findNearestEnemy(x, y) {
var nearest = null;
var minDistance = Infinity;
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var dx = enemy.x - x;
var dy = enemy.y - y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < minDistance) {
minDistance = distance;
nearest = enemy;
}
}
for (var i = 0; i < turrets.length; i++) {
var turret = turrets[i];
var dx = turret.x - x;
var dy = turret.y - y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < minDistance) {
minDistance = distance;
nearest = turret;
}
}
return nearest;
}
function spawnEnemy() {
var enemy = new EnemyTank();
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
enemy.x = Math.random() * 2048;
enemy.y = -50;
break;
case 1:
enemy.x = 2098;
enemy.y = Math.random() * 2732;
break;
case 2:
enemy.x = Math.random() * 2048;
enemy.y = 2782;
break;
case 3:
enemy.x = -50;
enemy.y = Math.random() * 2732;
break;
}
enemies.push(enemy);
game.addChild(enemy);
}
function spawnTurret() {
var turret = new Turret();
turret.x = 300 + Math.random() * 1448;
turret.y = 300 + Math.random() * 2132;
turrets.push(turret);
game.addChild(turret);
}
function spawnPowerUp(x, y) {
if (Math.random() < 0.3) {
var type = Math.random() < 0.6 ? 'health' : 'rapidfire';
var powerUp = new PowerUp(type);
powerUp.x = x;
powerUp.y = y;
powerUps.push(powerUp);
game.addChild(powerUp);
}
}
function spawnBuildings() {
for (var i = 0; i < 5; i++) {
var building = new Building();
building.x = 300 + Math.random() * 1448;
building.y = 300 + Math.random() * 2132;
buildings.push(building);
game.addChild(building);
}
}
function spawnBarrels() {
for (var i = 0; i < 3; i++) {
var barrel = new ExplosiveBarrel();
barrel.x = 300 + Math.random() * 1448;
barrel.y = 300 + Math.random() * 2132;
barrels.push(barrel);
game.addChild(barrel);
}
}
playerTank = new PlayerTank();
playerTank.x = 1024;
playerTank.y = 1366;
game.addChild(playerTank);
spawnBuildings();
spawnBarrels();
LK.playMusic('battleMusic');
var targetX = playerTank.x;
var targetY = playerTank.y;
game.down = function (x, y, obj) {
targetX = x;
targetY = y;
};
game.move = function (x, y, obj) {
targetX = x;
targetY = y;
};
game.update = function () {
if (playerTank) {
var dx = targetX - playerTank.x;
var dy = targetY - playerTank.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 10) {
var newX = playerTank.x + dx / distance * playerTank.speed;
var newY = playerTank.y + dy / distance * playerTank.speed;
newX = Math.max(60, Math.min(1988, newX));
newY = Math.max(80, Math.min(2652, newY));
// Check collision with buildings
var canMoveX = true;
var canMoveY = true;
var tempTank = {
x: newX,
y: playerTank.y,
width: playerTank.width,
height: playerTank.height,
intersects: playerTank.intersects.bind({
x: newX,
y: playerTank.y,
width: playerTank.width,
height: playerTank.height
})
};
var tempTankY = {
x: playerTank.x,
y: newY,
width: playerTank.width,
height: playerTank.height,
intersects: playerTank.intersects.bind({
x: playerTank.x,
y: newY,
width: playerTank.width,
height: playerTank.height
})
};
for (var b = 0; b < buildings.length; b++) {
var building = buildings[b];
var buildingBounds = {
x: building.x - 100,
y: building.y - 100,
width: 200,
height: 200
};
if (newX + 120 > buildingBounds.x && newX - 120 < buildingBounds.x + buildingBounds.width && playerTank.y + 160 > buildingBounds.y && playerTank.y - 160 < buildingBounds.y + buildingBounds.height) {
canMoveX = false;
}
if (playerTank.x + 120 > buildingBounds.x && playerTank.x - 120 < buildingBounds.x + buildingBounds.width && newY + 160 > buildingBounds.y && newY - 160 < buildingBounds.y + buildingBounds.height) {
canMoveY = false;
}
}
for (var b = 0; b < barrels.length; b++) {
var barrel = barrels[b];
var barrelBounds = {
x: barrel.x - 60,
y: barrel.y - 75,
width: 120,
height: 150
};
if (newX + 120 > barrelBounds.x && newX - 120 < barrelBounds.x + barrelBounds.width && playerTank.y + 160 > barrelBounds.y && playerTank.y - 160 < barrelBounds.y + barrelBounds.height) {
canMoveX = false;
}
if (playerTank.x + 120 > barrelBounds.x && playerTank.x - 120 < barrelBounds.x + barrelBounds.width && newY + 160 > barrelBounds.y && newY - 160 < barrelBounds.y + barrelBounds.height) {
canMoveY = false;
}
}
if (canMoveX) playerTank.x = newX;
if (canMoveY) playerTank.y = newY;
}
}
waveTimer++;
if (enemiesSpawned < enemiesPerWave && waveTimer % 120 === 0) {
spawnEnemy();
enemiesSpawned++;
if (wave > 2 && enemiesSpawned % 2 === 0) {
spawnTurret();
}
}
if (enemies.length === 0 && turrets.length === 0 && enemiesSpawned >= enemiesPerWave) {
wave++;
enemiesPerWave = Math.min(wave * 2 + 1, 15);
enemiesSpawned = 0;
waveTimer = 0;
waveTxt.setText('Wave ' + wave);
tween(waveTxt, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 300,
onFinish: function onFinish() {
tween(waveTxt, {
scaleX: 1,
scaleY: 1
}, {
duration: 300
});
}
});
}
for (var i = playerBullets.length - 1; i >= 0; i--) {
var bullet = playerBullets[i];
if (bullet.x < -50 || bullet.x > 2098 || bullet.y < -50 || bullet.y > 2782) {
bullet.destroy();
playerBullets.splice(i, 1);
continue;
}
for (var j = enemies.length - 1; j >= 0; j--) {
var enemy = enemies[j];
if (bullet.intersects(enemy)) {
if (enemy.takeDamage(bullet.damage)) {
spawnPowerUp(enemy.x, enemy.y);
enemy.destroy();
enemies.splice(j, 1);
score += 100;
LK.getSound('explosion').play();
}
bullet.destroy();
playerBullets.splice(i, 1);
break;
}
}
if (i < 0) continue;
for (var j = turrets.length - 1; j >= 0; j--) {
var turret = turrets[j];
if (bullet.intersects(turret)) {
if (turret.takeDamage(bullet.damage)) {
spawnPowerUp(turret.x, turret.y);
turret.destroy();
turrets.splice(j, 1);
score += 150;
LK.getSound('explosion').play();
}
bullet.destroy();
playerBullets.splice(i, 1);
break;
}
}
if (i < 0) continue;
for (var j = buildings.length - 1; j >= 0; j--) {
var building = buildings[j];
if (bullet.intersects(building)) {
if (building.takeDamage(bullet.damage)) {
building.destroy();
buildings.splice(j, 1);
}
bullet.destroy();
playerBullets.splice(i, 1);
break;
}
}
if (i < 0) continue;
for (var j = barrels.length - 1; j >= 0; j--) {
var barrel = barrels[j];
if (bullet.intersects(barrel)) {
if (barrel.takeDamage(bullet.damage)) {
barrel.destroy();
barrels.splice(j, 1);
}
bullet.destroy();
playerBullets.splice(i, 1);
break;
}
}
}
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var bullet = enemyBullets[i];
if (bullet.x < -50 || bullet.x > 2098 || bullet.y < -50 || bullet.y > 2782) {
bullet.destroy();
enemyBullets.splice(i, 1);
continue;
}
if (playerTank && bullet.intersects(playerTank)) {
if (playerTank.takeDamage(bullet.damage)) {
if (score > highScore) {
storage.highScore = score;
}
LK.showGameOver();
}
bullet.destroy();
enemyBullets.splice(i, 1);
updateHealthBar();
}
}
for (var i = powerUps.length - 1; i >= 0; i--) {
var powerUp = powerUps[i];
if (powerUp.lifetime <= 0) {
powerUp.destroy();
powerUps.splice(i, 1);
continue;
}
if (playerTank && !powerUp.collected && powerUp.intersects(playerTank)) {
powerUp.collected = true;
if (powerUp.type === 'health') {
playerTank.heal(30);
updateHealthBar();
} else if (powerUp.type === 'rapidfire') {
playerTank.enableRapidFire();
}
LK.getSound('powerup').play();
tween(powerUp, {
scaleX: 0,
scaleY: 0,
alpha: 0
}, {
duration: 300,
onFinish: function onFinish() {
powerUp.destroy();
}
});
powerUps.splice(i, 1);
}
}
scoreTxt.setText('Score: ' + score);
updateHealthBar();
}; ===================================================================
--- original.js
+++ change.js
@@ -283,9 +283,9 @@
/****
* Initialize Game
****/
var game = new LK.Game({
- backgroundColor: 0x1a1a1a
+ backgroundColor: 0x228B22
});
/****
* Game Code
@@ -452,12 +452,71 @@
var dx = targetX - playerTank.x;
var dy = targetY - playerTank.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 10) {
- playerTank.x += dx / distance * playerTank.speed;
- playerTank.y += dy / distance * playerTank.speed;
- playerTank.x = Math.max(60, Math.min(1988, playerTank.x));
- playerTank.y = Math.max(80, Math.min(2652, playerTank.y));
+ var newX = playerTank.x + dx / distance * playerTank.speed;
+ var newY = playerTank.y + dy / distance * playerTank.speed;
+ newX = Math.max(60, Math.min(1988, newX));
+ newY = Math.max(80, Math.min(2652, newY));
+ // Check collision with buildings
+ var canMoveX = true;
+ var canMoveY = true;
+ var tempTank = {
+ x: newX,
+ y: playerTank.y,
+ width: playerTank.width,
+ height: playerTank.height,
+ intersects: playerTank.intersects.bind({
+ x: newX,
+ y: playerTank.y,
+ width: playerTank.width,
+ height: playerTank.height
+ })
+ };
+ var tempTankY = {
+ x: playerTank.x,
+ y: newY,
+ width: playerTank.width,
+ height: playerTank.height,
+ intersects: playerTank.intersects.bind({
+ x: playerTank.x,
+ y: newY,
+ width: playerTank.width,
+ height: playerTank.height
+ })
+ };
+ for (var b = 0; b < buildings.length; b++) {
+ var building = buildings[b];
+ var buildingBounds = {
+ x: building.x - 100,
+ y: building.y - 100,
+ width: 200,
+ height: 200
+ };
+ if (newX + 120 > buildingBounds.x && newX - 120 < buildingBounds.x + buildingBounds.width && playerTank.y + 160 > buildingBounds.y && playerTank.y - 160 < buildingBounds.y + buildingBounds.height) {
+ canMoveX = false;
+ }
+ if (playerTank.x + 120 > buildingBounds.x && playerTank.x - 120 < buildingBounds.x + buildingBounds.width && newY + 160 > buildingBounds.y && newY - 160 < buildingBounds.y + buildingBounds.height) {
+ canMoveY = false;
+ }
+ }
+ for (var b = 0; b < barrels.length; b++) {
+ var barrel = barrels[b];
+ var barrelBounds = {
+ x: barrel.x - 60,
+ y: barrel.y - 75,
+ width: 120,
+ height: 150
+ };
+ if (newX + 120 > barrelBounds.x && newX - 120 < barrelBounds.x + barrelBounds.width && playerTank.y + 160 > barrelBounds.y && playerTank.y - 160 < barrelBounds.y + barrelBounds.height) {
+ canMoveX = false;
+ }
+ if (playerTank.x + 120 > barrelBounds.x && playerTank.x - 120 < barrelBounds.x + barrelBounds.width && newY + 160 > barrelBounds.y && newY - 160 < barrelBounds.y + barrelBounds.height) {
+ canMoveY = false;
+ }
+ }
+ if (canMoveX) playerTank.x = newX;
+ if (canMoveY) playerTank.y = newY;
}
}
waveTimer++;
if (enemiesSpawned < enemiesPerWave && waveTimer % 120 === 0) {