/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Enemy class
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemySprite = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = enemySprite.width;
self.height = enemySprite.height;
self.speed = 6 + Math.random() * 3;
self.shootTimer = 60 + Math.floor(Math.random() * 60);
self.hp = 1;
// Update
self.update = function () {
self.y += self.speed;
self.shootTimer--;
if (self.shootTimer <= 0) {
self.shoot();
self.shootTimer = 90 + Math.floor(Math.random() * 60);
}
};
// Shoot
self.shoot = function () {
var bullet = new EnemyBullet();
bullet.x = self.x;
bullet.y = self.y + self.height / 2 + bullet.height / 2;
enemyBullets.push(bullet);
game.addChild(bullet);
};
return self;
});
// Enemy2 class (stronger enemy)
var Enemy2 = Container.expand(function () {
var self = Container.call(this);
var enemySprite = self.attachAsset('enemy2', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = enemySprite.width;
self.height = enemySprite.height;
self.speed = 7 + Math.random() * 2; // Slightly faster than normal enemy
self.shootTimer = 60 + Math.floor(Math.random() * 60);
self.hp = 2; // 2 armor
// Update
self.update = function () {
self.y += self.speed;
self.shootTimer--;
if (self.shootTimer <= 0) {
self.shoot();
self.shootTimer = 90 + Math.floor(Math.random() * 60);
}
};
// Shoot
self.shoot = function () {
var bullet = new EnemyBullet();
bullet.x = self.x;
bullet.y = self.y + self.height / 2 + bullet.height / 2;
enemyBullets.push(bullet);
game.addChild(bullet);
};
return self;
});
// Enemy bullet class
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletSprite = self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = bulletSprite.width;
self.height = bulletSprite.height;
self.speed = 18;
self.update = function () {
self.y += self.speed;
};
return self;
});
// Hero class
var Hero = Container.expand(function () {
var self = Container.call(this);
var heroSprite = self.attachAsset('hero', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = heroSprite.width;
self.height = heroSprite.height;
// Attach gun asset to hero's hand, but anchor at the bottom center for upward rotation
var gunSprite = self.attachAsset('heroGun', {
anchorX: 0.5,
anchorY: 1.0 // Anchor at the very bottom of the gun for correct rotation
});
// Raise the gun: rotate upwards and move to hero's hand
gunSprite.x = 0;
gunSprite.y = -heroSprite.height * 0.45; // Move gun above hero's hand
gunSprite.rotation = -Math.PI / 2; // Point gun straight up (90 degrees)
self.gunSprite = gunSprite;
self.shootCooldown = 0;
self.poweredUp = false;
self.powerupTimer = 0;
self.rapidFire = false;
self.rapidFireTimer = 0;
self.tripleShot = false;
self.tripleShotTimer = 0;
// Shoot method
self.shoot = function () {
if (self.shootCooldown > 0) return;
if (self.tripleShot) {
// Triple shot: three bullets, center, left, right
var offset = 50;
var bulletCenter = new HeroBullet();
bulletCenter.x = self.x;
bulletCenter.y = self.y - self.height / 2 - bulletCenter.height / 2;
heroBullets.push(bulletCenter);
game.addChild(bulletCenter);
var bulletLeft = new HeroBullet();
bulletLeft.x = self.x - offset;
bulletLeft.y = self.y - self.height / 2 - bulletLeft.height / 2;
heroBullets.push(bulletLeft);
game.addChild(bulletLeft);
var bulletRight = new HeroBullet();
bulletRight.x = self.x + offset;
bulletRight.y = self.y - self.height / 2 - bulletRight.height / 2;
heroBullets.push(bulletRight);
game.addChild(bulletRight);
LK.getSound('shoot').play();
self.shootCooldown = 6; // Fastest shooting for triple shot
} else if (self.poweredUp) {
// Twin shot: two bullets, left and right
var offset = 40;
var bulletLeft = new TwinHeroBullet();
bulletLeft.x = self.x - offset;
bulletLeft.y = self.y - self.height / 2 - bulletLeft.height / 2;
bulletLeft.offsetX = -offset;
heroBullets.push(bulletLeft);
game.addChild(bulletLeft);
var bulletRight = new TwinHeroBullet();
bulletRight.x = self.x + offset;
bulletRight.y = self.y - self.height / 2 - bulletRight.height / 2;
bulletRight.offsetX = offset;
heroBullets.push(bulletRight);
game.addChild(bulletRight);
LK.getSound('shoot').play();
self.shootCooldown = 10; // Faster shooting if powered up
} else {
var bullet = new HeroBullet();
bullet.x = self.x;
bullet.y = self.y - self.height / 2 - bullet.height / 2;
heroBullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
self.shootCooldown = 20;
}
};
// Powerup method
self.activatePowerup = function () {
self.poweredUp = true;
self.powerupTimer = 300; // 5 seconds at 60fps
tween(self, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 200,
easing: tween.elasticOut
});
};
// Remove powerup
self.deactivatePowerup = function () {
self.poweredUp = false;
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.elasticIn
});
};
// Update
self.update = function () {
if (self.shootCooldown > 0) self.shootCooldown--;
if (self.rapidFire) {
self.rapidFireTimer--;
if (self.rapidFireTimer <= 0) {
self.rapidFire = false;
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.elasticIn
});
}
}
if (self.tripleShot) {
self.tripleShotTimer--;
if (self.tripleShotTimer <= 0) {
self.tripleShot = false;
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.elasticIn
});
}
}
if (self.poweredUp) {
self.powerupTimer--;
if (self.powerupTimer <= 0) {
self.deactivatePowerup();
}
}
};
return self;
});
// Hero bullet class
var HeroBullet = Container.expand(function () {
var self = Container.call(this);
var bulletSprite = self.attachAsset('heroBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = bulletSprite.width;
self.height = bulletSprite.height;
self.speed = -28;
self.update = function () {
self.y += self.speed;
};
return self;
});
// Powerup class
var Powerup = Container.expand(function () {
var self = Container.call(this);
var powerupSprite = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = powerupSprite.width;
self.height = powerupSprite.height;
self.speed = 10;
self.update = function () {
self.y += self.speed;
};
return self;
});
// Twin hero bullet class (for 2-bullet powerup)
var TwinHeroBullet = Container.expand(function () {
var self = Container.call(this);
var bulletSprite = self.attachAsset('heroBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = bulletSprite.width;
self.height = bulletSprite.height;
self.speed = -28;
self.offsetX = 0; // will be set on creation
self.update = function () {
self.y += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222a36
});
/****
* Game Code
****/
// Music
// Sound effects
// Powerup: green ellipse
// Hero bullet: yellow box
// Enemy bullet: orange box
// Enemy asset: red ellipse
// Hero asset: blue box
// Play music
LK.playMusic('battlefieldMusic');
// Score
var score = 0;
var scoreTxt = new Text2('0', {
size: 120,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Hero lives
var heroLives = 5;
var livesTxt = new Text2("♥ x" + heroLives, {
size: 110,
fill: 0xFF4444,
font: "Impact, Arial Black, Tahoma"
});
livesTxt.anchor.set(1, 0);
livesTxt.x = LK.gui.width - 40;
livesTxt.y = 0;
LK.gui.top.addChild(livesTxt);
// Armor display
var armorTxt = new Text2("", {
size: 90,
fill: 0x66ccff,
font: "Impact, Arial Black, Tahoma"
});
armorTxt.anchor.set(1, 0);
armorTxt.x = LK.gui.width - 40;
armorTxt.y = 120;
LK.gui.top.addChild(armorTxt);
// Hero instance
var hero = new Hero();
hero.armor = 5; // Start with 5 armor
game.addChild(hero);
hero.x = 2048 / 2;
hero.y = 2732 - 350;
// Arrays for game objects
var enemies = [];
var heroBullets = [];
var enemyBullets = [];
var powerups = [];
// Dragging
var dragNode = null;
// Difficulty
var spawnTimer = 0;
var spawnInterval = 60;
var difficultyTimer = 0;
// Track enemy spawn multiplier for score-based scaling
var enemySpawnMultiplier = 1;
var lastScoreForSpawnIncrease = 0;
// Powerup spawn
var powerupTimer = 600;
// Move handler
function handleMove(x, y, obj) {
if (dragNode) {
// Clamp hero inside game area, avoid top 100px and bottom 100px
var minX = hero.width / 2;
var maxX = 2048 - hero.width / 2;
var minY = 100 + hero.height / 2;
var maxY = 2732 - hero.height / 2 - 100;
hero.x = Math.max(minX, Math.min(maxX, x));
hero.y = Math.max(minY, Math.min(maxY, y));
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
// Only start drag if touch is on hero
var dx = x - hero.x;
var dy = y - hero.y;
if (dx * dx + dy * dy < hero.width / 2 * (hero.width / 2)) {
dragNode = hero;
handleMove(x, y, obj);
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Main update loop
game.update = function () {
// Hero update
hero.update();
// Hero auto-shoot
if (hero.tripleShot) {
if (LK.ticks % 2 === 0) {
hero.shoot();
}
} else if (hero.rapidFire) {
if (LK.ticks % 3 === 0) {
hero.shoot();
}
} else if (hero.poweredUp) {
if (LK.ticks % 6 === 0) {
hero.shoot();
}
} else {
if (LK.ticks % 12 === 0) {
hero.shoot();
}
}
// Increase enemy spawn multiplier every 150 points by 3%
if (score - lastScoreForSpawnIncrease >= 150) {
var increases = Math.floor((score - lastScoreForSpawnIncrease) / 150);
for (var inc = 0; inc < increases; inc++) {
enemySpawnMultiplier *= 1.03;
}
lastScoreForSpawnIncrease += 150 * increases;
}
// Spawn enemies
spawnTimer--;
if (spawnTimer <= 0) {
var margin = 120;
var enemiesToSpawn = Math.max(1, Math.floor(enemySpawnMultiplier));
for (var s = 0; s < enemiesToSpawn; s++) {
var enemy;
// Spawn Enemy2 every 20 points (but not at score 0)
if (score > 0 && score % 20 === 0 && s === 0) {
enemy = new Enemy2();
} else {
enemy = new Enemy();
}
enemy.x = margin + Math.random() * (2048 - 2 * margin);
enemy.y = -enemy.height / 2;
enemies.push(enemy);
game.addChild(enemy);
}
spawnTimer = spawnInterval;
}
// Increase difficulty over time
difficultyTimer++;
if (difficultyTimer % 600 === 0 && spawnInterval > 20) {
spawnInterval -= 5;
}
// Powerup spawn
powerupTimer--;
if (powerupTimer <= 0) {
// 20% chance to spawn powerup3 (kill all enemies), 30% for powerup2 (armor), else normal powerup
var rand = Math.random();
var powerup;
if (rand < 0.2) {
powerup = new Powerup();
powerup.assetId = 'powerup3';
// Change sprite to powerup3 asset
if (powerup.children && powerup.children.length > 0) {
powerup.removeChild(powerup.children[0]);
}
var sprite = powerup.attachAsset('powerup3', {
anchorX: 0.5,
anchorY: 0.5
});
powerup.width = sprite.width;
powerup.height = sprite.height;
} else if (rand < 0.5) {
powerup = new Powerup();
powerup.assetId = 'powerup2';
// Change sprite to powerup2 asset
if (powerup.children && powerup.children.length > 0) {
powerup.removeChild(powerup.children[0]);
}
var sprite = powerup.attachAsset('powerup2', {
anchorX: 0.5,
anchorY: 0.5
});
powerup.width = sprite.width;
powerup.height = sprite.height;
} else {
powerup = new Powerup();
powerup.assetId = 'powerup';
}
powerup.x = 200 + Math.random() * (2048 - 400);
powerup.y = -powerup.height / 2;
powerups.push(powerup);
game.addChild(powerup);
powerupTimer = 810 + Math.floor(Math.random() * 540);
}
// Update and cleanup hero bullets
for (var i = heroBullets.length - 1; i >= 0; i--) {
var b = heroBullets[i];
b.update();
if (b.y < -b.height / 2) {
b.destroy();
heroBullets.splice(i, 1);
continue;
}
// Collision with enemies
for (var j = enemies.length - 1; j >= 0; j--) {
var e = enemies[j];
if (b.intersects(e)) {
e.hp--;
if (e.hp <= 0) {
LK.getSound('enemyDown').play();
score += 10;
scoreTxt.setText(score);
// Restore 1 life every 50 points, but only on the exact frame score crosses a multiple of 50
if (score % 50 === 0 && heroLives < 5) {
heroLives++;
livesTxt.setText("♥ x" + heroLives);
// Optional: flash green to indicate heal
LK.effects.flashScreen(0x44de83, 400);
}
// 30% chance to drop a life if not at max
if (heroLives < 5 && Math.random() < 0.3) {
heroLives++;
livesTxt.setText("♥ x" + heroLives);
LK.effects.flashScreen(0x44de83, 400);
}
// 30% chance to gain armor if killed enemy is Enemy2 (purple)
if (e instanceof Enemy2 && Math.random() < 0.3) {
if (typeof hero.armor === "undefined") hero.armor = 0;
hero.armor++;
// Optional: flash blue to indicate armor gain
LK.effects.flashScreen(0x66ccff, 300);
}
e.destroy();
enemies.splice(j, 1);
}
b.destroy();
heroBullets.splice(i, 1);
break;
}
}
}
// Update and cleanup enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var eb = enemyBullets[i];
eb.update();
if (eb.y > 2732 + eb.height / 2) {
eb.destroy();
enemyBullets.splice(i, 1);
continue;
}
// Collision with hero
if (eb.intersects(hero)) {
LK.effects.flashScreen(0xff0000, 800);
// If hero has armor, consume armor instead of life
if (typeof hero.armor !== "undefined" && hero.armor > 0) {
hero.armor--;
// Optional: flash blue to indicate armor loss
LK.effects.flashScreen(0x66ccff, 200);
} else {
heroLives--;
livesTxt.setText("♥ x" + heroLives);
if (heroLives <= 0) {
LK.showGameOver();
return;
}
}
eb.destroy();
enemyBullets.splice(i, 1);
continue;
}
}
// Update and cleanup enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var e = enemies[i];
e.update();
if (e.y > 2732 + e.height / 2) {
e.destroy();
enemies.splice(i, 1);
continue;
}
// Collision with hero
if (e.intersects(hero)) {
LK.effects.flashScreen(0xff0000, 800);
// If hero has armor, consume armor instead of life
if (typeof hero.armor !== "undefined" && hero.armor > 0) {
hero.armor--;
// Optional: flash blue to indicate armor loss
LK.effects.flashScreen(0x66ccff, 200);
} else {
heroLives--;
livesTxt.setText("♥ x" + heroLives);
if (heroLives <= 0) {
LK.showGameOver();
return;
}
}
e.destroy();
enemies.splice(i, 1);
continue;
}
}
// Update and cleanup powerups
for (var i = powerups.length - 1; i >= 0; i--) {
var p = powerups[i];
p.update();
if (p.y > 2732 + p.height / 2) {
p.destroy();
powerups.splice(i, 1);
continue;
}
// Collision with hero
if (p.intersects(hero)) {
LK.getSound('powerup').play();
// Check if this is a powerup3 (kill all enemies)
if (p.assetId === 'powerup3') {
// Kill all enemies instantly
for (var j = enemies.length - 1; j >= 0; j--) {
var e = enemies[j];
LK.getSound('enemyDown').play();
score += 10;
scoreTxt.setText(score);
// Restore 1 life every 50 points, but only on the exact frame score crosses a multiple of 50
if (score % 50 === 0 && heroLives < 5) {
heroLives++;
livesTxt.setText("♥ x" + heroLives);
LK.effects.flashScreen(0x44de83, 400);
}
e.destroy();
enemies.splice(j, 1);
}
// Optional: flash screen to indicate effect
LK.effects.flashScreen(0x00cfff, 600);
} else
// Check if this is a powerup2 (armor powerup)
if (p.assetId === 'powerup2') {
// 20% chance to grant triple shot
if (Math.random() < 0.2) {
hero.tripleShot = true;
hero.tripleShotTimer = 300; // 5 seconds at 60fps
// Remove other powerups if triple shot is granted
hero.rapidFire = false;
hero.rapidFireTimer = 0;
hero.poweredUp = false;
hero.powerupTimer = 0;
tween(hero, {
scaleX: 1.7,
scaleY: 1.7
}, {
duration: 200,
easing: tween.elasticOut
});
} else {
// Grant 5 armor to hero
if (typeof hero.armor === "undefined") hero.armor = 0;
hero.armor += 5;
// Optional: flash blue to indicate armor gain
LK.effects.flashScreen(0x66ccff, 400);
}
} else {
// 20% chance to grant rapid fire (faster shooting)
if (Math.random() < 0.2) {
hero.rapidFire = true;
hero.rapidFireTimer = 300; // 5 seconds at 60fps
hero.poweredUp = false; // Remove twin shot if rapid fire is granted
tween(hero, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
easing: tween.elasticOut
});
} else {
hero.activatePowerup();
}
// 40% chance to restore 1 life if not at max
if (heroLives < 5 && Math.random() < 0.4) {
heroLives++;
livesTxt.setText("♥ x" + heroLives);
// Optional: flash green to indicate heal
LK.effects.flashScreen(0x44de83, 400);
}
}
p.destroy();
powerups.splice(i, 1);
continue;
}
}
// Update armor display
if (typeof hero.armor !== "undefined" && hero.armor > 0) {
armorTxt.setText("🛡 x" + hero.armor);
armorTxt.visible = true;
} else {
armorTxt.setText("");
armorTxt.visible = false;
}
// Win condition removed: score is now unlimited
}; /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Enemy class
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemySprite = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = enemySprite.width;
self.height = enemySprite.height;
self.speed = 6 + Math.random() * 3;
self.shootTimer = 60 + Math.floor(Math.random() * 60);
self.hp = 1;
// Update
self.update = function () {
self.y += self.speed;
self.shootTimer--;
if (self.shootTimer <= 0) {
self.shoot();
self.shootTimer = 90 + Math.floor(Math.random() * 60);
}
};
// Shoot
self.shoot = function () {
var bullet = new EnemyBullet();
bullet.x = self.x;
bullet.y = self.y + self.height / 2 + bullet.height / 2;
enemyBullets.push(bullet);
game.addChild(bullet);
};
return self;
});
// Enemy2 class (stronger enemy)
var Enemy2 = Container.expand(function () {
var self = Container.call(this);
var enemySprite = self.attachAsset('enemy2', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = enemySprite.width;
self.height = enemySprite.height;
self.speed = 7 + Math.random() * 2; // Slightly faster than normal enemy
self.shootTimer = 60 + Math.floor(Math.random() * 60);
self.hp = 2; // 2 armor
// Update
self.update = function () {
self.y += self.speed;
self.shootTimer--;
if (self.shootTimer <= 0) {
self.shoot();
self.shootTimer = 90 + Math.floor(Math.random() * 60);
}
};
// Shoot
self.shoot = function () {
var bullet = new EnemyBullet();
bullet.x = self.x;
bullet.y = self.y + self.height / 2 + bullet.height / 2;
enemyBullets.push(bullet);
game.addChild(bullet);
};
return self;
});
// Enemy bullet class
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletSprite = self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = bulletSprite.width;
self.height = bulletSprite.height;
self.speed = 18;
self.update = function () {
self.y += self.speed;
};
return self;
});
// Hero class
var Hero = Container.expand(function () {
var self = Container.call(this);
var heroSprite = self.attachAsset('hero', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = heroSprite.width;
self.height = heroSprite.height;
// Attach gun asset to hero's hand, but anchor at the bottom center for upward rotation
var gunSprite = self.attachAsset('heroGun', {
anchorX: 0.5,
anchorY: 1.0 // Anchor at the very bottom of the gun for correct rotation
});
// Raise the gun: rotate upwards and move to hero's hand
gunSprite.x = 0;
gunSprite.y = -heroSprite.height * 0.45; // Move gun above hero's hand
gunSprite.rotation = -Math.PI / 2; // Point gun straight up (90 degrees)
self.gunSprite = gunSprite;
self.shootCooldown = 0;
self.poweredUp = false;
self.powerupTimer = 0;
self.rapidFire = false;
self.rapidFireTimer = 0;
self.tripleShot = false;
self.tripleShotTimer = 0;
// Shoot method
self.shoot = function () {
if (self.shootCooldown > 0) return;
if (self.tripleShot) {
// Triple shot: three bullets, center, left, right
var offset = 50;
var bulletCenter = new HeroBullet();
bulletCenter.x = self.x;
bulletCenter.y = self.y - self.height / 2 - bulletCenter.height / 2;
heroBullets.push(bulletCenter);
game.addChild(bulletCenter);
var bulletLeft = new HeroBullet();
bulletLeft.x = self.x - offset;
bulletLeft.y = self.y - self.height / 2 - bulletLeft.height / 2;
heroBullets.push(bulletLeft);
game.addChild(bulletLeft);
var bulletRight = new HeroBullet();
bulletRight.x = self.x + offset;
bulletRight.y = self.y - self.height / 2 - bulletRight.height / 2;
heroBullets.push(bulletRight);
game.addChild(bulletRight);
LK.getSound('shoot').play();
self.shootCooldown = 6; // Fastest shooting for triple shot
} else if (self.poweredUp) {
// Twin shot: two bullets, left and right
var offset = 40;
var bulletLeft = new TwinHeroBullet();
bulletLeft.x = self.x - offset;
bulletLeft.y = self.y - self.height / 2 - bulletLeft.height / 2;
bulletLeft.offsetX = -offset;
heroBullets.push(bulletLeft);
game.addChild(bulletLeft);
var bulletRight = new TwinHeroBullet();
bulletRight.x = self.x + offset;
bulletRight.y = self.y - self.height / 2 - bulletRight.height / 2;
bulletRight.offsetX = offset;
heroBullets.push(bulletRight);
game.addChild(bulletRight);
LK.getSound('shoot').play();
self.shootCooldown = 10; // Faster shooting if powered up
} else {
var bullet = new HeroBullet();
bullet.x = self.x;
bullet.y = self.y - self.height / 2 - bullet.height / 2;
heroBullets.push(bullet);
game.addChild(bullet);
LK.getSound('shoot').play();
self.shootCooldown = 20;
}
};
// Powerup method
self.activatePowerup = function () {
self.poweredUp = true;
self.powerupTimer = 300; // 5 seconds at 60fps
tween(self, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 200,
easing: tween.elasticOut
});
};
// Remove powerup
self.deactivatePowerup = function () {
self.poweredUp = false;
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.elasticIn
});
};
// Update
self.update = function () {
if (self.shootCooldown > 0) self.shootCooldown--;
if (self.rapidFire) {
self.rapidFireTimer--;
if (self.rapidFireTimer <= 0) {
self.rapidFire = false;
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.elasticIn
});
}
}
if (self.tripleShot) {
self.tripleShotTimer--;
if (self.tripleShotTimer <= 0) {
self.tripleShot = false;
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 200,
easing: tween.elasticIn
});
}
}
if (self.poweredUp) {
self.powerupTimer--;
if (self.powerupTimer <= 0) {
self.deactivatePowerup();
}
}
};
return self;
});
// Hero bullet class
var HeroBullet = Container.expand(function () {
var self = Container.call(this);
var bulletSprite = self.attachAsset('heroBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = bulletSprite.width;
self.height = bulletSprite.height;
self.speed = -28;
self.update = function () {
self.y += self.speed;
};
return self;
});
// Powerup class
var Powerup = Container.expand(function () {
var self = Container.call(this);
var powerupSprite = self.attachAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = powerupSprite.width;
self.height = powerupSprite.height;
self.speed = 10;
self.update = function () {
self.y += self.speed;
};
return self;
});
// Twin hero bullet class (for 2-bullet powerup)
var TwinHeroBullet = Container.expand(function () {
var self = Container.call(this);
var bulletSprite = self.attachAsset('heroBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = bulletSprite.width;
self.height = bulletSprite.height;
self.speed = -28;
self.offsetX = 0; // will be set on creation
self.update = function () {
self.y += self.speed;
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x222a36
});
/****
* Game Code
****/
// Music
// Sound effects
// Powerup: green ellipse
// Hero bullet: yellow box
// Enemy bullet: orange box
// Enemy asset: red ellipse
// Hero asset: blue box
// Play music
LK.playMusic('battlefieldMusic');
// Score
var score = 0;
var scoreTxt = new Text2('0', {
size: 120,
fill: "#fff"
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Hero lives
var heroLives = 5;
var livesTxt = new Text2("♥ x" + heroLives, {
size: 110,
fill: 0xFF4444,
font: "Impact, Arial Black, Tahoma"
});
livesTxt.anchor.set(1, 0);
livesTxt.x = LK.gui.width - 40;
livesTxt.y = 0;
LK.gui.top.addChild(livesTxt);
// Armor display
var armorTxt = new Text2("", {
size: 90,
fill: 0x66ccff,
font: "Impact, Arial Black, Tahoma"
});
armorTxt.anchor.set(1, 0);
armorTxt.x = LK.gui.width - 40;
armorTxt.y = 120;
LK.gui.top.addChild(armorTxt);
// Hero instance
var hero = new Hero();
hero.armor = 5; // Start with 5 armor
game.addChild(hero);
hero.x = 2048 / 2;
hero.y = 2732 - 350;
// Arrays for game objects
var enemies = [];
var heroBullets = [];
var enemyBullets = [];
var powerups = [];
// Dragging
var dragNode = null;
// Difficulty
var spawnTimer = 0;
var spawnInterval = 60;
var difficultyTimer = 0;
// Track enemy spawn multiplier for score-based scaling
var enemySpawnMultiplier = 1;
var lastScoreForSpawnIncrease = 0;
// Powerup spawn
var powerupTimer = 600;
// Move handler
function handleMove(x, y, obj) {
if (dragNode) {
// Clamp hero inside game area, avoid top 100px and bottom 100px
var minX = hero.width / 2;
var maxX = 2048 - hero.width / 2;
var minY = 100 + hero.height / 2;
var maxY = 2732 - hero.height / 2 - 100;
hero.x = Math.max(minX, Math.min(maxX, x));
hero.y = Math.max(minY, Math.min(maxY, y));
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
// Only start drag if touch is on hero
var dx = x - hero.x;
var dy = y - hero.y;
if (dx * dx + dy * dy < hero.width / 2 * (hero.width / 2)) {
dragNode = hero;
handleMove(x, y, obj);
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Main update loop
game.update = function () {
// Hero update
hero.update();
// Hero auto-shoot
if (hero.tripleShot) {
if (LK.ticks % 2 === 0) {
hero.shoot();
}
} else if (hero.rapidFire) {
if (LK.ticks % 3 === 0) {
hero.shoot();
}
} else if (hero.poweredUp) {
if (LK.ticks % 6 === 0) {
hero.shoot();
}
} else {
if (LK.ticks % 12 === 0) {
hero.shoot();
}
}
// Increase enemy spawn multiplier every 150 points by 3%
if (score - lastScoreForSpawnIncrease >= 150) {
var increases = Math.floor((score - lastScoreForSpawnIncrease) / 150);
for (var inc = 0; inc < increases; inc++) {
enemySpawnMultiplier *= 1.03;
}
lastScoreForSpawnIncrease += 150 * increases;
}
// Spawn enemies
spawnTimer--;
if (spawnTimer <= 0) {
var margin = 120;
var enemiesToSpawn = Math.max(1, Math.floor(enemySpawnMultiplier));
for (var s = 0; s < enemiesToSpawn; s++) {
var enemy;
// Spawn Enemy2 every 20 points (but not at score 0)
if (score > 0 && score % 20 === 0 && s === 0) {
enemy = new Enemy2();
} else {
enemy = new Enemy();
}
enemy.x = margin + Math.random() * (2048 - 2 * margin);
enemy.y = -enemy.height / 2;
enemies.push(enemy);
game.addChild(enemy);
}
spawnTimer = spawnInterval;
}
// Increase difficulty over time
difficultyTimer++;
if (difficultyTimer % 600 === 0 && spawnInterval > 20) {
spawnInterval -= 5;
}
// Powerup spawn
powerupTimer--;
if (powerupTimer <= 0) {
// 20% chance to spawn powerup3 (kill all enemies), 30% for powerup2 (armor), else normal powerup
var rand = Math.random();
var powerup;
if (rand < 0.2) {
powerup = new Powerup();
powerup.assetId = 'powerup3';
// Change sprite to powerup3 asset
if (powerup.children && powerup.children.length > 0) {
powerup.removeChild(powerup.children[0]);
}
var sprite = powerup.attachAsset('powerup3', {
anchorX: 0.5,
anchorY: 0.5
});
powerup.width = sprite.width;
powerup.height = sprite.height;
} else if (rand < 0.5) {
powerup = new Powerup();
powerup.assetId = 'powerup2';
// Change sprite to powerup2 asset
if (powerup.children && powerup.children.length > 0) {
powerup.removeChild(powerup.children[0]);
}
var sprite = powerup.attachAsset('powerup2', {
anchorX: 0.5,
anchorY: 0.5
});
powerup.width = sprite.width;
powerup.height = sprite.height;
} else {
powerup = new Powerup();
powerup.assetId = 'powerup';
}
powerup.x = 200 + Math.random() * (2048 - 400);
powerup.y = -powerup.height / 2;
powerups.push(powerup);
game.addChild(powerup);
powerupTimer = 810 + Math.floor(Math.random() * 540);
}
// Update and cleanup hero bullets
for (var i = heroBullets.length - 1; i >= 0; i--) {
var b = heroBullets[i];
b.update();
if (b.y < -b.height / 2) {
b.destroy();
heroBullets.splice(i, 1);
continue;
}
// Collision with enemies
for (var j = enemies.length - 1; j >= 0; j--) {
var e = enemies[j];
if (b.intersects(e)) {
e.hp--;
if (e.hp <= 0) {
LK.getSound('enemyDown').play();
score += 10;
scoreTxt.setText(score);
// Restore 1 life every 50 points, but only on the exact frame score crosses a multiple of 50
if (score % 50 === 0 && heroLives < 5) {
heroLives++;
livesTxt.setText("♥ x" + heroLives);
// Optional: flash green to indicate heal
LK.effects.flashScreen(0x44de83, 400);
}
// 30% chance to drop a life if not at max
if (heroLives < 5 && Math.random() < 0.3) {
heroLives++;
livesTxt.setText("♥ x" + heroLives);
LK.effects.flashScreen(0x44de83, 400);
}
// 30% chance to gain armor if killed enemy is Enemy2 (purple)
if (e instanceof Enemy2 && Math.random() < 0.3) {
if (typeof hero.armor === "undefined") hero.armor = 0;
hero.armor++;
// Optional: flash blue to indicate armor gain
LK.effects.flashScreen(0x66ccff, 300);
}
e.destroy();
enemies.splice(j, 1);
}
b.destroy();
heroBullets.splice(i, 1);
break;
}
}
}
// Update and cleanup enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var eb = enemyBullets[i];
eb.update();
if (eb.y > 2732 + eb.height / 2) {
eb.destroy();
enemyBullets.splice(i, 1);
continue;
}
// Collision with hero
if (eb.intersects(hero)) {
LK.effects.flashScreen(0xff0000, 800);
// If hero has armor, consume armor instead of life
if (typeof hero.armor !== "undefined" && hero.armor > 0) {
hero.armor--;
// Optional: flash blue to indicate armor loss
LK.effects.flashScreen(0x66ccff, 200);
} else {
heroLives--;
livesTxt.setText("♥ x" + heroLives);
if (heroLives <= 0) {
LK.showGameOver();
return;
}
}
eb.destroy();
enemyBullets.splice(i, 1);
continue;
}
}
// Update and cleanup enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var e = enemies[i];
e.update();
if (e.y > 2732 + e.height / 2) {
e.destroy();
enemies.splice(i, 1);
continue;
}
// Collision with hero
if (e.intersects(hero)) {
LK.effects.flashScreen(0xff0000, 800);
// If hero has armor, consume armor instead of life
if (typeof hero.armor !== "undefined" && hero.armor > 0) {
hero.armor--;
// Optional: flash blue to indicate armor loss
LK.effects.flashScreen(0x66ccff, 200);
} else {
heroLives--;
livesTxt.setText("♥ x" + heroLives);
if (heroLives <= 0) {
LK.showGameOver();
return;
}
}
e.destroy();
enemies.splice(i, 1);
continue;
}
}
// Update and cleanup powerups
for (var i = powerups.length - 1; i >= 0; i--) {
var p = powerups[i];
p.update();
if (p.y > 2732 + p.height / 2) {
p.destroy();
powerups.splice(i, 1);
continue;
}
// Collision with hero
if (p.intersects(hero)) {
LK.getSound('powerup').play();
// Check if this is a powerup3 (kill all enemies)
if (p.assetId === 'powerup3') {
// Kill all enemies instantly
for (var j = enemies.length - 1; j >= 0; j--) {
var e = enemies[j];
LK.getSound('enemyDown').play();
score += 10;
scoreTxt.setText(score);
// Restore 1 life every 50 points, but only on the exact frame score crosses a multiple of 50
if (score % 50 === 0 && heroLives < 5) {
heroLives++;
livesTxt.setText("♥ x" + heroLives);
LK.effects.flashScreen(0x44de83, 400);
}
e.destroy();
enemies.splice(j, 1);
}
// Optional: flash screen to indicate effect
LK.effects.flashScreen(0x00cfff, 600);
} else
// Check if this is a powerup2 (armor powerup)
if (p.assetId === 'powerup2') {
// 20% chance to grant triple shot
if (Math.random() < 0.2) {
hero.tripleShot = true;
hero.tripleShotTimer = 300; // 5 seconds at 60fps
// Remove other powerups if triple shot is granted
hero.rapidFire = false;
hero.rapidFireTimer = 0;
hero.poweredUp = false;
hero.powerupTimer = 0;
tween(hero, {
scaleX: 1.7,
scaleY: 1.7
}, {
duration: 200,
easing: tween.elasticOut
});
} else {
// Grant 5 armor to hero
if (typeof hero.armor === "undefined") hero.armor = 0;
hero.armor += 5;
// Optional: flash blue to indicate armor gain
LK.effects.flashScreen(0x66ccff, 400);
}
} else {
// 20% chance to grant rapid fire (faster shooting)
if (Math.random() < 0.2) {
hero.rapidFire = true;
hero.rapidFireTimer = 300; // 5 seconds at 60fps
hero.poweredUp = false; // Remove twin shot if rapid fire is granted
tween(hero, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 200,
easing: tween.elasticOut
});
} else {
hero.activatePowerup();
}
// 40% chance to restore 1 life if not at max
if (heroLives < 5 && Math.random() < 0.4) {
heroLives++;
livesTxt.setText("♥ x" + heroLives);
// Optional: flash green to indicate heal
LK.effects.flashScreen(0x44de83, 400);
}
}
p.destroy();
powerups.splice(i, 1);
continue;
}
}
// Update armor display
if (typeof hero.armor !== "undefined" && hero.armor > 0) {
armorTxt.setText("🛡 x" + hero.armor);
armorTxt.visible = true;
} else {
armorTxt.setText("");
armorTxt.visible = false;
}
// Win condition removed: score is now unlimited
};
Fullscreen modern App Store landscape banner, 16:9, high definition, for a game titled "Battlefield Blitz" and with the description "A dynamic 2D war game where you control a hero, dodge enemy attacks, and shoot down waves of foes to survive and score high.". No text on banner!
Enemy. In-Game asset. 2d. High contrast. No shadows
Gun. In-Game asset. 2d. High contrast. No shadows
Mermi. In-Game asset. 2d. High contrast. No shadows
Şarjör. In-Game asset. 2d. High contrast. No shadows
Alev topu. In-Game asset. 2d. High contrast. No shadows