/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Enemy bullet
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bullet = self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 18;
self.update = function () {
self.y += self.speed;
};
return self;
});
// Enemy ship
var EnemyShip = Container.expand(function () {
var self = Container.call(this);
var ship = self.attachAsset('enemyShip', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = ship.width;
self.height = ship.height;
self.speed = 6;
self.shootCooldown = 0;
self.update = function () {
self.y += self.speed;
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
};
return self;
});
// Explosion effect (MVP: fade out and destroy)
var Explosion = Container.expand(function () {
var self = Container.call(this);
var exp = self.attachAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5
});
exp.alpha = 1;
tween(exp, {
alpha: 0
}, {
duration: 400,
easing: tween.linear,
onFinish: function onFinish() {
self.destroy();
}
});
return self;
});
// Player bullet
var PlayerBullet = Container.expand(function () {
var self = Container.call(this);
var bullet = self.attachAsset('playerBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -28;
self.update = function () {
self.y += self.speed;
};
return self;
});
// Player ship
var PlayerShip = Container.expand(function () {
var self = Container.call(this);
var ship = self.attachAsset('playerShip', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = ship.width;
self.height = ship.height;
self.lives = 3;
self.invincible = false;
self.invincibleTicks = 0;
self.update = function () {
if (self.invincible) {
self.invincibleTicks--;
ship.alpha = self.invincibleTicks % 10 < 5 ? 0.4 : 1;
if (self.invincibleTicks <= 0) {
self.invincible = false;
ship.alpha = 1;
}
}
};
// Flash for damage
self.flash = function () {
LK.effects.flashObject(self, 0xffffff, 400);
};
return self;
});
// PowerUp class
var PowerUp = Container.expand(function () {
var self = Container.call(this);
// Types: 'speed', 'double', 'invincible', 'rapid', 'shield', 'score'
self.type = 'speed';
self.duration = 600; // 10 seconds at 60fps
// Icon color by type
var colorMap = {
speed: 0x00ffff,
"double": 0xffd700,
invincible: 0xffffff,
rapid: 0xff00ff,
shield: 0x00ff00,
score: 0xff6600
};
var icon = self.attachAsset('boosts', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 3,
color: colorMap[self.type] || 0xffffff
});
self.width = icon.width;
self.height = icon.height;
self.speed = 8;
self.setType = function (type) {
self.type = type;
icon.color = colorMap[type] || 0xffffff;
};
self.update = function () {
self.y += self.speed;
};
return self;
});
// Starfield background star
var Star = Container.expand(function () {
var self = Container.call(this);
var star = self.attachAsset('star', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 0;
self.update = function () {
self.y += self.speed;
if (self.y > 2732 + 10) {
self.y = -10;
self.x = 50 + Math.random() * (2048 - 100);
self.speed = 2 + Math.random() * 4;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000010
});
/****
* Game Code
****/
// Music (placeholder, not played in MVP)
// Sounds
// Explosion: green box (for MVP, will flash and fade)
// Star: white ellipse
// Enemy bullet: orange ellipse
// Player bullet: yellow ellipse
// Enemy ship: red box
// Player ship: blue box
// Starfield
var stars = [];
for (var i = 0; i < 60; i++) {
var star = new Star();
star.x = 50 + Math.random() * (2048 - 100);
star.y = Math.random() * 2732;
star.speed = 2 + Math.random() * 4;
stars.push(star);
game.addChild(star);
}
// Player
var player = new PlayerShip();
player.x = 2048 / 2;
player.y = 2732 - 300;
game.addChild(player);
// Player bullets
var playerBullets = [];
// Enemies
var enemies = [];
var enemyBullets = [];
// Explosions
var explosions = [];
// Power-ups
var powerUp = null;
var powerUpActive = false;
var powerUpType = null;
var powerUpTicks = 0;
var powerUpIcon = null;
var powerUpTimerTxt = null;
var nextPowerUpTicks = 300; // 5s to 8s after last
// Score and lives
var score = 0;
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var livesTxt = new Text2('♥♥♥', {
size: 90,
fill: 0xFF6666
});
livesTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(livesTxt);
// Power-up UI
powerUpIcon = new Container();
var iconAsset = LK.getAsset('boosts-ui', {
anchorX: 0.5,
anchorY: 0,
scaleX: 2,
scaleY: 2,
color: 0xffffff
});
powerUpIcon.addChild(iconAsset);
powerUpIcon.visible = false;
powerUpIcon.x = 120;
powerUpIcon.y = 20;
LK.gui.top.addChild(powerUpIcon);
powerUpTimerTxt = new Text2('', {
size: 60,
fill: 0xffffff
});
powerUpTimerTxt.anchor.set(0, 0);
powerUpTimerTxt.x = 60;
powerUpTimerTxt.y = 0;
powerUpIcon.addChild(powerUpTimerTxt);
// Dragging
var dragNode = null;
// Enemy spawn control
var enemySpawnTicks = 0;
var enemySpawnInterval = 60; // ticks (1s)
var enemySpeed = 6;
var minEnemySpawnInterval = 24; // fastest spawn (0.4s)
var maxEnemySpeed = 18;
// Player shoot control
var playerShootCooldown = 0;
var playerShootInterval = 12; // ticks (0.2s)
// Game state
var gameOver = false;
// Move handler
function handleMove(x, y, obj) {
if (dragNode && !gameOver) {
// Clamp to game area (leave 60px margin)
var halfW = player.width / 2;
var halfH = player.height / 2;
// Power-up: speed
var speedMult = powerUpActive && powerUpType === 'speed' ? 2 : 1;
// Move player faster if speed boost
var px = player.x + (x - player.x) * 0.2 * speedMult;
var py = player.y + (y - player.y) * 0.2 * speedMult;
var nx = Math.max(halfW + 60, Math.min(2048 - halfW - 60, px));
var ny = Math.max(halfH + 120, Math.min(2732 - halfH - 60, py));
player.x = nx;
player.y = ny;
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
if (!gameOver) {
dragNode = player;
handleMove(x, y, obj);
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Update function
game.update = function () {
if (gameOver) {
return;
}
// Update starfield
for (var i = 0; i < stars.length; i++) {
stars[i].update();
}
// Update player
player.update();
// Power-up spawn logic
if (!powerUp && !powerUpActive) {
nextPowerUpTicks--;
if (nextPowerUpTicks <= 0) {
powerUp = new PowerUp();
// Random type
var types = ['speed', 'double', 'invincible', 'rapid', 'score'];
var t = types[Math.floor(Math.random() * types.length)];
powerUp.setType(t);
powerUp.x = 100 + Math.random() * (2048 - 200);
powerUp.y = -60;
game.addChild(powerUp);
}
}
// Power-up update
if (powerUp) {
powerUp.update();
// Remove if off screen
if (powerUp.y > 2732 + 60) {
powerUp.destroy();
powerUp = null;
nextPowerUpTicks = 300 + Math.floor(Math.random() * 180); // 5-8s
}
// Pickup
if (powerUp && powerUp.intersects(player)) {
// Activate effect
powerUpActive = true;
powerUpType = powerUp.type;
powerUpTicks = 600; // 10s
// UI
powerUpIcon.visible = true;
var colorMap = {
speed: 0x00ffff,
"double": 0xffd700,
invincible: 0xffffff,
rapid: 0xff00ff,
shield: 0x00ff00,
score: 0xff6600
};
powerUpIcon.children[0].color = colorMap[powerUpType] || 0xffffff;
powerUpTimerTxt.setText('10.0');
// Sound/Effect
LK.getSound('shoot').play();
// Remove from game
powerUp.destroy();
powerUp = null;
}
}
// Power-up effect timer
if (powerUpActive) {
powerUpTicks--;
// UI update
powerUpTimerTxt.setText((powerUpTicks / 60).toFixed(1));
if (powerUpTicks <= 0) {
// Expire
powerUpActive = false;
powerUpType = null;
powerUpIcon.visible = false;
nextPowerUpTicks = 300 + Math.floor(Math.random() * 180);
// Sound/Effect
LK.getSound('explosion').play();
}
}
// Player shooting
if (playerShootCooldown > 0) {
playerShootCooldown--;
}
if (dragNode && playerShootCooldown <= 0) {
// Power-up: double shot or rapid
if (powerUpActive && powerUpType === 'double') {
// Two bullets
for (var i = -1; i <= 1; i += 2) {
var pb = new PlayerBullet();
pb.x = player.x + i * 40;
pb.y = player.y - player.height / 2 - 10;
playerBullets.push(pb);
game.addChild(pb);
}
} else {
var pb = new PlayerBullet();
pb.x = player.x;
pb.y = player.y - player.height / 2 - 10;
playerBullets.push(pb);
game.addChild(pb);
}
// Rapid fire
if (powerUpActive && powerUpType === 'rapid') {
playerShootCooldown = Math.floor(playerShootInterval / 2);
} else {
playerShootCooldown = playerShootInterval;
}
LK.getSound('shoot').play();
}
// Update player bullets
for (var i = playerBullets.length - 1; i >= 0; i--) {
var b = playerBullets[i];
b.update();
// Remove if off screen
if (b.y < -40) {
b.destroy();
playerBullets.splice(i, 1);
continue;
}
// Check collision with enemies
for (var j = enemies.length - 1; j >= 0; j--) {
var e = enemies[j];
if (b.intersects(e)) {
// Explosion
var exp = new Explosion();
exp.x = e.x;
exp.y = e.y;
explosions.push(exp);
game.addChild(exp);
LK.getSound('explosion').play();
// Remove enemy and bullet
e.destroy();
enemies.splice(j, 1);
b.destroy();
playerBullets.splice(i, 1);
// Score
score++;
scoreTxt.setText(score);
// Difficulty up
if (score % 10 === 0 && enemySpawnInterval > minEnemySpawnInterval) {
enemySpawnInterval -= 6;
if (enemySpawnInterval < minEnemySpawnInterval) {
enemySpawnInterval = minEnemySpawnInterval;
}
}
if (score % 15 === 0 && enemySpeed < maxEnemySpeed) {
enemySpeed += 2;
if (enemySpeed > maxEnemySpeed) {
enemySpeed = maxEnemySpeed;
}
}
break;
}
}
}
// Spawn enemies
enemySpawnTicks++;
if (enemySpawnTicks >= enemySpawnInterval) {
enemySpawnTicks = 0;
var e = new EnemyShip();
e.x = 100 + Math.random() * (2048 - 200);
e.y = -80;
e.speed = enemySpeed;
e.shootCooldown = 30 + Math.floor(Math.random() * 40);
enemies.push(e);
game.addChild(e);
}
// Update enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var e = enemies[i];
e.update();
// Remove if off screen
if (e.y > 2732 + 100) {
e.destroy();
enemies.splice(i, 1);
continue;
}
// Enemy shooting
if (e.shootCooldown <= 0) {
var eb = new EnemyBullet();
eb.x = e.x;
eb.y = e.y + e.height / 2 + 10;
enemyBullets.push(eb);
game.addChild(eb);
e.shootCooldown = 60 + Math.floor(Math.random() * 40);
LK.getSound('enemyShoot').play();
}
}
// Update enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var eb = enemyBullets[i];
eb.update();
// Remove if off screen
if (eb.y > 2732 + 40) {
eb.destroy();
enemyBullets.splice(i, 1);
continue;
}
// Check collision with player
if (!player.invincible && !(powerUpActive && powerUpType === 'invincible') && eb.intersects(player)) {
eb.destroy();
enemyBullets.splice(i, 1);
// Damage player
player.lives--;
player.invincible = true;
player.invincibleTicks = 60;
player.flash();
// Update lives display
var livesStr = '';
for (var l = 0; l < player.lives; l++) {
livesStr += '♥';
}
livesTxt.setText(livesStr);
// Explosion
var exp = new Explosion();
exp.x = player.x;
exp.y = player.y;
explosions.push(exp);
game.addChild(exp);
LK.getSound('explosion').play();
// Game over
if (player.lives <= 0) {
gameOver = true;
LK.effects.flashScreen(0xff0000, 1200);
LK.showGameOver();
return;
}
}
}
// Update explosions (auto-destroyed by tween)
// No need to update, but clean up destroyed ones
for (var i = explosions.length - 1; i >= 0; i--) {
if (explosions[i].destroyed) {
explosions.splice(i, 1);
}
}
};
// Play background music
LK.playMusic('background_music2', {
fade: {
start: 0,
end: 1,
duration: 1000
}
}); /****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
// Enemy bullet
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bullet = self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 18;
self.update = function () {
self.y += self.speed;
};
return self;
});
// Enemy ship
var EnemyShip = Container.expand(function () {
var self = Container.call(this);
var ship = self.attachAsset('enemyShip', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = ship.width;
self.height = ship.height;
self.speed = 6;
self.shootCooldown = 0;
self.update = function () {
self.y += self.speed;
if (self.shootCooldown > 0) {
self.shootCooldown--;
}
};
return self;
});
// Explosion effect (MVP: fade out and destroy)
var Explosion = Container.expand(function () {
var self = Container.call(this);
var exp = self.attachAsset('explosion', {
anchorX: 0.5,
anchorY: 0.5
});
exp.alpha = 1;
tween(exp, {
alpha: 0
}, {
duration: 400,
easing: tween.linear,
onFinish: function onFinish() {
self.destroy();
}
});
return self;
});
// Player bullet
var PlayerBullet = Container.expand(function () {
var self = Container.call(this);
var bullet = self.attachAsset('playerBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = -28;
self.update = function () {
self.y += self.speed;
};
return self;
});
// Player ship
var PlayerShip = Container.expand(function () {
var self = Container.call(this);
var ship = self.attachAsset('playerShip', {
anchorX: 0.5,
anchorY: 0.5
});
self.width = ship.width;
self.height = ship.height;
self.lives = 3;
self.invincible = false;
self.invincibleTicks = 0;
self.update = function () {
if (self.invincible) {
self.invincibleTicks--;
ship.alpha = self.invincibleTicks % 10 < 5 ? 0.4 : 1;
if (self.invincibleTicks <= 0) {
self.invincible = false;
ship.alpha = 1;
}
}
};
// Flash for damage
self.flash = function () {
LK.effects.flashObject(self, 0xffffff, 400);
};
return self;
});
// PowerUp class
var PowerUp = Container.expand(function () {
var self = Container.call(this);
// Types: 'speed', 'double', 'invincible', 'rapid', 'shield', 'score'
self.type = 'speed';
self.duration = 600; // 10 seconds at 60fps
// Icon color by type
var colorMap = {
speed: 0x00ffff,
"double": 0xffd700,
invincible: 0xffffff,
rapid: 0xff00ff,
shield: 0x00ff00,
score: 0xff6600
};
var icon = self.attachAsset('boosts', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 3,
color: colorMap[self.type] || 0xffffff
});
self.width = icon.width;
self.height = icon.height;
self.speed = 8;
self.setType = function (type) {
self.type = type;
icon.color = colorMap[type] || 0xffffff;
};
self.update = function () {
self.y += self.speed;
};
return self;
});
// Starfield background star
var Star = Container.expand(function () {
var self = Container.call(this);
var star = self.attachAsset('star', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 0;
self.update = function () {
self.y += self.speed;
if (self.y > 2732 + 10) {
self.y = -10;
self.x = 50 + Math.random() * (2048 - 100);
self.speed = 2 + Math.random() * 4;
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000010
});
/****
* Game Code
****/
// Music (placeholder, not played in MVP)
// Sounds
// Explosion: green box (for MVP, will flash and fade)
// Star: white ellipse
// Enemy bullet: orange ellipse
// Player bullet: yellow ellipse
// Enemy ship: red box
// Player ship: blue box
// Starfield
var stars = [];
for (var i = 0; i < 60; i++) {
var star = new Star();
star.x = 50 + Math.random() * (2048 - 100);
star.y = Math.random() * 2732;
star.speed = 2 + Math.random() * 4;
stars.push(star);
game.addChild(star);
}
// Player
var player = new PlayerShip();
player.x = 2048 / 2;
player.y = 2732 - 300;
game.addChild(player);
// Player bullets
var playerBullets = [];
// Enemies
var enemies = [];
var enemyBullets = [];
// Explosions
var explosions = [];
// Power-ups
var powerUp = null;
var powerUpActive = false;
var powerUpType = null;
var powerUpTicks = 0;
var powerUpIcon = null;
var powerUpTimerTxt = null;
var nextPowerUpTicks = 300; // 5s to 8s after last
// Score and lives
var score = 0;
var scoreTxt = new Text2('0', {
size: 120,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
var livesTxt = new Text2('♥♥♥', {
size: 90,
fill: 0xFF6666
});
livesTxt.anchor.set(1, 0);
LK.gui.topRight.addChild(livesTxt);
// Power-up UI
powerUpIcon = new Container();
var iconAsset = LK.getAsset('boosts-ui', {
anchorX: 0.5,
anchorY: 0,
scaleX: 2,
scaleY: 2,
color: 0xffffff
});
powerUpIcon.addChild(iconAsset);
powerUpIcon.visible = false;
powerUpIcon.x = 120;
powerUpIcon.y = 20;
LK.gui.top.addChild(powerUpIcon);
powerUpTimerTxt = new Text2('', {
size: 60,
fill: 0xffffff
});
powerUpTimerTxt.anchor.set(0, 0);
powerUpTimerTxt.x = 60;
powerUpTimerTxt.y = 0;
powerUpIcon.addChild(powerUpTimerTxt);
// Dragging
var dragNode = null;
// Enemy spawn control
var enemySpawnTicks = 0;
var enemySpawnInterval = 60; // ticks (1s)
var enemySpeed = 6;
var minEnemySpawnInterval = 24; // fastest spawn (0.4s)
var maxEnemySpeed = 18;
// Player shoot control
var playerShootCooldown = 0;
var playerShootInterval = 12; // ticks (0.2s)
// Game state
var gameOver = false;
// Move handler
function handleMove(x, y, obj) {
if (dragNode && !gameOver) {
// Clamp to game area (leave 60px margin)
var halfW = player.width / 2;
var halfH = player.height / 2;
// Power-up: speed
var speedMult = powerUpActive && powerUpType === 'speed' ? 2 : 1;
// Move player faster if speed boost
var px = player.x + (x - player.x) * 0.2 * speedMult;
var py = player.y + (y - player.y) * 0.2 * speedMult;
var nx = Math.max(halfW + 60, Math.min(2048 - halfW - 60, px));
var ny = Math.max(halfH + 120, Math.min(2732 - halfH - 60, py));
player.x = nx;
player.y = ny;
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
if (!gameOver) {
dragNode = player;
handleMove(x, y, obj);
}
};
game.up = function (x, y, obj) {
dragNode = null;
};
// Update function
game.update = function () {
if (gameOver) {
return;
}
// Update starfield
for (var i = 0; i < stars.length; i++) {
stars[i].update();
}
// Update player
player.update();
// Power-up spawn logic
if (!powerUp && !powerUpActive) {
nextPowerUpTicks--;
if (nextPowerUpTicks <= 0) {
powerUp = new PowerUp();
// Random type
var types = ['speed', 'double', 'invincible', 'rapid', 'score'];
var t = types[Math.floor(Math.random() * types.length)];
powerUp.setType(t);
powerUp.x = 100 + Math.random() * (2048 - 200);
powerUp.y = -60;
game.addChild(powerUp);
}
}
// Power-up update
if (powerUp) {
powerUp.update();
// Remove if off screen
if (powerUp.y > 2732 + 60) {
powerUp.destroy();
powerUp = null;
nextPowerUpTicks = 300 + Math.floor(Math.random() * 180); // 5-8s
}
// Pickup
if (powerUp && powerUp.intersects(player)) {
// Activate effect
powerUpActive = true;
powerUpType = powerUp.type;
powerUpTicks = 600; // 10s
// UI
powerUpIcon.visible = true;
var colorMap = {
speed: 0x00ffff,
"double": 0xffd700,
invincible: 0xffffff,
rapid: 0xff00ff,
shield: 0x00ff00,
score: 0xff6600
};
powerUpIcon.children[0].color = colorMap[powerUpType] || 0xffffff;
powerUpTimerTxt.setText('10.0');
// Sound/Effect
LK.getSound('shoot').play();
// Remove from game
powerUp.destroy();
powerUp = null;
}
}
// Power-up effect timer
if (powerUpActive) {
powerUpTicks--;
// UI update
powerUpTimerTxt.setText((powerUpTicks / 60).toFixed(1));
if (powerUpTicks <= 0) {
// Expire
powerUpActive = false;
powerUpType = null;
powerUpIcon.visible = false;
nextPowerUpTicks = 300 + Math.floor(Math.random() * 180);
// Sound/Effect
LK.getSound('explosion').play();
}
}
// Player shooting
if (playerShootCooldown > 0) {
playerShootCooldown--;
}
if (dragNode && playerShootCooldown <= 0) {
// Power-up: double shot or rapid
if (powerUpActive && powerUpType === 'double') {
// Two bullets
for (var i = -1; i <= 1; i += 2) {
var pb = new PlayerBullet();
pb.x = player.x + i * 40;
pb.y = player.y - player.height / 2 - 10;
playerBullets.push(pb);
game.addChild(pb);
}
} else {
var pb = new PlayerBullet();
pb.x = player.x;
pb.y = player.y - player.height / 2 - 10;
playerBullets.push(pb);
game.addChild(pb);
}
// Rapid fire
if (powerUpActive && powerUpType === 'rapid') {
playerShootCooldown = Math.floor(playerShootInterval / 2);
} else {
playerShootCooldown = playerShootInterval;
}
LK.getSound('shoot').play();
}
// Update player bullets
for (var i = playerBullets.length - 1; i >= 0; i--) {
var b = playerBullets[i];
b.update();
// Remove if off screen
if (b.y < -40) {
b.destroy();
playerBullets.splice(i, 1);
continue;
}
// Check collision with enemies
for (var j = enemies.length - 1; j >= 0; j--) {
var e = enemies[j];
if (b.intersects(e)) {
// Explosion
var exp = new Explosion();
exp.x = e.x;
exp.y = e.y;
explosions.push(exp);
game.addChild(exp);
LK.getSound('explosion').play();
// Remove enemy and bullet
e.destroy();
enemies.splice(j, 1);
b.destroy();
playerBullets.splice(i, 1);
// Score
score++;
scoreTxt.setText(score);
// Difficulty up
if (score % 10 === 0 && enemySpawnInterval > minEnemySpawnInterval) {
enemySpawnInterval -= 6;
if (enemySpawnInterval < minEnemySpawnInterval) {
enemySpawnInterval = minEnemySpawnInterval;
}
}
if (score % 15 === 0 && enemySpeed < maxEnemySpeed) {
enemySpeed += 2;
if (enemySpeed > maxEnemySpeed) {
enemySpeed = maxEnemySpeed;
}
}
break;
}
}
}
// Spawn enemies
enemySpawnTicks++;
if (enemySpawnTicks >= enemySpawnInterval) {
enemySpawnTicks = 0;
var e = new EnemyShip();
e.x = 100 + Math.random() * (2048 - 200);
e.y = -80;
e.speed = enemySpeed;
e.shootCooldown = 30 + Math.floor(Math.random() * 40);
enemies.push(e);
game.addChild(e);
}
// Update enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var e = enemies[i];
e.update();
// Remove if off screen
if (e.y > 2732 + 100) {
e.destroy();
enemies.splice(i, 1);
continue;
}
// Enemy shooting
if (e.shootCooldown <= 0) {
var eb = new EnemyBullet();
eb.x = e.x;
eb.y = e.y + e.height / 2 + 10;
enemyBullets.push(eb);
game.addChild(eb);
e.shootCooldown = 60 + Math.floor(Math.random() * 40);
LK.getSound('enemyShoot').play();
}
}
// Update enemy bullets
for (var i = enemyBullets.length - 1; i >= 0; i--) {
var eb = enemyBullets[i];
eb.update();
// Remove if off screen
if (eb.y > 2732 + 40) {
eb.destroy();
enemyBullets.splice(i, 1);
continue;
}
// Check collision with player
if (!player.invincible && !(powerUpActive && powerUpType === 'invincible') && eb.intersects(player)) {
eb.destroy();
enemyBullets.splice(i, 1);
// Damage player
player.lives--;
player.invincible = true;
player.invincibleTicks = 60;
player.flash();
// Update lives display
var livesStr = '';
for (var l = 0; l < player.lives; l++) {
livesStr += '♥';
}
livesTxt.setText(livesStr);
// Explosion
var exp = new Explosion();
exp.x = player.x;
exp.y = player.y;
explosions.push(exp);
game.addChild(exp);
LK.getSound('explosion').play();
// Game over
if (player.lives <= 0) {
gameOver = true;
LK.effects.flashScreen(0xff0000, 1200);
LK.showGameOver();
return;
}
}
}
// Update explosions (auto-destroyed by tween)
// No need to update, but clean up destroyed ones
for (var i = explosions.length - 1; i >= 0; i--) {
if (explosions[i].destroyed) {
explosions.splice(i, 1);
}
}
};
// Play background music
LK.playMusic('background_music2', {
fade: {
start: 0,
end: 1,
duration: 1000
}
});
give me a low polly bullet look under. In-Game asset. 2d. High contrast. No shadows
explosion. In-Game asset. 2d. High contrast. No shadows
low polly white star. In-Game asset. 2d. High contrast. No shadows
i need general boost img. In-Game asset. 2d. High contrast. No shadows
add fire on ass
add fire on ass