User prompt
Rotate enemy bullets 180 degrees
User prompt
Remove the code that removes enemies if they exit the screen at the bottom as it's not needed
User prompt
Make sure the location where enemies stop flying down the screen is such that the enemy is always fully visible
User prompt
Decrease the alpha of the background stars
User prompt
Make sure the enemy health bar uses the enemy total health when inited
User prompt
Update the enemy class to accept currentWave as an argument during creation. Then use the current wave information to set total health of the enemy
User prompt
Parse the wave information into the enemy constructor
User prompt
Always spawn 5 enemies
User prompt
Increase the alpha of the background stars
User prompt
Increase the alpha of the background stars
User prompt
Make the background stars move slower
User prompt
When the y value of the background makes the top of the background edge visible on the screen reset the y. Use the hight of the image to determine when this is.
User prompt
set background alpha to .4
User prompt
Add .5 to background y every tick
User prompt
Set the anchor point on the background image to .5,1
User prompt
Fix Bug: 'undefined' in this line: 'heroGraphics.tint = 0xffffff;' Line Number: 102
User prompt
Make background have 20% opacity
User prompt
Make the background element centered on the screen
User prompt
Add background element behind the stars in the games class
User prompt
In the update game objects function, destroy enemy bulles if they exit the screen left or right
User prompt
Fix Bug: 'TypeError: undefined is not an object (evaluating 'powerup.intersects')' in this line: 'if (powerup.intersects(hero)) {' Line Number: 306
User prompt
When collecting a powerup, remove all other powerups, such that only one powerup can be collected per round
User prompt
When spawning powerups, spawn 3 random powerups spaced equally on the screen.
User prompt
Set initial hero bullet acceleration to .2
User prompt
Pass along the hero acceleration variable to hero bullet move and use that instead of it's own acceleration variable
var Powerup = Container.expand(function (type) {
var self = Container.call(this);
self.type = type;
var powerupGraphics;
switch (type) {
case 'extraBullet':
powerupGraphics = XS.getAsset('extraBulletPowerup', 'Extra Bullet Powerup Graphics', 0.5, 0.5);
break;
case 'shield':
powerupGraphics = XS.getAsset('shieldPowerup', 'Shield Powerup Graphics', 0.5, 0.5);
break;
case 'speed':
powerupGraphics = XS.getAsset('speedPowerup', 'Speed Powerup Graphics', 0.5, 0.5);
break;
case 'health':
powerupGraphics = XS.getAsset('healthPowerup', 'Health Powerup Graphics', 0.5, 0.5);
break;
case 'missileSpeed':
powerupGraphics = XS.getAsset('missileSpeedPowerup', 'Missile Speed Powerup Graphics', 0.5, 0.5);
break;
default:
powerupGraphics = XS.getAsset('powerup', 'Powerup Graphics', 0.5, 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 = XS.getAsset('healthBar', 'Health Bar Graphics', .5, 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) {
var self = Container.call(this);
var bulletGraphics = XS.getAsset('heroBullet', 'Hero Bullet Graphics', 0.5, 0.5);
self.addChild(bulletGraphics);
self.speed = 0;
self.acceleration = acceleration;
self.move = function () {
self.speed += self.acceleration;
self.y -= self.speed;
};
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = XS.getAsset('enemyBullet', 'Enemy Bullet Graphics', 0.5, 0.5);
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);
var heroGraphics = XS.getAsset('hero', 'Hero Spaceship', 0.5, 0.5);
self.addChild(heroGraphics);
self.health = 100;
self.healthBar = self.addChild(new HealthBar(100, 0x00ff00));
self.healthBar.y = -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 = XS.getAsset('shieldEffect', 'Shield Effect Graphics', 0.5, 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);
} else {
self.shieldBar.visible = false;
self.shieldEffect.visible = false;
self.shieldBar.updateHealth(0);
}
};
self.updateShield();
self.hitEffectCounter = 0;
self.shield = 0;
self.fireRate = 30;
self.bulletCount = 1;
self.acceleration = 1;
self.updateHitEffect = function () {
if (self.hitEffectCounter > 0) {
heroGraphics.tint = 0xff0000 + (0xffffff - 0xff0000) * (10 - self.hitEffectCounter) / 10;
self.hitEffectCounter--;
} else {
heroGraphics.tint = 0xffffff;
}
};
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = XS.getAsset('enemy', 'Enemy Spaceship', 0.5, 0.5);
self.addChild(enemyGraphics);
self.speed = 6;
self.health = 50;
self.targetY = Math.random() * (2732 / 3);
self.sidewaysOffset = Math.random() * 60;
self.healthBar = self.addChild(new HealthBar(50, 0xff0000));
self.healthBar.y = -enemyGraphics.height / 2 - 50;
self.healthBar.updateHealth(self.health);
self.hitEffectCounter = 0;
self.updateHitEffect = function () {
if (self.hitEffectCounter > 0) {
enemyGraphics.tint = 0xff0000 + (0xffffff - 0xff0000) * (10 - self.hitEffectCounter) / 10;
self.hitEffectCounter--;
} else {
enemyGraphics.tint = 0xffffff;
}
};
self.move = function () {
if (self.y < self.targetY) {
self.y += self.speed;
}
self.x += Math.sin((XS.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 = XS.getAsset('star', 'Star Graphics', 0.5, 0.5);
self.addChild(starGraphics);
self.speed = (Math.random() * 2 + 1) * 1.5;
self.alpha = self.speed / 3;
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;
}
};
});
var Game = Container.expand(function () {
var self = Container.call(this);
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);
self.addChild(star);
}
var hero = self.addChild(new Hero());
hero.x = 1024;
hero.y = 2400;
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"
});
scoreText.anchor.set(0.5, 0);
XS.gui.topCenter.addChild(scoreText);
var powerupLabel = new Text2('', {
size: 64,
font: "'GillSans-Bold',Impact,'Arial Black',Tahoma",
fill: "#ffffff"
});
powerupLabel.anchor.set(0.5, 0);
XS.gui.topCenter.addChild(powerupLabel);
powerupLabel.y = scoreText.height + 10;
powerupLabel.visible = false;
function spawnWave() {
for (var i = 0; i < currentWave + 3; i++) {
var enemy = new Enemy();
enemy.x = Math.random() * 2048;
enemy.y = -100 - i * 100;
enemies.push(enemy);
self.addChild(enemy);
}
allEnemiesKilled = false;
var powerupTypes = ['health', 'speed', 'shield'];
if (hero.bulletCount < 5) {
powerupTypes.push('extraBullet');
}
if (hero.fireRate > 5) {
powerupTypes.push('powerup');
}
powerupTypes.push('missileSpeed');
var powerupType = powerupTypes[Math.floor(Math.random() * powerupTypes.length)];
var powerup = new Powerup(powerupType);
powerup.x = Math.random() * 2048;
powerup.y = -100;
powerups.push(powerup);
self.addChild(powerup);
}
function fireHeroBullet() {
var angleStep = Math.PI / (hero.bulletCount + 1);
for (var i = 0; i < hero.bulletCount; i++) {
var bullet = new HeroBullet(hero.acceleration);
bullet.x = hero.x + Math.cos((i + 1) * angleStep) * 100;
bullet.y = hero.y - Math.sin((i + 1) * angleStep) * 100;
heroBullets.push(bullet);
self.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);
enemyBullets.push(bullet);
self.addChild(bullet);
}
function updateGameObjects() {
enemies.forEach(function (enemy, index) {
enemy.move();
if (enemy.y > 2732) {
enemy.destroy();
enemies.splice(index, 1);
}
});
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.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.intersects(enemy)) {
heroBullet.destroy();
heroBullets.splice(hIndex, 1);
enemy.health -= 10;
enemy.healthBar.updateHealth(enemy.health);
enemy.hitEffectCounter = 10;
if (enemy.health <= 0) {
enemy.destroy();
enemies.splice(eIndex, 1);
score += 100;
scoreText.setText(score);
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();
} else {
hero.health -= 10;
hero.healthBar.updateHealth(hero.health);
hero.hitEffectCounter = 10;
}
}
}
for (var index = powerups.length - 1; index >= 0; index--) {
var powerup = powerups[index];
if (powerup.intersects(hero)) {
powerup.destroy();
powerups.splice(index, 1);
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;
}
powerupLabel.visible = true;
XS.setTimeout(function () {
powerupLabel.visible = false;
}, 3000);
}
}
}
var targetPosition = {
x: hero.x,
y: hero.y
};
stage.on('down', function (obj) {
targetPosition = obj.event.getLocalPosition(self);
});
stage.on('move', function (obj) {
targetPosition = obj.event.getLocalPosition(self);
});
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);
hero.x += maxSpeed * Math.cos(angle);
hero.y += maxSpeed * Math.sin(angle);
} else {
hero.x = targetPosition.x;
hero.y = targetPosition.y;
}
}
function handleTick() {
moveHeroTowardsTarget();
updateGameObjects();
checkCollisions();
starField.forEach(function (star) {
star.move();
});
if (allEnemiesKilled) {
currentWave++;
spawnWave();
}
if (hero.health <= 0) {
XS.showGameOver();
}
if (XS.ticks % Math.floor(hero.fireRate) === 0) {
fireHeroBullet();
}
enemies.forEach(function (enemy, index) {
enemy.updateHitEffect();
if (XS.ticks % 90 === 0) {
fireEnemyBullet(enemy);
}
if (XS.ticks % 180 === 0 && index % 2 === 0) {
fireEnemyBullet(enemy);
}
});
hero.updateHitEffect();
}
XS.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
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.
Stylish hero spaceship facing upwards, with a single cannon in the center. Single Game Texture. In-Game asset. 2d. Pixelart. White background. Blank background. Low detail. High contrast.
single alien enemy spaceship facing down, looking like space alien adopted to living in space. 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.