/**** * Classes ****/ var EnemyBulletIndicator = Container.expand(function () { var self = Container.call(this); var indicatorGraphics = self.attachAsset('enemyBulletIndicator', { anchorX: 0.5, anchorY: 0.5 }); indicatorGraphics.alpha = 0.5; }); var Obstacle = Container.expand(function () { var self = Container.call(this); var obstacleGraphics = self.attachAsset('obstacle', { anchorX: 0.5, anchorY: 1 }); obstacleGraphics.y += 50; }); var ExitDoor = Container.expand(function () { var self = Container.call(this); var backgroundElement = self.attachAsset('backgroundElement1', { anchorX: 0.5, anchorY: 0.5 }); backgroundElement.y -= 760; var backgroundElement2 = self.attachAsset('backgroundElement2', { anchorX: 0.5, anchorY: 0.5 }); backgroundElement2.y -= 760; backgroundElement2.blendMode = 1; var doorGraphics = self.attachAsset('exitDoor', { anchorX: 0.5, anchorY: 1 }); self.rotate = function () { backgroundElement.rotation += 0.00125; backgroundElement2.rotation -= 0.00175; }; }); var EnemySpawnIndicator = Container.expand(function () { var self = Container.call(this); var spawnIndicatorGraphics = self.attachAsset('spawnIndicator', { anchorX: 0.5, anchorY: 0.5 }); spawnIndicatorGraphics.alpha = 0.5; }); var ExplosionParticle = Container.expand(function () { var self = Container.call(this); var particleGraphics = self.attachAsset('particle', { anchorX: 0.5, anchorY: 0.5 }); particleGraphics.blendMode = 1; 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 = self.attachAsset('healthBar', { anchorX: 0.5, anchorY: 1 }); 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 = self.attachAsset('target', { anchorX: 0.5, anchorY: 0.5 }); targetGraphics.alpha = 0.5; targetGraphics.y -= 30; }); 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.attachAsset('playerShadow', { anchorX: 0.5, anchorY: 0.8 }); playerShadow.alpha = 0.3; var playerAsset = self.attachAsset('player', { anchorX: 0.5, anchorY: 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.setPosition(self.x, 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; }; self.flashRed = function () { LK.effects.flashObject(playerAsset, 0xFF0000, 1000); }; }); 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.setPosition(self.x, self.y); projectile.originX = self.x; projectile.originY = self.y; projectile.targetX = player.x; projectile.targetY = player.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; return true; } } return false; }; ; self.alpha = 0; self.lastProjectile = 0; self.dx = 0; self.dy = 0; self.health = 100; self.animateIn = function () { self.fadeInTicks = 50; }; var enemyShadow = self.attachAsset('enemyShadow', { anchorX: 0.5, anchorY: 0.8 }); enemyShadow.alpha = 0.3; var enemyGraphics = self.attachAsset('enemy', { anchorX: 0.5, anchorY: 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) { var movedTowardsPlayer = true; if (self.fadeInTicks > 0) { self.alpha += 0.02; self.fadeInTicks--; } else { movedTowardsPlayer = 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; } } return movedTowardsPlayer; }; self.flashRed = function () { LK.effects.flashObject(enemyGraphics, 0xFF0000, 1000); }; }); var PlayerBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.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); return self.x < 150 || self.x > 2048 - 150 || self.y < 700 || self.y > 2732 - 150; }; }); var EnemyBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('enemyBullet', { anchorX: 0.5, anchorY: 0.5 }); bulletGraphics.y -= 150; self.dx = 0; self.dy = 0; self.originX = 0; self.originY = 0; self.move = function () { self.setPosition(self.x + self.dx * 4.2, self.y + self.dy * 4.2); bulletGraphics.rotation += 0.1; var dx = self.targetX - self.x; var dy = self.targetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); var totalDistance = Math.sqrt(Math.pow(self.targetX - self.originX, 2) + Math.pow(self.targetY - self.originY, 2)); var percentCompleted = distance / totalDistance; bulletGraphics.y = -150 * percentCompleted - 200 * Math.sin(Math.PI * percentCompleted); if (!self.indicator) { self.indicator = new EnemyBulletIndicator(); self.indicator.setPosition(self.targetX, self.targetY); self.parent.addChild(self.indicator); } var totalDistance = Math.sqrt(Math.pow(self.targetX - self.originX, 2) + Math.pow(self.targetY - self.originY, 2)); var percentCompleted = 1 - distance / totalDistance; self.indicator.scale.set(3 - 2 * percentCompleted, 3 - 2 * percentCompleted); self.indicator.alpha = percentCompleted; if (distance < 25 || self.x < 150 || self.x > 2048 - 150 || self.y < 700 || self.y > 2732 - 150) { self.indicator.destroy(); return true; } return false; }; }); var Background = Container.expand(function () { var self = Container.call(this); var backgroundGraphics = self.attachAsset('background', { anchorX: 0.5, anchorY: 0.5 }); backgroundGraphics.setPosition(2048 / 2, 2732 / 2 + 300); self.exitDoor = self.addChildAt(new ExitDoor(), 1); self.exitDoor.setPosition(2048 / 2, 2732 / 2 - 670 + 400); self.exitDoor.visible = false; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x343942 }); /**** * Game Code ****/ game.enemyBulletMove = function () { for (var i = enemyBullets.length - 1; i >= 0; i--) { if (enemyBullets[i] && enemyBullets[i].move()) { var dx = player.x - enemyBullets[i].x; var dy = player.y - enemyBullets[i].y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 225 && !game.allEnemiesKilled) { player.health -= 10; player.healthBar.updateHealth(player.health); player.flashRed(); if (player.health <= 0) { LK.showGameOver(); } } game.createExplosion(enemyBullets[i].x, enemyBullets[i].y); enemyBullets[i].destroy(); enemyBullets.splice(i, 1); } } }; game.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; }; game.allEnemiesKilled = false; game.waveCount = 2; game.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; }; game.checkEnemies = function () { if (!game.allEnemiesKilled && enemies.length === 0 && spawnIndicators.length === 0) { background.exitDoor.visible = true; game.allEnemiesKilled = true; LK.effects.flashScreen(0xFFFFFF, 1000); game.setPlayerTarget(background.exitDoor.x, background.exitDoor.y - 300); } }; game.rotateBackground = function () { background.children[1].rotate(); }; game.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(); } } }; game.bulletMove = function () { for (var i = bullets.length - 1; i >= 0; i--) { if (bullets[i] && bullets[i].move()) { game.createExplosion(bullets[i].x, bullets[i].y - 150); 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); score += 1; LK.setScore(score); scoreDisplay.setText(score.toString()); } 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; } game.createExplosion(bullets[i].x, bullets[i].y - 150); bullets[i].destroy(); bullets.splice(i, 1); break; } } } } }; game.enemyTick = function () { for (var i = 0; i < enemies.length; i++) { var moved = 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; } } if (!moved && LK.ticks - enemies[i].lastProjectile >= 180) { enemies[i].lastProjectile = LK.ticks; var projectile = enemies[i].throwProjectile(player); if (projectile) { enemyBullets.push(projectile); game.addChild(projectile); } } } }; game.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 && LK.ticks - player.lastShot >= 30 && enemies.length > 0) { player.lastShot = LK.ticks; var bullet = player.shoot(enemies); if (bullet) { bullets.push(bullet); game.addChild(bullet); } } if (distance < player.speed) { targetIndicator.visible = false; if (game.allEnemiesKilled) { game.spawnNextWave(); } } }; var spawnIndicators = []; game.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; }; game.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 (game.isTooClose(x, y) || game.lineIntersectsObstacle(x, y, x, y)); var spawnIndicator = game.addChild(new EnemySpawnIndicator()); spawnIndicator.setPosition(x, y); spawnIndicators.push(spawnIndicator); (function (spawnIndicator) { LK.setTimeout(function () { var enemy = game.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); } }, 2000); })(spawnIndicator); } }; game.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; game.addChild(particle); particles.push(particle); } }; var particles = []; game.sortGameObjects = function () { game.children.sort(function (a, b) { return a.y < b.y ? -1 : 1; }); for (var i = 0; i < game.children.length; i++) { if (game.children[i] instanceof EnemyBulletIndicator) { game.setChildIndex(game.children[i], 1); } } game.setChildIndex(targetIndicator, 1); }; var background = game.addChild(new Background()); var player = game.addChild(new Player()); player.setPosition(2048 / 2, 2732 - player.height); player.setTarget(player.x, player.y); var targetIndicator = game.addChild(new TargetIndicator()); targetIndicator.setPosition(player.x, player.y); var obstacles = []; var enemies = []; game.spawnEnemies(1); var obstacleSpacing = 2048 / 3; for (var i = 0; i < 2; i++) { for (var j = 0; j < 2; j++) { var obstacle = game.addChild(new Obstacle()); obstacle.setPosition(obstacleSpacing * (i + 1), 2732 / 2 + obstacleSpacing * j); obstacles.push(obstacle); } } var bullets = []; var enemyBullets = []; var score = 0; var scoreDisplay = new Text2(score.toString(), { size: 80, fill: '#ffffff', font: 'Impact', dropShadow: true, dropShadowColor: '#000000', dropShadowBlur: 4, dropShadowAngle: Math.PI / 6, dropShadowDistance: 6 }); scoreDisplay.anchor.set(0.5, 0); LK.gui.topCenter.addChild(scoreDisplay); var waveDisplay = new Text2('Wave: 1', { size: 40, fill: '#ffffff', font: 'Impact', dropShadow: true, dropShadowColor: '#000000', dropShadowBlur: 4, dropShadowAngle: Math.PI / 6, dropShadowDistance: 6 }); waveDisplay.anchor.set(0.5, 1); LK.gui.bottom.addChild(waveDisplay); LK.on('tick', function () { game.playerMove(obstacles); game.bulletMove(); game.enemyTick(); game.enemyBulletMove(); game.particleMove(); game.rotateBackground(); game.sortGameObjects(); game.checkEnemies(); }); game.spawnNextWave = function () { player.setPosition(2048 / 2, 2732 - player.height); player.setTarget(player.x, player.y); background.exitDoor.visible = false; game.allEnemiesKilled = false; waveDisplay.setText('Wave: ' + game.waveCount); game.spawnEnemies(game.waveCount++); LK.effects.flashScreen(0x000000, 2000); for (var i = enemyBullets.length - 1; i >= 0; i--) { if (enemyBullets[i].indicator) { enemyBullets[i].indicator.destroy(); } enemyBullets[i].destroy(); enemyBullets.splice(i, 1); } }; game.on('down', function (obj) { if (!game.allEnemiesKilled) { var pos = obj.event.getLocalPosition(game); game.setPlayerTarget(pos.x, pos.y); } });
/****
* Classes
****/
var EnemyBulletIndicator = Container.expand(function () {
var self = Container.call(this);
var indicatorGraphics = self.attachAsset('enemyBulletIndicator', {
anchorX: 0.5,
anchorY: 0.5
});
indicatorGraphics.alpha = 0.5;
});
var Obstacle = Container.expand(function () {
var self = Container.call(this);
var obstacleGraphics = self.attachAsset('obstacle', {
anchorX: 0.5,
anchorY: 1
});
obstacleGraphics.y += 50;
});
var ExitDoor = Container.expand(function () {
var self = Container.call(this);
var backgroundElement = self.attachAsset('backgroundElement1', {
anchorX: 0.5,
anchorY: 0.5
});
backgroundElement.y -= 760;
var backgroundElement2 = self.attachAsset('backgroundElement2', {
anchorX: 0.5,
anchorY: 0.5
});
backgroundElement2.y -= 760;
backgroundElement2.blendMode = 1;
var doorGraphics = self.attachAsset('exitDoor', {
anchorX: 0.5,
anchorY: 1
});
self.rotate = function () {
backgroundElement.rotation += 0.00125;
backgroundElement2.rotation -= 0.00175;
};
});
var EnemySpawnIndicator = Container.expand(function () {
var self = Container.call(this);
var spawnIndicatorGraphics = self.attachAsset('spawnIndicator', {
anchorX: 0.5,
anchorY: 0.5
});
spawnIndicatorGraphics.alpha = 0.5;
});
var ExplosionParticle = Container.expand(function () {
var self = Container.call(this);
var particleGraphics = self.attachAsset('particle', {
anchorX: 0.5,
anchorY: 0.5
});
particleGraphics.blendMode = 1;
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 = self.attachAsset('healthBar', {
anchorX: 0.5,
anchorY: 1
});
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 = self.attachAsset('target', {
anchorX: 0.5,
anchorY: 0.5
});
targetGraphics.alpha = 0.5;
targetGraphics.y -= 30;
});
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.attachAsset('playerShadow', {
anchorX: 0.5,
anchorY: 0.8
});
playerShadow.alpha = 0.3;
var playerAsset = self.attachAsset('player', {
anchorX: 0.5,
anchorY: 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.setPosition(self.x, 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;
};
self.flashRed = function () {
LK.effects.flashObject(playerAsset, 0xFF0000, 1000);
};
});
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.setPosition(self.x, self.y);
projectile.originX = self.x;
projectile.originY = self.y;
projectile.targetX = player.x;
projectile.targetY = player.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;
return true;
}
}
return false;
};
;
self.alpha = 0;
self.lastProjectile = 0;
self.dx = 0;
self.dy = 0;
self.health = 100;
self.animateIn = function () {
self.fadeInTicks = 50;
};
var enemyShadow = self.attachAsset('enemyShadow', {
anchorX: 0.5,
anchorY: 0.8
});
enemyShadow.alpha = 0.3;
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 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) {
var movedTowardsPlayer = true;
if (self.fadeInTicks > 0) {
self.alpha += 0.02;
self.fadeInTicks--;
} else {
movedTowardsPlayer = 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;
}
}
return movedTowardsPlayer;
};
self.flashRed = function () {
LK.effects.flashObject(enemyGraphics, 0xFF0000, 1000);
};
});
var PlayerBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.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);
return self.x < 150 || self.x > 2048 - 150 || self.y < 700 || self.y > 2732 - 150;
};
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('enemyBullet', {
anchorX: 0.5,
anchorY: 0.5
});
bulletGraphics.y -= 150;
self.dx = 0;
self.dy = 0;
self.originX = 0;
self.originY = 0;
self.move = function () {
self.setPosition(self.x + self.dx * 4.2, self.y + self.dy * 4.2);
bulletGraphics.rotation += 0.1;
var dx = self.targetX - self.x;
var dy = self.targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var totalDistance = Math.sqrt(Math.pow(self.targetX - self.originX, 2) + Math.pow(self.targetY - self.originY, 2));
var percentCompleted = distance / totalDistance;
bulletGraphics.y = -150 * percentCompleted - 200 * Math.sin(Math.PI * percentCompleted);
if (!self.indicator) {
self.indicator = new EnemyBulletIndicator();
self.indicator.setPosition(self.targetX, self.targetY);
self.parent.addChild(self.indicator);
}
var totalDistance = Math.sqrt(Math.pow(self.targetX - self.originX, 2) + Math.pow(self.targetY - self.originY, 2));
var percentCompleted = 1 - distance / totalDistance;
self.indicator.scale.set(3 - 2 * percentCompleted, 3 - 2 * percentCompleted);
self.indicator.alpha = percentCompleted;
if (distance < 25 || self.x < 150 || self.x > 2048 - 150 || self.y < 700 || self.y > 2732 - 150) {
self.indicator.destroy();
return true;
}
return false;
};
});
var Background = Container.expand(function () {
var self = Container.call(this);
var backgroundGraphics = self.attachAsset('background', {
anchorX: 0.5,
anchorY: 0.5
});
backgroundGraphics.setPosition(2048 / 2, 2732 / 2 + 300);
self.exitDoor = self.addChildAt(new ExitDoor(), 1);
self.exitDoor.setPosition(2048 / 2, 2732 / 2 - 670 + 400);
self.exitDoor.visible = false;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x343942
});
/****
* Game Code
****/
game.enemyBulletMove = function () {
for (var i = enemyBullets.length - 1; i >= 0; i--) {
if (enemyBullets[i] && enemyBullets[i].move()) {
var dx = player.x - enemyBullets[i].x;
var dy = player.y - enemyBullets[i].y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 225 && !game.allEnemiesKilled) {
player.health -= 10;
player.healthBar.updateHealth(player.health);
player.flashRed();
if (player.health <= 0) {
LK.showGameOver();
}
}
game.createExplosion(enemyBullets[i].x, enemyBullets[i].y);
enemyBullets[i].destroy();
enemyBullets.splice(i, 1);
}
}
};
game.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;
};
game.allEnemiesKilled = false;
game.waveCount = 2;
game.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;
};
game.checkEnemies = function () {
if (!game.allEnemiesKilled && enemies.length === 0 && spawnIndicators.length === 0) {
background.exitDoor.visible = true;
game.allEnemiesKilled = true;
LK.effects.flashScreen(0xFFFFFF, 1000);
game.setPlayerTarget(background.exitDoor.x, background.exitDoor.y - 300);
}
};
game.rotateBackground = function () {
background.children[1].rotate();
};
game.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();
}
}
};
game.bulletMove = function () {
for (var i = bullets.length - 1; i >= 0; i--) {
if (bullets[i] && bullets[i].move()) {
game.createExplosion(bullets[i].x, bullets[i].y - 150);
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);
score += 1;
LK.setScore(score);
scoreDisplay.setText(score.toString());
} 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;
}
game.createExplosion(bullets[i].x, bullets[i].y - 150);
bullets[i].destroy();
bullets.splice(i, 1);
break;
}
}
}
}
};
game.enemyTick = function () {
for (var i = 0; i < enemies.length; i++) {
var moved = 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;
}
}
if (!moved && LK.ticks - enemies[i].lastProjectile >= 180) {
enemies[i].lastProjectile = LK.ticks;
var projectile = enemies[i].throwProjectile(player);
if (projectile) {
enemyBullets.push(projectile);
game.addChild(projectile);
}
}
}
};
game.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 && LK.ticks - player.lastShot >= 30 && enemies.length > 0) {
player.lastShot = LK.ticks;
var bullet = player.shoot(enemies);
if (bullet) {
bullets.push(bullet);
game.addChild(bullet);
}
}
if (distance < player.speed) {
targetIndicator.visible = false;
if (game.allEnemiesKilled) {
game.spawnNextWave();
}
}
};
var spawnIndicators = [];
game.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;
};
game.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 (game.isTooClose(x, y) || game.lineIntersectsObstacle(x, y, x, y));
var spawnIndicator = game.addChild(new EnemySpawnIndicator());
spawnIndicator.setPosition(x, y);
spawnIndicators.push(spawnIndicator);
(function (spawnIndicator) {
LK.setTimeout(function () {
var enemy = game.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);
}
}, 2000);
})(spawnIndicator);
}
};
game.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;
game.addChild(particle);
particles.push(particle);
}
};
var particles = [];
game.sortGameObjects = function () {
game.children.sort(function (a, b) {
return a.y < b.y ? -1 : 1;
});
for (var i = 0; i < game.children.length; i++) {
if (game.children[i] instanceof EnemyBulletIndicator) {
game.setChildIndex(game.children[i], 1);
}
}
game.setChildIndex(targetIndicator, 1);
};
var background = game.addChild(new Background());
var player = game.addChild(new Player());
player.setPosition(2048 / 2, 2732 - player.height);
player.setTarget(player.x, player.y);
var targetIndicator = game.addChild(new TargetIndicator());
targetIndicator.setPosition(player.x, player.y);
var obstacles = [];
var enemies = [];
game.spawnEnemies(1);
var obstacleSpacing = 2048 / 3;
for (var i = 0; i < 2; i++) {
for (var j = 0; j < 2; j++) {
var obstacle = game.addChild(new Obstacle());
obstacle.setPosition(obstacleSpacing * (i + 1), 2732 / 2 + obstacleSpacing * j);
obstacles.push(obstacle);
}
}
var bullets = [];
var enemyBullets = [];
var score = 0;
var scoreDisplay = new Text2(score.toString(), {
size: 80,
fill: '#ffffff',
font: 'Impact',
dropShadow: true,
dropShadowColor: '#000000',
dropShadowBlur: 4,
dropShadowAngle: Math.PI / 6,
dropShadowDistance: 6
});
scoreDisplay.anchor.set(0.5, 0);
LK.gui.topCenter.addChild(scoreDisplay);
var waveDisplay = new Text2('Wave: 1', {
size: 40,
fill: '#ffffff',
font: 'Impact',
dropShadow: true,
dropShadowColor: '#000000',
dropShadowBlur: 4,
dropShadowAngle: Math.PI / 6,
dropShadowDistance: 6
});
waveDisplay.anchor.set(0.5, 1);
LK.gui.bottom.addChild(waveDisplay);
LK.on('tick', function () {
game.playerMove(obstacles);
game.bulletMove();
game.enemyTick();
game.enemyBulletMove();
game.particleMove();
game.rotateBackground();
game.sortGameObjects();
game.checkEnemies();
});
game.spawnNextWave = function () {
player.setPosition(2048 / 2, 2732 - player.height);
player.setTarget(player.x, player.y);
background.exitDoor.visible = false;
game.allEnemiesKilled = false;
waveDisplay.setText('Wave: ' + game.waveCount);
game.spawnEnemies(game.waveCount++);
LK.effects.flashScreen(0x000000, 2000);
for (var i = enemyBullets.length - 1; i >= 0; i--) {
if (enemyBullets[i].indicator) {
enemyBullets[i].indicator.destroy();
}
enemyBullets[i].destroy();
enemyBullets.splice(i, 1);
}
};
game.on('down', function (obj) {
if (!game.allEnemiesKilled) {
var pos = obj.event.getLocalPosition(game);
game.setPlayerTarget(pos.x, pos.y);
}
});
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.