User prompt
Enemy bullets should not intersect enemies
User prompt
Fix Bug: 'TypeError: overlay.setPosition is not a function. (In 'overlay.setPosition(2048 / 2, 2732)', 'overlay.setPosition' is undefined)' in this line: 'overlay.setPosition(2048 / 2, 2732);' Line Number: 417
User prompt
Fix Bug: 'ReferenceError: Can't find variable: OverlayElement' in this line: 'var overlay = self.addChild(new OverlayElement());' Line Number: 417
User prompt
OverlayElement is deprecated, remove this class and switch the game to use XS.effects.flashScreen for the same functionality
User prompt
Fix Bug: 'ReferenceError: Can't find variable: targetIndicator' in this line: 'targetIndicator.visible = false;' Line Number: 372
User prompt
Inline creation of targetIndicator and addChild of node
User prompt
When creating obstacles inline addChilde with the object creation
User prompt
Where targetIndicator x and y is set use set position
User prompt
Where obstacles are spawned use setPosition
User prompt
when setting targetIndicator x and y at once use set position
User prompt
In player when setting position of overlay use set position
User prompt
in spawn enemy When both setting x and y of element in two subsequent lines use .setPosition instead
User prompt
in spawn enemies When both setting x and y of element in two subsequent lines use .setPosition instead
User prompt
In createExplosion When both setting x and y of element in two subsequent lines use .setPosition instead
User prompt
Fix Bug: 'ReferenceError: Can't find variable: healthBar' in this line: 'self.healthBar = healthBar;' Line Number: 98
User prompt
Fix Bug: 'ReferenceError: Can't find variable: playerShadow' in this line: 'playerShadow.alpha = 0.3;' Line Number: 95
User prompt
In Player Rather than first creating an asset using var xxx = XS.getAsset and then attaching it with xxx = self.addChild(...) do this in one call where possible. Replace 3 instances where this is not already done
User prompt
In exit door Rather than first creating an asset using var xxx = XS.getAsset and then attaching it with xxx = self.addChild(...) do this in one call where possible. Replace 3 instances where this is not already done
User prompt
Rather than first creating an asset using var xxx = XS.getAsset and then attaching it with xxx = self.addChild(...) do this in one call where possible. Replace 3 instances where this is not already done
User prompt
Rather than setting scale x and y use scale.set
User prompt
Fix Bug: 'ReferenceError: Can't find variable: particleGraphics' in this line: 'particleGraphics.scale.x *= 0.98;' Line Number: 51
User prompt
use variable = self.addChild(XS.getAsset(...)) when possible
User prompt
When setting x and y at the same time use setPosition
User prompt
Add a type argument to bullet which determines if it's a player or enemy bullet
User prompt
Enemies are not throwing things at the hero
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.addChild(XS.getAsset('obstacle', 'Obstacle', .5, 1));
obstacleGraphics.y += 50;
});
var ExitDoor = Container.expand(function () {
var self = Container.call(this);
var backgroundElement = self.addChild(XS.getAsset('backgroundElement1', 'Background Element 1', .5, .5));
backgroundElement.y -= 760;
var backgroundElement2 = self.addChild(XS.getAsset('backgroundElement2', 'Background Element 2', .5, .5));
backgroundElement2.y -= 760;
backgroundElement2.blendMode = 1;
var doorGraphics = self.addChild(XS.getAsset('exitDoor', 'Exit Door', .5, 1));
self.rotationSpeed1 = 0.005 * 0.25;
self.rotationSpeed2 = 0.007 * 0.25;
self.rotate = function () {
backgroundElement.rotation += self.rotationSpeed1;
backgroundElement2.rotation -= self.rotationSpeed2;
};
});
var EnemySpawnIndicator = Container.expand(function () {
var self = Container.call(this);
var spawnIndicatorGraphics = self.addChild(XS.getAsset('spawnIndicator', 'Enemy Spawn Indicator', .5, .5));
spawnIndicatorGraphics.alpha = 0.5;
});
var ExplosionParticle = Container.expand(function () {
var self = Container.call(this);
var particleGraphics = self.addChild(XS.getAsset('particle', 'Explosion Particle', .5, .5));
self.dx = (Math.random() - 0.5) * 10;
self.dy = (Math.random() - 0.5) * 7;
self.move = function () {
self.setPosition(self.x + self.dx, self.y + self.dy);
self.alpha -= 0.02;
particleGraphics.scale.set(particleGraphics.scale.x * 0.98, particleGraphics.scale.y * 0.98);
self.dx *= 0.98;
self.dy *= 0.98;
if (self.alpha <= 0) {
self.destroy();
}
};
});
var HealthBar = Container.expand(function () {
var self = Container.call(this);
var healthBarGraphics = XS.getAsset('healthBar', 'Health Bar', .5, 1);
self.addChild(healthBarGraphics);
self.setTint = function (tint) {
healthBarGraphics.tint = tint;
};
self.setTint(0x00FF00);
self.updateHealth = function (health) {
self.scale.set(health / 100, 1);
};
});
var TargetIndicator = Container.expand(function () {
var self = Container.call(this);
var targetGraphics = XS.getAsset('target', 'Target Indicator', .5, .5);
targetGraphics.alpha = 0.5;
targetGraphics.y -= 30;
self.addChild(targetGraphics);
});
var Player = Container.expand(function () {
var self = Container.call(this);
self.health = 100;
self.findNearestEnemy = function (enemies) {
var nearestEnemy = null;
var nearestDistance = Infinity;
for (var i = 0; i < enemies.length; i++) {
var dx = enemies[i].x - self.x;
var dy = enemies[i].y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < nearestDistance && !self.parent.lineIntersectsObstacle(self.x, self.y, enemies[i].x, enemies[i].y)) {
nearestDistance = distance;
nearestEnemy = enemies[i];
}
}
return nearestEnemy;
};
var playerShadow = self.addChild(XS.getAsset('playerShadow', 'Player shadow', .5, .8));
playerShadow.alpha = 0.3;
self.addChild(XS.getAsset('player', 'Player character', .5, 1));
var healthBar = new HealthBar();
self.addChild(healthBar).y = -self.children[1].height;
self.healthBar = healthBar;
self.targetX = 2048 / 2;
self.targetY = 2732 / 2;
self.speed = 5;
self.lastShot = 0;
self.move = function (obstacles) {
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > self.speed) {
self.setPosition(self.x + dx / distance * self.speed, self.y + dy / distance * self.speed);
for (var i = 0; i < obstacles.length; i++) {
var dx = obstacles[i].x - self.x;
var dy = obstacles[i].y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < obstacles[i].width / 2) {
self.x -= dx / distance * 10;
self.y -= dy / distance * 10;
}
}
self.healthBar.updateHealth(self.health);
return true;
}
self.healthBar.updateHealth(self.health);
return false;
};
self.setTarget = function (x, y) {
self.targetX = x;
self.targetY = y;
};
self.shoot = function (enemies) {
var nearestEnemy = self.findNearestEnemy(enemies);
if (nearestEnemy) {
var bullet = new PlayerBullet();
bullet.x = self.x;
bullet.y = self.y;
var dx = nearestEnemy.x - self.x;
var dy = nearestEnemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
bullet.dx = dx / distance;
bullet.dy = dy / distance;
return bullet;
}
return null;
};
});
var Enemy = Container.expand(function () {
var self = Container.call(this);
self.throwProjectile = function (player) {
if (!self.parent.lineIntersectsObstacle(self.x, self.y, player.x, player.y)) {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var projectile = new EnemyBullet();
projectile.x = self.x;
projectile.y = self.y;
projectile.dx = dx / distance;
projectile.dy = dy / distance;
return projectile;
}
return null;
};
self.moveTowardsPlayer = function (player) {
if (!self.parent.lineIntersectsObstacle(self.x, self.y, player.x, player.y)) {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 800) {
self.dx += dx / distance * 0.3;
self.dy += dy / distance * 0.3;
}
}
};
;
self.alpha = 0;
self.lastProjectile = 0;
self.dx = 0;
self.dy = 0;
self.fadeRedTint = function () {
if (self.fadeOutRedTint > 0) {
enemyGraphics.tint = 0xff0000 + (0xffffff - 0xff0000) * (10 - self.fadeOutRedTint) / 10;
if (--self.fadeOutRedTint <= 0) {
enemyGraphics.tint = 0xFFFFFF;
}
}
};
self.health = 100;
self.animateIn = function () {
self.fadeInTicks = 50;
};
var enemyShadow = self.addChild(XS.getAsset('enemyShadow', 'Enemy shadow', .5, .8));
enemyShadow.alpha = 0.3;
var enemyGraphics = self.addChild(XS.getAsset('enemy', 'Enemy character', .5, 1));
var healthBar = new HealthBar();
healthBar.setTint(0xFF0000);
healthBar.y = -enemyGraphics.height;
self.addChild(healthBar);
self.healthBar = healthBar;
self.healthBar.updateHealth(self.health);
self.move = function (obstacles, player) {
self.fadeRedTint();
if (self.fadeInTicks > 0) {
self.alpha += 0.02;
self.fadeInTicks--;
} else {
self.moveTowardsPlayer(player);
}
self.setPosition(self.x + self.dx, self.y + self.dy);
self.dx *= 0.80;
self.dy *= 0.80;
if (self.x < 150 || self.x > 2048 - 150 || self.y < 700 || self.y > 2732 - 150) {
self.x = Math.max(Math.min(self.x, 2048 - 150), 150);
self.y = Math.max(Math.min(self.y, 2732 - 150), 700);
}
for (var i = 0; i < obstacles.length; i++) {
var dx = obstacles[i].x - self.x;
var dy = obstacles[i].y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < obstacles[i].width / 2) {
self.x -= dx / distance * 10;
self.y -= dy / distance * 10;
}
}
};
self.flashRed = function () {
self.children[0].tint = 0xFF0000;
self.fadeOutRedTint = 10;
};
});
var PlayerBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.addChild(XS.getAsset('bullet', 'Bullet', .5, .5));
bulletGraphics.y -= 150;
bulletGraphics.blendMode = 1;
self.dx = 0;
self.dy = 0;
self.move = function () {
self.dx *= 1.02;
self.dy *= 1.02;
self.setPosition(self.x + self.dx * 4, self.y + self.dy * 4);
if (self.x < 150 || self.x > 2048 - 150 || self.y < 700 || self.y > 2732 - 150) {
return true;
}
return false;
};
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.addChild(XS.getAsset('bullet', 'Bullet', .5, .5));
bulletGraphics.y -= 150;
bulletGraphics.blendMode = 1;
self.dx = 0;
self.dy = 0;
self.move = function () {
self.dx *= 1.02;
self.dy *= 1.02;
self.setPosition(self.x + self.dx * 4, self.y + self.dy * 4);
if (self.x < 150 || self.x > 2048 - 150 || self.y < 700 || self.y > 2732 - 150) {
return true;
}
return false;
};
});
var Background = Container.expand(function () {
var self = Container.call(this);
var backgroundGraphics = XS.getAsset('background', 'Background', .5, .5);
backgroundGraphics.x = 2048 / 2;
backgroundGraphics.y = 2732 / 2 + 300;
self.addChild(backgroundGraphics);
self.exitDoor = self.addChildAt(new ExitDoor(), 1);
self.exitDoor.x = 2048 / 2;
self.exitDoor.y = 2732 / 2 - 670 + 400;
self.exitDoor.visible = false;
});
var Game = Container.expand(function () {
var self = Container.call(this);
self.lineIntersectsObstacle = function (x1, y1, x2, y2) {
for (var i = 0; i < obstacles.length; i++) {
var dx = obstacles[i].x - x1;
var dy = obstacles[i].y - y1;
var distance = Math.sqrt(dx * dx + dy * dy);
var radius = obstacles[i].width * 0.7 / 2;
if (distance < radius) {
return true;
}
var t = ((x2 - x1) * (obstacles[i].x - x1) + (y2 - y1) * (obstacles[i].y - y1)) / (Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
t = Math.max(0, Math.min(1, t));
var nearestX = x1 + t * (x2 - x1);
var nearestY = y1 + t * (y2 - y1);
dx = obstacles[i].x - nearestX;
dy = obstacles[i].y - nearestY;
distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= radius) {
return true;
}
}
return false;
};
self.allEnemiesKilled = false;
self.setPlayerTarget = function (x, y) {
x = Math.max(Math.min(x, 2048 - 150), 150);
y = Math.max(Math.min(y, 2732 - 150), 700);
player.setTarget(x, y);
targetIndicator.setPosition(x, y);
targetIndicator.visible = true;
};
self.checkEnemies = function () {
if (!self.allEnemiesKilled && enemies.length === 0 && spawnIndicators.length === 0) {
background.exitDoor.visible = true;
self.allEnemiesKilled = true;
XS.effects.flashScreen(0xFFFFFF, 1000);
self.setPlayerTarget(background.exitDoor.x, background.exitDoor.y - 300);
}
};
self.rotateBackground = function () {
background.children[1].rotate();
};
self.particleMove = function () {
for (var i = particles.length - 1; i >= 0; i--) {
if (particles[i].alpha <= 0) {
particles[i].destroy();
particles.splice(i, 1);
} else {
particles[i].move();
}
}
};
self.bulletMove = function () {
for (var i = bullets.length - 1; i >= 0; i--) {
if (bullets[i] && bullets[i].move()) {
self.createExplosion(bullets[i].x, bullets[i].y);
bullets[i].destroy();
bullets.splice(i, 1);
} else {
bullets[i].move();
for (var j = 0; j < enemies.length; j++) {
if (bullets[i].intersects(enemies[j])) {
enemies[j].health -= 10;
enemies[j].healthBar.updateHealth(enemies[j].health);
enemies[j].flashRed();
if (enemies[j].health <= 0) {
enemies[j].destroy();
enemies.splice(j, 1);
} else {
var angle = Math.atan2(bullets[i].dy, bullets[i].dx);
enemies[j].x += Math.cos(angle) * 15;
enemies[j].y += Math.sin(angle) * 15;
enemies[j].dx = Math.cos(angle) * 10;
enemies[j].dy = Math.sin(angle) * 10;
}
self.createExplosion(bullets[i].x, bullets[i].y);
bullets[i].destroy();
bullets.splice(i, 1);
break;
}
}
}
}
};
self.enemyMove = function () {
for (var i = 0; i < enemies.length; i++) {
enemies[i].move(obstacles, player);
for (var j = i + 1; j < enemies.length; j++) {
var dx = enemies[j].x - enemies[i].x;
var dy = enemies[j].y - enemies[i].y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < enemies[i].width) {
enemies[i].x -= dx / distance;
enemies[i].y -= dy / distance;
enemies[j].x += dx / distance;
enemies[j].y += dy / distance;
}
}
}
};
self.playerMove = function (obstacles) {
player.move(obstacles);
var dx = player.targetX - player.x;
var dy = player.targetY - player.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < player.speed && XS.ticks - player.lastShot >= 60 && enemies.length > 0) {
player.lastShot = XS.ticks;
var bullet = player.shoot(enemies);
if (bullet) {
bullets.push(bullet);
self.addChild(bullet);
}
}
if (distance < player.speed) {
targetIndicator.visible = false;
if (self.allEnemiesKilled) {
self.spawnNextWave();
}
}
};
var spawnIndicators = [];
self.isTooClose = function (x, y) {
for (var i = 0; i < spawnIndicators.length; i++) {
var dx = spawnIndicators[i].x - x;
var dy = spawnIndicators[i].y - y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 200) {
return true;
}
}
return false;
};
self.spawnEnemies = function (count) {
for (var i = 0; i < count; i++) {
var x, y;
do {
x = Math.random() * (2048 - 300) + 150;
y = Math.random() * (2732 - 850) + 700;
} while (self.isTooClose(x, y) || self.lineIntersectsObstacle(x, y, x, y));
var spawnIndicator = self.addChild(new EnemySpawnIndicator());
spawnIndicator.setPosition(x, y);
spawnIndicators.push(spawnIndicator);
(function (spawnIndicator) {
XS.setTimeout(function () {
var enemy = self.addChild(new Enemy());
enemy.setPosition(spawnIndicator.x, spawnIndicator.y);
enemies.push(enemy);
spawnIndicator.destroy();
enemy.animateIn();
var index = spawnIndicators.indexOf(spawnIndicator);
if (index > -1) {
spawnIndicators.splice(index, 1);
}
}, 3000);
})(spawnIndicator);
}
};
self.createExplosion = function (x, y) {
for (var j = 0; j < 10; j++) {
var particle = new ExplosionParticle();
particle.setPosition(x, y);
particle.dx = (Math.random() - 0.5) * 10;
particle.dy = (Math.random() - 0.5) * 7;
self.addChild(particle);
particles.push(particle);
}
};
var particles = [];
self.sortGameObjects = function () {
self.children.sort(function (a, b) {
return a.y < b.y ? -1 : 1;
});
self.setChildIndex(targetIndicator, 1);
};
var background = self.addChild(new Background());
var player = self.addChild(new Player());
player.setPosition(2048 / 2, 2732 - player.height);
player.setTarget(player.x, player.y);
var targetIndicator = self.addChild(new TargetIndicator());
targetIndicator.setPosition(player.x, player.y);
var obstacles = [];
var enemies = [];
self.spawnEnemies(5);
var obstacleSpacing = 2048 / 3;
for (var i = 0; i < 2; i++) {
var obstacle = self.addChild(new Obstacle());
obstacle.setPosition(obstacleSpacing * (i + 1), 2732 / 2 + 500);
obstacles.push(obstacle);
}
var bullets = [];
XS.on('tick', function () {
self.playerMove(obstacles);
self.bulletMove();
self.enemyMove();
for (var i = 0; i < enemies.length; i++) {
if (XS.ticks - enemies[i].lastProjectile >= 60) {
enemies[i].lastProjectile = XS.ticks;
var projectile = enemies[i].throwProjectile(player);
if (projectile) {
bullets.push(projectile);
self.addChild(projectile);
}
}
}
self.particleMove();
self.rotateBackground();
self.sortGameObjects();
self.checkEnemies();
});
self.spawnNextWave = function () {
player.setPosition(2048 / 2, 2732 - player.height);
player.setTarget(player.x, player.y);
background.exitDoor.visible = false;
self.allEnemiesKilled = false;
self.spawnEnemies(5);
XS.effects.flashScreen(0x000000, 1000);
};
stage.on('down', function (obj) {
if (!self.allEnemiesKilled) {
var pos = obj.event.getLocalPosition(self);
self.setPlayerTarget(pos.x, pos.y);
}
});
});
===================================================================
--- original.js
+++ change.js
@@ -112,9 +112,9 @@
};
self.shoot = function (enemies) {
var nearestEnemy = self.findNearestEnemy(enemies);
if (nearestEnemy) {
- var bullet = new Bullet();
+ var bullet = new PlayerBullet();
bullet.x = self.x;
bullet.y = self.y;
var dx = nearestEnemy.x - self.x;
var dy = nearestEnemy.y - self.y;
@@ -132,9 +132,9 @@
if (!self.parent.lineIntersectsObstacle(self.x, self.y, player.x, player.y)) {
var dx = player.x - self.x;
var dy = player.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
- var projectile = new Bullet();
+ var projectile = new EnemyBullet();
projectile.x = self.x;
projectile.y = self.y;
projectile.dx = dx / distance;
projectile.dy = dy / distance;
@@ -208,11 +208,10 @@
self.children[0].tint = 0xFF0000;
self.fadeOutRedTint = 10;
};
});
-var Bullet = Container.expand(function (type) {
+var PlayerBullet = Container.expand(function () {
var self = Container.call(this);
- self.type = type;
var bulletGraphics = self.addChild(XS.getAsset('bullet', 'Bullet', .5, .5));
bulletGraphics.y -= 150;
bulletGraphics.blendMode = 1;
self.dx = 0;
@@ -226,8 +225,25 @@
}
return false;
};
});
+var EnemyBullet = Container.expand(function () {
+ var self = Container.call(this);
+ var bulletGraphics = self.addChild(XS.getAsset('bullet', 'Bullet', .5, .5));
+ bulletGraphics.y -= 150;
+ bulletGraphics.blendMode = 1;
+ self.dx = 0;
+ self.dy = 0;
+ self.move = function () {
+ self.dx *= 1.02;
+ self.dy *= 1.02;
+ self.setPosition(self.x + self.dx * 4, self.y + self.dy * 4);
+ if (self.x < 150 || self.x > 2048 - 150 || self.y < 700 || self.y > 2732 - 150) {
+ return true;
+ }
+ return false;
+ };
+});
var Background = Container.expand(function () {
var self = Container.call(this);
var backgroundGraphics = XS.getAsset('background', 'Background', .5, .5);
backgroundGraphics.x = 2048 / 2;
giant wall Pixel art, 16 bit, isometric, SNES, top-down, no background, white background, low resolution, symmetrical
Single Short round Isometric dungeon column, simple, few stones, single column, no floor, dark room, Single Game Texture. In-Game asset. 2d. Pixelart. White background. Blank background. Low detail. High contrast.
Multi color chaotic noise, primary colors Single Game Texture. In-Game asset. 2d. Pixelart. White background. Blank background. Low detail. High contrast.
Round purple magic fireball. White core Single Game Texture. In-Game asset. 2d. Pixelart. White background. Blank background. Low detail. High contrast.
enemy goblin , Pixel art, 16 bit, isometric, SNES, top-down, no background, white background, low resolution, symmetrical, seen from front. No staff.
Single fire particle Single Game Texture. In-Game asset. 2d. Pixelart. White background. Blank background. Low detail. High contrast.
https://i.imgur.com/R3ZLguO.jpg Dungeon, Empty open floor, dark, fullscreen, Single Game Texture. In-Game asset. 2d. Pixelart. White background. Blank background. high detail. High contrast. --ar 2:3
single wizard, hooded Pixel art, 16 bit, isometric, SNES, top-down, no background, white background, low resolution, symmetrical, seen from front.
round bomb. fuse on fire Single Game Texture. In-Game asset. 2d. Pixelart. White background. Blank background. Low detail. High contrast.
Multi color chaotic noise, primary colors. Rays from the center. Darker center Single Game Texture. In-Game asset. 2d. Pixelart. Low detail. High contrast.