User prompt
Only attach bullet to stage and array if bullet is defined
User prompt
Fix Bug: 'TypeError: null is not an object (evaluating 'bullets[i].move')' in this line: 'if (bullets[i].move()) {' Line Number: 275
User prompt
do not create a new bullet if nearestEnemy is false
User prompt
Fix Bug: 'ReferenceError: Can't find variable: obstacles' in this line: 'for (var i = 0; i < obstacles.length; i++) {' Line Number: 232
User prompt
When finding nearest enemy, draw a line between the hero and the enemy. If an obstacle is in the path. Don't allow the hero to see the enemy
User prompt
Only spawn one enemy
User prompt
Do not fire bullets unless there are enemies to shoot at
User prompt
Define dx and dy for explosion particles and bullets
User prompt
In the z sort function after sorting, attach the target indicator at 1
User prompt
Remove the special code for background and target selector in the z sort function
User prompt
Move down the column graphics inside the column class by 50px
User prompt
Rewrite the sort method such that it returns -1 or 1
User prompt
Move the columns down by 500px
User prompt
Make the obstacles y position be at the center of the screen, and then space them equally on the x axis
User prompt
Only spawn two obstacles
User prompt
Make the obstacles asset have anchor point .5,1
User prompt
Add a new obstacle class to the game. Add 3 random obstacles to the scene
User prompt
Increase enemy hp to 100
User prompt
Move down the asset in background by 100px
User prompt
Give enemies 1 hp
User prompt
Move down the asset in background by 100px
User prompt
Move down the asset in background by 100px
User prompt
Decrease immediate knock back effect from 25 to 15 but increase momentum from 5 to 10
User prompt
Further increase the friction of the enemies
User prompt
Further increase the friction of the enemies
var Obstacle = Container.expand(function () { var self = Container.call(this); var obstacleGraphics = XS.getAsset('obstacle', 'Obstacle', .5, 1); obstacleGraphics.y += 50; self.addChild(obstacleGraphics); }); var OverlayElement = Container.expand(function () { var self = Container.call(this); var overlayGraphics = XS.getAsset('overlay', 'Overlay Element', .5, 1); self.addChild(overlayGraphics); self.alpha = 0; self.flashed = false; self.flash = function (color, duration) { overlayGraphics.tint = color; self.alpha = 1; var fadeOutInterval = XS.setInterval(function () { self.alpha -= 0.02; if (self.alpha <= 0) { XS.clearInterval(fadeOutInterval); } }, duration / 50); }; }); var ExitDoor = Container.expand(function () { var self = Container.call(this); var backgroundElement = XS.getAsset('backgroundElement1', 'Background Element 1', .5, .5); backgroundElement.y -= 760; self.addChild(backgroundElement); var backgroundElement2 = XS.getAsset('backgroundElement2', 'Background Element 2', .5, .5); backgroundElement2.y -= 760; backgroundElement2.blendMode = 1; self.addChild(backgroundElement2); var doorGraphics = XS.getAsset('exitDoor', 'Exit Door', .5, 1); self.addChild(doorGraphics); 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 = XS.getAsset('spawnIndicator', 'Enemy Spawn Indicator', .5, .5); spawnIndicatorGraphics.alpha = 0.5; self.addChild(spawnIndicatorGraphics); }); var ExplosionParticle = Container.expand(function () { var self = Container.call(this); var particleGraphics = XS.getAsset('particle', 'Explosion particle', .5, .5); particleGraphics.scale.set(Math.random() * .5 + .5); particleGraphics.y -= 150; particleGraphics.blendMode = 3; self.addChild(particleGraphics); self.dx = (Math.random() - 0.5) * 10; self.dy = (Math.random() - 0.5) * 7; self.move = function () { self.x += self.dx; self.y += self.dy; self.alpha -= 0.02; 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.x = health / 100; }; }); 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 = XS.getAsset('playerShadow', 'Player shadow', .5, .8); playerShadow.alpha = 0.3; self.addChild(playerShadow); var playerGraphics = XS.getAsset('player', 'Player character', .5, 1); self.addChild(playerGraphics); var healthBar = new HealthBar(); healthBar.y = -playerGraphics.height; self.addChild(healthBar); self.healthBar = healthBar; self.targetX = 2048 / 2; self.targetY = 2732 / 2; self.speed = 5; self.lastShot = 0; self.move = function () { 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.x += dx / distance * self.speed; self.y += dy / distance * self.speed; 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 bullet = new Bullet(); bullet.x = self.x; bullet.y = self.y; var nearestEnemy = self.findNearestEnemy(enemies); if (nearestEnemy) { 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; }; }); var Enemy = Container.expand(function () { var self = Container.call(this); self.alpha = 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 = XS.getAsset('enemyShadow', 'Enemy shadow', .5, .8); enemyShadow.alpha = 0.3; self.addChild(enemyShadow); var enemyGraphics = XS.getAsset('enemy', 'Enemy character', .5, 1); self.addChild(enemyGraphics); 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 () { self.fadeRedTint(); if (self.fadeInTicks > 0) { self.alpha += 0.02; self.fadeInTicks--; } 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); } }; self.flashRed = function () { self.children[0].tint = 0xFF0000; self.fadeOutRedTint = 10; }; }); var Bullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = XS.getAsset('bullet', 'Bullet', .5, .5); bulletGraphics.y -= 150; bulletGraphics.blendMode = 1; self.addChild(bulletGraphics); self.dx = 0; self.dy = 0; self.move = function () { self.dx *= 1.02; self.dy *= 1.02; 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); if (distance < obstacles[i].width / 2) { 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.x = x; targetIndicator.y = y; targetIndicator.visible = true; }; self.checkEnemies = function () { if (!self.allEnemiesKilled && enemies.length === 0 && spawnIndicators.length === 0) { background.exitDoor.visible = true; self.allEnemiesKilled = true; overlay.flash(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].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(); } }; self.playerMove = function () { player.move(0, 0); 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); 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)); var spawnIndicator = self.addChild(new EnemySpawnIndicator()); spawnIndicator.x = x; spawnIndicator.y = y; spawnIndicators.push(spawnIndicator); (function (spawnIndicator) { XS.setTimeout(function () { var enemy = self.addChild(new Enemy()); enemy.x = spawnIndicator.x; enemy.y = 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.x = x; particle.y = 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 overlay = self.addChild(new OverlayElement()); overlay.x = 2048 / 2; overlay.y = 2732; var targetIndicator = new TargetIndicator(); var player = self.addChild(new Player()); player.x = 2048 / 2; player.y = 2732 - player.height; player.setTarget(player.x, player.y); targetIndicator.x = player.x; targetIndicator.y = player.y; self.addChild(targetIndicator); var enemies = []; self.spawnEnemies(1); var obstacleSpacing = 2048 / 3; for (var i = 0; i < 2; i++) { var obstacle = new Obstacle(); obstacle.x = obstacleSpacing * (i + 1); obstacle.y = 2732 / 2 + 500; self.addChild(obstacle); } var bullets = []; XS.on('tick', function () { self.playerMove(); self.bulletMove(); self.enemyMove(); self.particleMove(); self.rotateBackground(); self.sortGameObjects(); self.checkEnemies(); }); self.spawnNextWave = function () { player.x = 2048 / 2; player.y = 2732 - player.height; player.setTarget(player.x, player.y); background.exitDoor.visible = false; self.allEnemiesKilled = false; self.spawnEnemies(5); overlay.flash(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
@@ -95,9 +95,9 @@
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) {
+ if (distance < nearestDistance && !self.parent.lineIntersectsObstacle(self.x, self.y, enemies[i].x, enemies[i].y)) {
nearestDistance = distance;
nearestEnemy = enemies[i];
}
}
@@ -227,8 +227,19 @@
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);
+ if (distance < obstacles[i].width / 2) {
+ 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);
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.