/****
* Classes
****/
var EngineParticle = Container.expand(function () {
var self = Container.call(this);
var particleGraphics = self.attachAsset('engineParticle', {
anchorX: 0.5,
anchorY: 0.5
});
particleGraphics.rotation = Math.random() * Math.PI * 2;
particleGraphics.blendMode = 1;
self.speed = 20;
self.move = function () {
self.y += self.speed;
self.alpha -= 0.03;
if (self.alpha <= 0) {
self.destroy();
}
};
});
var Powerup = Container.expand(function (type) {
var self = Container.call(this);
self.type = type;
var powerupGraphics;
switch (type) {
case 'extraBullet':
powerupGraphics = LK.getAsset('extraBulletPowerup', {
anchorX: 0.5,
anchorY: 0.5
});
break;
case 'shield':
powerupGraphics = LK.getAsset('shieldPowerup', {
anchorX: 0.5,
anchorY: 0.5
});
break;
case 'speed':
powerupGraphics = LK.getAsset('speedPowerup', {
anchorX: 0.5,
anchorY: 0.5
});
break;
case 'health':
powerupGraphics = LK.getAsset('healthPowerup', {
anchorX: 0.5,
anchorY: 0.5
});
break;
case 'missileSpeed':
powerupGraphics = LK.getAsset('missileSpeedPowerup', {
anchorX: 0.5,
anchorY: 0.5
});
break;
case 'curveBullet':
powerupGraphics = LK.getAsset('curveBulletPowerup', {
anchorX: 0.5,
anchorY: 0.5
});
break;
case 'scoreMultiplier':
powerupGraphics = LK.getAsset('scoreMultiplierPowerup', {
anchorX: 0.5,
anchorY: 0.5
});
break;
default:
powerupGraphics = LK.getAsset('powerup', {
anchorX: 0.5,
anchorY: 0.5
});
break;
}
self.addChild(powerupGraphics);
self.speed = 3;
self.move = function () {
self.y += self.speed;
};
});
var HealthBar = Container.expand(function (maxHealth, color) {
var self = Container.call(this);
var barGraphics = LK.getAsset('healthBar', {
anchorX: 0.5,
anchorY: 1
});
barGraphics.tint = color;
self.addChild(barGraphics);
self.maxHealth = maxHealth;
self.currentHealth = maxHealth;
self.updateHealth = function (newHealth) {
self.currentHealth = newHealth;
barGraphics.scale.x = self.currentHealth / self.maxHealth;
};
self.intersectable = false;
});
var HeroBullet = Container.expand(function (acceleration, enemies, curveBullet) {
var self = Container.call(this);
var bulletGraphics = LK.getAsset('heroBullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.addChild(bulletGraphics);
self.speed = 10;
self.acceleration = 0.2;
self.curveBullet = curveBullet || 0;
self.move = function () {
self.speed += self.acceleration;
var speedX = 0;
var speedY = -self.speed;
if (self.curveBullet > 0 && enemies.length > 0) {
var nearestEnemy = enemies.reduce(function (nearest, enemy) {
var dx = self.x - enemy.x;
var dy = self.y - enemy.y;
var distance = Math.sqrt(dx * dx + dy * dy);
return distance < nearest.distance ? {
enemy: enemy,
distance: distance
} : nearest;
}, {
enemy: null,
distance: Infinity
});
if (nearestEnemy.enemy) {
var angle = Math.atan2(nearestEnemy.enemy.y - self.y, nearestEnemy.enemy.x - self.x);
speedX = self.speed * Math.cos(angle) * self.curveBullet * 0.1;
speedY = -self.speed;
self.rotation = Math.atan2(speedY, speedX) + Math.PI / 2;
}
}
self.x += speedX;
self.y += speedY;
};
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = LK.getAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
bulletGraphics.rotation = Math.PI;
self.addChild(bulletGraphics);
self.speed = 5;
self.move = function () {
self.x += self.speedX;
self.y += self.speedY;
};
});
var Hero = Container.expand(function () {
var self = Container.call(this);
self.heroGraphics = LK.getAsset('hero', {
anchorX: 0.5,
anchorY: 0.5
});
self.addChild(self.heroGraphics);
self.health = 100;
self.healthBar = self.addChild(new HealthBar(100, 0x00ff00));
self.healthBar.y = -self.heroGraphics.height / 2 - 50;
self.healthBar.updateHealth(self.health);
self.shieldBar = self.addChild(new HealthBar(10, 0x4682B4));
self.shieldBar.y = self.healthBar.y - 30;
self.shieldBar.visible = false;
self.shieldEffect = LK.getAsset('shieldEffect', {
anchorX: 0.5,
anchorY: 0.5
});
self.shieldEffect.visible = false;
self.shieldEffect.alpha = 0.5;
self.addChildAt(self.shieldEffect, 1);
self.updateShield = function () {
if (self.shield > 0) {
self.shieldBar.visible = true;
self.shieldEffect.visible = true;
self.shieldBar.updateHealth(self.shield);
self.shieldEffect.alpha = self.shield / 10 / 2;
} else {
self.shieldBar.visible = false;
self.shieldEffect.visible = false;
self.shieldBar.updateHealth(0);
}
};
self.updateShield();
self.hitEffectCounter = 0;
self.curveBullet = 0;
self.shield = 0;
self.fireRate = 30;
self.bulletCount = 1;
self.acceleration = 1;
self.scoreMultiplier = 1;
});
var Enemy = Container.expand(function (currentWave) {
var self = Container.call(this);
var enemyGraphics = LK.getAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.addChild(enemyGraphics);
self.speed = 6;
self.targetSpeed = 6;
self.health = 30 + currentWave * 10;
self.targetY = Math.random() * (2732 / 3) + enemyGraphics.height;
self.sidewaysOffset = Math.random() * 60;
self.healthBar = self.addChild(new HealthBar(self.health, 0xff0000));
self.healthBar.y = -enemyGraphics.height / 2 - 50;
self.healthBar.updateHealth(self.health);
self.hitEffectCounter = 0;
self.tickOffset = Math.floor(Math.random() * 90);
self.move = function () {
if (self.y < self.targetY) {
self.speed = Math.min(self.targetSpeed, self.speed + 0.5);
self.y += self.speed;
}
self.x += Math.sin((LK.ticks + self.sidewaysOffset) / 30) * 5;
if (self.x < 0) {
self.x = 0;
}
if (self.x > 2048 - enemyGraphics.width) {
self.x = 2048 - enemyGraphics.width;
}
};
});
var StarField = Container.expand(function () {
var self = Container.call(this);
var starGraphics = LK.getAsset('star', {
anchorX: 0.5,
anchorY: 0.5
});
starGraphics.rotation = Math.random() * Math.PI * 2;
starGraphics.blendMode = 1;
self.addChild(starGraphics);
self.speed = (Math.random() * 2 + 1) * 2;
self.alpha = self.speed / 4;
self.move = function () {
self.y += self.speed;
if (self.y > 2732) {
self.y = -100;
self.x = Math.random() * 2048;
self.speed = Math.random() * 2 + 1;
self.alpha = self.speed / 3;
}
};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x1c0921
});
/****
* Game Code
****/
var background = LK.getAsset('background', {
anchorX: 0.5,
anchorY: 1
});
background.x = 2048 / 2;
background.y = 2732;
background.alpha = 0.8;
game.addChild(background);
var starField = [];
for (var i = 0; i < 100; i++) {
var star = new StarField();
star.x = Math.random() * 2048;
star.y = Math.random() * 2732;
starField.push(star);
game.addChild(star);
}
var hero = game.addChild(new Hero());
hero.x = 1024;
hero.y = 2400;
hero.previousX = hero.x;
var particles = [];
var enemies = [];
var heroBullets = [];
var enemyBullets = [];
var powerups = [];
var score = 0;
var currentWave = 0;
var allEnemiesKilled = true;
var scoreText = new Text2('0', {
size: 100,
font: "'GillSans-Bold',Impact,'Arial Black',Tahoma",
fill: "#ffffff",
defaultFont: "'Arial', sans-serif",
dropShadow: true,
dropShadowColor: '#000000',
dropShadowBlur: 4,
dropShadowAngle: Math.PI / 6,
dropShadowDistance: 6
});
scoreText.anchor.set(0.5, 0);
LK.gui.topCenter.addChild(scoreText);
var powerupLabel = new Text2('', {
size: 64,
font: "Verdana",
fill: "#ffffff",
dropShadow: true,
dropShadowColor: '#000000',
dropShadowBlur: 4,
dropShadowAngle: Math.PI / 6,
dropShadowDistance: 6
});
powerupLabel.anchor.set(0.5, 0);
LK.gui.topCenter.addChild(powerupLabel);
powerupLabel.y = scoreText.height + 10;
powerupLabel.visible = false;
function spawnWave() {
for (var i = 0; i < 5; i++) {
var enemy = new Enemy(currentWave);
enemy.x = Math.random() * 2048;
enemy.y = -100 - i * 100;
enemies.push(enemy);
game.addChild(enemy);
}
allEnemiesKilled = false;
var powerupTypes = ['health', 'speed', 'shield'];
if (hero.bulletCount < 5) {
powerupTypes.push('extraBullet');
}
if (hero.fireRate > 20) {
powerupTypes.push('powerup');
}
powerupTypes.push('missileSpeed', 'curveBullet', 'scoreMultiplier');
for (var i = 0; i < 3; i++) {
var powerupType = powerupTypes[Math.floor(Math.random() * powerupTypes.length)];
var powerup = new Powerup(powerupType);
powerup.x = (i + 1) * 2048 / 4;
powerup.y = -100;
powerups.push(powerup);
game.addChild(powerup);
}
var waveText = new Text2('Wave ' + currentWave, {
size: 200,
font: "'GillSans-Bold',Impact,'Arial Black',Tahoma",
fill: "#ffffff",
dropShadow: true,
dropShadowColor: '#000000',
dropShadowBlur: 4,
dropShadowAngle: Math.PI / 6,
dropShadowDistance: 6
});
waveText.anchor.set(0.5, 0.5);
waveText.x = 2048 / 2;
waveText.y = 2732 / 2;
game.addChild(waveText);
LK.setTimeout(function () {
waveText.destroy();
}, 2000);
}
function fireHeroBullet(enemies, curveBullet) {
var angleStep = Math.PI / (hero.bulletCount + 1);
for (var i = 0; i < hero.bulletCount; i++) {
var bullet = new HeroBullet(hero.acceleration, enemies, curveBullet);
bullet.x = hero.x + Math.cos((i + 1) * angleStep) * 100;
bullet.y = hero.y - Math.sin((i + 1) * angleStep) * 100;
heroBullets.push(bullet);
game.addChild(bullet);
}
}
function fireEnemyBullet(enemy) {
var bullet = new EnemyBullet();
bullet.x = enemy.x;
bullet.y = enemy.y + 50;
var angle = Math.atan2(hero.y - bullet.y, hero.x - bullet.x);
bullet.speedX = bullet.speed * Math.cos(angle);
bullet.speedY = bullet.speed * Math.sin(angle);
bullet.rotation = angle - Math.PI / 2;
enemyBullets.push(bullet);
game.addChild(bullet);
}
function updateGameObjects() {
enemies.forEach(function (enemy, index) {
enemy.move();
});
for (var index = heroBullets.length - 1; index >= 0; index--) {
var bullet = heroBullets[index];
bullet.move();
if (bullet.y < 0) {
bullet.destroy();
heroBullets.splice(index, 1);
}
}
for (var index = enemyBullets.length - 1; index >= 0; index--) {
var bullet = enemyBullets[index];
bullet.move();
if (bullet.y > 2732 || bullet.x < 0 || bullet.x > 2048) {
bullet.destroy();
enemyBullets.splice(index, 1);
}
}
for (var index = powerups.length - 1; index >= 0; index--) {
var powerup = powerups[index];
powerup.move();
if (powerup.y > 2732) {
powerup.destroy();
powerups.splice(index, 1);
}
}
}
function checkCollisions() {
for (var hIndex = heroBullets.length - 1; hIndex >= 0; hIndex--) {
var heroBullet = heroBullets[hIndex];
for (var eIndex = enemies.length - 1; eIndex >= 0; eIndex--) {
var enemy = enemies[eIndex];
if (heroBullet && enemy && heroBullet.intersects(enemy)) {
heroBullet.destroy();
heroBullets.splice(hIndex, 1);
heroBullet = null;
enemy.health -= 10;
enemy.healthBar.updateHealth(enemy.health);
enemy.hitEffectCounter = 10;
enemy.speed = -5;
enemy.y -= 7;
LK.effects.flashObject(enemy, 0xff0000, 1000);
if (enemy.health <= 0) {
enemy.destroy();
enemies.splice(eIndex, 1);
score += Math.floor(100 * hero.scoreMultiplier);
LK.setScore(score);
scoreText.setText(LK.getScore());
if (enemies.length === 0) {
allEnemiesKilled = true;
}
}
}
}
}
for (var index = enemyBullets.length - 1; index >= 0; index--) {
var enemyBullet = enemyBullets[index];
if (enemyBullet.intersects(hero)) {
enemyBullet.destroy();
enemyBullets.splice(index, 1);
if (hero.shield > 0) {
hero.shield--;
hero.updateShield();
LK.effects.flashObject(hero.shieldEffect, 0xff0000, 1000);
} else {
hero.health -= 10;
hero.healthBar.updateHealth(hero.health);
hero.hitEffectCounter = 10;
LK.effects.flashObject(hero, 0xff0000, 1000);
}
}
}
for (var index = powerups.length - 1; index >= 0; index--) {
var powerup = powerups[index];
if (powerup && powerup.intersects(hero)) {
for (var i = powerups.length - 1; i >= 0; i--) {
powerups[i].destroy();
}
powerups = [];
switch (powerup.type) {
case 'powerup':
hero.fireRate = Math.max(5, hero.fireRate * 0.9);
powerupLabel.setText('+10% Rate of Fire');
break;
case 'health':
hero.health = 100;
hero.healthBar.updateHealth(hero.health);
powerupLabel.setText('Health restored');
break;
case 'speed':
hero.speed *= 1.1;
powerupLabel.setText('+10% Speed');
break;
case 'shield':
hero.shield = 10;
hero.updateShield();
powerupLabel.setText('Shield');
break;
case 'extraBullet':
hero.bulletCount++;
powerupLabel.setText('Extra Bullet');
break;
case 'missileSpeed':
hero.acceleration *= 1.1;
powerupLabel.setText('Missile Speed +10%');
break;
case 'curveBullet':
hero.curveBullet += 1;
powerupLabel.setText('Enhancing Bullet Homing');
break;
case 'scoreMultiplier':
hero.scoreMultiplier += 0.1;
powerupLabel.setText('Score Multiplier +10%');
break;
}
powerupLabel.visible = true;
LK.setTimeout(function () {
powerupLabel.visible = false;
}, 3000);
}
}
}
var targetPosition = {
x: hero.x,
y: hero.y
};
game.on('down', function (obj) {
targetPosition = obj.event.getLocalPosition(game);
});
game.on('move', function (obj) {
targetPosition = obj.event.getLocalPosition(game);
});
function moveHeroTowardsTarget() {
var dx = targetPosition.x - hero.x;
var dy = targetPosition.y - hero.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var maxSpeed = 15;
if (distance > maxSpeed) {
var angle = Math.atan2(dy, dx);
var oldX = hero.x;
hero.x += maxSpeed * Math.cos(angle);
hero.y += maxSpeed * Math.sin(angle);
var deltaX = hero.x - oldX;
var targetRotation = deltaX !== 0 ? Math.sign(deltaX) * Math.PI / 30 : 0;
hero.heroGraphics.rotation += (targetRotation - hero.heroGraphics.rotation) * 0.1;
} else {
var oldX = hero.x;
hero.x = targetPosition.x;
hero.y = targetPosition.y;
var deltaX = hero.x - oldX;
var targetRotation = deltaX !== 0 ? Math.sign(deltaX) * Math.PI / 30 : 0;
hero.heroGraphics.rotation += (targetRotation - hero.heroGraphics.rotation) * 0.1;
}
}
function handleTick() {
background.y += 0.5;
if (background.y >= background.height) {
background.y = 2732;
}
moveHeroTowardsTarget();
var particle = new EngineParticle();
particle.x = hero.x;
particle.y = hero.y + 75;
particles.push(particle);
game.addChild(particle);
updateGameObjects();
checkCollisions();
particles.forEach(function (particle, index) {
particle.move();
if (particle.alpha <= 0) {
particles.splice(index, 1);
}
});
starField.forEach(function (star) {
star.move();
});
if (allEnemiesKilled) {
currentWave++;
spawnWave();
}
if (hero.health <= 0) {
LK.showGameOver();
}
if (LK.ticks % Math.floor(hero.fireRate) === 0) {
fireHeroBullet(enemies, hero.curveBullet);
heroBullets.forEach(function (bullet) {
game.addChildAt(bullet, game.getChildIndex(hero));
});
}
enemies.forEach(function (enemy, index) {
if ((LK.ticks + enemy.tickOffset) % Math.max(60, 180 - currentWave * 5) === 0) {
fireEnemyBullet(enemy);
}
});
}
LK.on('tick', handleTick);
Round powerup. Shield icon Single Game Texture. In-Game asset. 2d. Pixelart. White background. Blank background. Low detail. High contrast.
Extra missile powerup circle. Missile and plus sign. Single Game Texture. In-Game asset. 2d. Pixelart. White background. Blank background. Low detail. High contrast.
Single space torpedo flying upwards Game Texture. In-Game asset. 2d. Pixelart. White background. Blank background. Low detail. High contrast.
Background galaxy nebulas and galaxies Single Game Texture. In-Game asset. 2d. Pixelart. White background. Blank background. Low detail. High contrast. --ar 1:10
Hero Space Ship facing upwards. 2D art, game texture, blank background. Sprite sheet asset. Design Guideline: The game's style is bright, high-quality vector graphics with sharp, clean lines and a modern aesthetic. Colors should be vivid and contrast well, emphasizing a futuristic, sleek feel. Textures are minimalistic, focusing on flat surfaces with subtle gradients for depth. Lighting effects are dynamic yet soft, enhancing the vibrancy without overpowering. Assets should look consistent, fitting a coherent, tech-savvy universe. Think 'sophisticated simplicity' for a futuristic, engaging spaceship game.
Game texture, Single Spaceship Engine exhaust light particle, yellow blue fire. Black background.
Alien Space enemy ship facing down 2D art, game texture, blank background. Sprite sheet asset. Design Guideline: The game's style is bright, high-quality vector graphics with sharp, clean lines and a modern aesthetic. Colors should be vivid and contrast well, emphasizing a futuristic, sleek feel. Textures are minimalistic, focusing on flat surfaces with subtle gradients for depth. Lighting effects are dynamic yet soft, enhancing the vibrancy without overpowering. Assets should look consistent, fitting a coherent, tech-savvy universe. Think 'sophisticated simplicity' for a futuristic, engaging spaceship game.
single Star particle, black background 2D art, game texture, blank background. Sprite sheet asset. Design Guideline: The game's style is bright, high-quality vector graphics with sharp, clean lines and a modern aesthetic. Colors should be vivid and contrast well, emphasizing a futuristic, sleek feel. Textures are minimalistic, focusing on flat surfaces with subtle gradients for depth. Lighting effects are dynamic yet soft, enhancing the vibrancy without overpowering. Assets should look consistent, fitting a coherent, tech-savvy universe. Think 'sophisticated simplicity' for a futuristic, engaging spaceship game.
Round powerup. Green health icon Single Game Texture. In-Game asset. 2d. Pixelart. White background. Blank background. Low detail. High contrast.
Blue glowing powerup circle with s in center Single Game Texture. In-Game asset. 2d. Pixelart. White background. Blank background. Low detail. High contrast.
Round powerup. Lightning icon pointing up. Single Game Texture. In-Game asset. 2d. Pixelart. White background. Blank background. Low detail. High contrast.
Single enemy slime bullet, seen from above facing upwards. Single Game Texture. In-Game asset. 2d. Pixelart. White background. Blank background. Low detail. High contrast.
Round powerup icon with bullseye Single Game Texture. In-Game asset. 2d. Pixelart. White background. Blank background. Low detail. High contrast.
Clean plasma bubble Single Game Texture. In-Game asset. 2d. Pixelart. White background. Blank background. Low detail. High contrast.