/****
* Classes
****/
var Arrow = Container.expand(function (target) {
var self = Container.call(this);
var arrowGraphics = self.attachAsset('arrow', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 18;
self.angle = 0;
self.target = target;
self.lastX = self.x;
self.lastY = self.y;
self._move_migrated = function () {
// Move in the direction of angle
self.lastX = self.x;
self.lastY = self.y;
self.x += self.speed * Math.cos(self.angle);
self.y += self.speed * Math.sin(self.angle);
self.rotation = self.angle;
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 20;
self._move_migrated = function () {
self.x += self.speed * Math.cos(self.angle);
self.y += self.speed * Math.sin(self.angle);
self.rotation += 0.1;
};
});
var Enemy = Container.expand(function (hero) {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 2; // Enemy needs 2 hits to die
self._move_migrated = function () {
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
self.x += dx / distance * 1.8;
self.y += dy / distance * 1.8;
};
});
var Enemy2 = Container.expand(function (hero) {
var self = Container.call(this);
var enemy2Graphics = self.attachAsset('enemy2', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 3; // Enemy2 needs 3 hits to die
self._move_migrated = function () {
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
self.x += dx / distance * 1.25;
self.y += dy / distance * 1.25;
};
});
var Enemy3 = Container.expand(function (hero) {
var self = Container.call(this);
var enemy3Graphics = self.attachAsset('enemy3', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 4; // Enemy3 needs 4 hits to die
self.arrowCooldown = 0;
self._move_migrated = function () {
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
self.x += dx / distance * 2.5;
self.y += dy / distance * 2.5;
// Arrow attack logic
if (distance > 400) {
// Only shoot if at a distance
if (self.arrowCooldown <= 0) {
var arrow = new Arrow(hero);
arrow.x = self.x;
arrow.y = self.y;
arrow.angle = Math.atan2(hero.y - self.y, hero.x - self.x);
enemyBullets.push(arrow);
game.addChild(arrow);
self.arrowCooldown = 60 + Math.floor(Math.random() * 60); // 1-2 seconds between shots
}
}
if (self.arrowCooldown > 0) {
self.arrowCooldown--;
}
};
});
var Hero = Container.expand(function () {
var self = Container.call(this);
var heroGraphics = self.attachAsset('hero', {
anchorX: 0.5,
anchorY: 0.5
});
self._move_migrated = function () {
if (self.targetPos) {
var dx = self.targetPos.x - self.x;
var dy = self.targetPos.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * 10;
self.y += dy / distance * 10;
} else {
self.x = self.targetPos.x;
self.y = self.targetPos.y;
self.targetPos = null;
}
}
};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// You should replace id with a unique asset for enemy2
game.setBackgroundColor(0x008000);
var hero = game.addChild(new Hero());
hero.enemies = [];
var heroBullets = [];
var enemyBullets = [];
hero.x = 2048 / 2;
hero.y = 2732 / 2;
game.targetPos = null;
game.on('down', function (x, y, obj) {
hero.targetPos = game.toLocal(obj.global);
});
var spawnEnemy = function spawnEnemy() {
var side = Math.floor(Math.random() * 4);
var enemy;
var rand = Math.random();
if (rand < 0.4) {
enemy = new Enemy(hero);
} else if (rand < 0.8) {
enemy = new Enemy2(hero);
} else {
enemy = new Enemy3(hero);
}
switch (side) {
case 0:
enemy.x = Math.random() * 2048;
enemy.y = 0;
break;
case 1:
enemy.x = 2048;
enemy.y = Math.random() * 2732;
break;
case 2:
enemy.x = Math.random() * 2048;
enemy.y = 2732;
break;
case 3:
enemy.x = 0;
enemy.y = Math.random() * 2732;
break;
}
hero.enemies.push(enemy);
game.addChild(enemy);
};
LK.on('tick', function () {
hero._move_migrated();
for (var i = 0; i < heroBullets.length; i++) {
heroBullets[i]._move_migrated();
}
for (var i = 0; i < enemyBullets.length; i++) {
enemyBullets[i]._move_migrated();
}
// Track arrow hits on hero
if (typeof hero.arrowHits === "undefined") {
hero.arrowHits = 0;
}
for (var i = enemyBullets.length - 1; i >= 0; i--) {
if (enemyBullets[i].intersects(hero)) {
enemyBullets[i].destroy();
enemyBullets.splice(i, 1);
hero.arrowHits++;
if (hero.arrowHits >= 10) {
LK.showGameOver();
}
}
}
// Track Enemy2 kills for arrow reset
if (typeof hero.enemy2Kills === "undefined") {
hero.enemy2Kills = 0;
}
// Track total kills for bullet upgrades
if (typeof hero.totalKills === "undefined") {
hero.totalKills = 0;
}
for (var i = 0; i < hero.enemies.length; i++) {
hero.enemies[i]._move_migrated();
for (var j = 0; j < heroBullets.length; j++) {
if (heroBullets[j].intersects(hero.enemies[i])) {
heroBullets[j].destroy();
heroBullets.splice(j, 1);
if (typeof hero.enemies[i].health === "number") {
hero.enemies[i].health--;
if (hero.enemies[i].health <= 0) {
// Check if this is an Enemy2
if (hero.enemies[i].attachAsset && hero.enemies[i].attachAsset.toString().indexOf("enemy2") !== -1) {
hero.enemy2Kills++;
if (hero.enemy2Kills >= 3) {
hero.arrowHits = 0;
hero.enemy2Kills = 0;
}
}
hero.totalKills++; // Increment total kills
hero.enemies[i].destroy();
hero.enemies.splice(i, 1);
i--;
j--;
break;
}
} else {
// fallback: destroy if no health property
hero.enemies[i].destroy();
hero.enemies.splice(i, 1);
i--;
j--;
break;
}
}
}
if (hero.intersects(hero.enemies[i])) {
LK.showGameOver();
}
}
if (LK.ticks % 30 === 0) {
spawnEnemy();
}
if (LK.ticks % 20 === 0 && hero.enemies.length > 0) {
// Find the closest enemy
var closestEnemy = null;
var minDist = Infinity;
for (var i = 0; i < hero.enemies.length; i++) {
var dx = hero.enemies[i].x - hero.x;
var dy = hero.enemies[i].y - hero.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < minDist) {
minDist = dist;
closestEnemy = hero.enemies[i];
}
}
if (closestEnemy) {
// Always fire the main bullet
var bullet = new Bullet();
bullet.x = hero.x;
bullet.y = hero.y;
var dx = closestEnemy.x - hero.x;
var dy = closestEnemy.y - hero.y;
bullet.angle = Math.atan2(dy, dx);
heroBullets.push(bullet);
game.addChild(bullet);
// After 5 kills, fire a second bullet with a slight delay
if (hero.totalKills >= 5) {
LK.setTimeout(function () {
if (!hero || !closestEnemy) return;
var bullet2 = new Bullet();
bullet2.x = hero.x;
bullet2.y = hero.y;
var dx2 = closestEnemy.x - hero.x;
var dy2 = closestEnemy.y - hero.y;
bullet2.angle = Math.atan2(dy2, dx2);
heroBullets.push(bullet2);
game.addChild(bullet2);
}, 120); // ~2 frames later
}
// After 25 kills, fire a third bullet in the opposite direction
if (hero.totalKills >= 25) {
var bullet3 = new Bullet();
bullet3.x = hero.x;
bullet3.y = hero.y;
// Opposite direction
bullet3.angle = Math.atan2(dy, dx) + Math.PI;
heroBullets.push(bullet3);
game.addChild(bullet3);
}
}
}
}); /****
* Classes
****/
var Arrow = Container.expand(function (target) {
var self = Container.call(this);
var arrowGraphics = self.attachAsset('arrow', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 18;
self.angle = 0;
self.target = target;
self.lastX = self.x;
self.lastY = self.y;
self._move_migrated = function () {
// Move in the direction of angle
self.lastX = self.x;
self.lastY = self.y;
self.x += self.speed * Math.cos(self.angle);
self.y += self.speed * Math.sin(self.angle);
self.rotation = self.angle;
};
return self;
});
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 20;
self._move_migrated = function () {
self.x += self.speed * Math.cos(self.angle);
self.y += self.speed * Math.sin(self.angle);
self.rotation += 0.1;
};
});
var Enemy = Container.expand(function (hero) {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 2; // Enemy needs 2 hits to die
self._move_migrated = function () {
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
self.x += dx / distance * 1.8;
self.y += dy / distance * 1.8;
};
});
var Enemy2 = Container.expand(function (hero) {
var self = Container.call(this);
var enemy2Graphics = self.attachAsset('enemy2', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 3; // Enemy2 needs 3 hits to die
self._move_migrated = function () {
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
self.x += dx / distance * 1.25;
self.y += dy / distance * 1.25;
};
});
var Enemy3 = Container.expand(function (hero) {
var self = Container.call(this);
var enemy3Graphics = self.attachAsset('enemy3', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 4; // Enemy3 needs 4 hits to die
self.arrowCooldown = 0;
self._move_migrated = function () {
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
self.x += dx / distance * 2.5;
self.y += dy / distance * 2.5;
// Arrow attack logic
if (distance > 400) {
// Only shoot if at a distance
if (self.arrowCooldown <= 0) {
var arrow = new Arrow(hero);
arrow.x = self.x;
arrow.y = self.y;
arrow.angle = Math.atan2(hero.y - self.y, hero.x - self.x);
enemyBullets.push(arrow);
game.addChild(arrow);
self.arrowCooldown = 60 + Math.floor(Math.random() * 60); // 1-2 seconds between shots
}
}
if (self.arrowCooldown > 0) {
self.arrowCooldown--;
}
};
});
var Hero = Container.expand(function () {
var self = Container.call(this);
var heroGraphics = self.attachAsset('hero', {
anchorX: 0.5,
anchorY: 0.5
});
self._move_migrated = function () {
if (self.targetPos) {
var dx = self.targetPos.x - self.x;
var dy = self.targetPos.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 5) {
self.x += dx / distance * 10;
self.y += dy / distance * 10;
} else {
self.x = self.targetPos.x;
self.y = self.targetPos.y;
self.targetPos = null;
}
}
};
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// You should replace id with a unique asset for enemy2
game.setBackgroundColor(0x008000);
var hero = game.addChild(new Hero());
hero.enemies = [];
var heroBullets = [];
var enemyBullets = [];
hero.x = 2048 / 2;
hero.y = 2732 / 2;
game.targetPos = null;
game.on('down', function (x, y, obj) {
hero.targetPos = game.toLocal(obj.global);
});
var spawnEnemy = function spawnEnemy() {
var side = Math.floor(Math.random() * 4);
var enemy;
var rand = Math.random();
if (rand < 0.4) {
enemy = new Enemy(hero);
} else if (rand < 0.8) {
enemy = new Enemy2(hero);
} else {
enemy = new Enemy3(hero);
}
switch (side) {
case 0:
enemy.x = Math.random() * 2048;
enemy.y = 0;
break;
case 1:
enemy.x = 2048;
enemy.y = Math.random() * 2732;
break;
case 2:
enemy.x = Math.random() * 2048;
enemy.y = 2732;
break;
case 3:
enemy.x = 0;
enemy.y = Math.random() * 2732;
break;
}
hero.enemies.push(enemy);
game.addChild(enemy);
};
LK.on('tick', function () {
hero._move_migrated();
for (var i = 0; i < heroBullets.length; i++) {
heroBullets[i]._move_migrated();
}
for (var i = 0; i < enemyBullets.length; i++) {
enemyBullets[i]._move_migrated();
}
// Track arrow hits on hero
if (typeof hero.arrowHits === "undefined") {
hero.arrowHits = 0;
}
for (var i = enemyBullets.length - 1; i >= 0; i--) {
if (enemyBullets[i].intersects(hero)) {
enemyBullets[i].destroy();
enemyBullets.splice(i, 1);
hero.arrowHits++;
if (hero.arrowHits >= 10) {
LK.showGameOver();
}
}
}
// Track Enemy2 kills for arrow reset
if (typeof hero.enemy2Kills === "undefined") {
hero.enemy2Kills = 0;
}
// Track total kills for bullet upgrades
if (typeof hero.totalKills === "undefined") {
hero.totalKills = 0;
}
for (var i = 0; i < hero.enemies.length; i++) {
hero.enemies[i]._move_migrated();
for (var j = 0; j < heroBullets.length; j++) {
if (heroBullets[j].intersects(hero.enemies[i])) {
heroBullets[j].destroy();
heroBullets.splice(j, 1);
if (typeof hero.enemies[i].health === "number") {
hero.enemies[i].health--;
if (hero.enemies[i].health <= 0) {
// Check if this is an Enemy2
if (hero.enemies[i].attachAsset && hero.enemies[i].attachAsset.toString().indexOf("enemy2") !== -1) {
hero.enemy2Kills++;
if (hero.enemy2Kills >= 3) {
hero.arrowHits = 0;
hero.enemy2Kills = 0;
}
}
hero.totalKills++; // Increment total kills
hero.enemies[i].destroy();
hero.enemies.splice(i, 1);
i--;
j--;
break;
}
} else {
// fallback: destroy if no health property
hero.enemies[i].destroy();
hero.enemies.splice(i, 1);
i--;
j--;
break;
}
}
}
if (hero.intersects(hero.enemies[i])) {
LK.showGameOver();
}
}
if (LK.ticks % 30 === 0) {
spawnEnemy();
}
if (LK.ticks % 20 === 0 && hero.enemies.length > 0) {
// Find the closest enemy
var closestEnemy = null;
var minDist = Infinity;
for (var i = 0; i < hero.enemies.length; i++) {
var dx = hero.enemies[i].x - hero.x;
var dy = hero.enemies[i].y - hero.y;
var dist = Math.sqrt(dx * dx + dy * dy);
if (dist < minDist) {
minDist = dist;
closestEnemy = hero.enemies[i];
}
}
if (closestEnemy) {
// Always fire the main bullet
var bullet = new Bullet();
bullet.x = hero.x;
bullet.y = hero.y;
var dx = closestEnemy.x - hero.x;
var dy = closestEnemy.y - hero.y;
bullet.angle = Math.atan2(dy, dx);
heroBullets.push(bullet);
game.addChild(bullet);
// After 5 kills, fire a second bullet with a slight delay
if (hero.totalKills >= 5) {
LK.setTimeout(function () {
if (!hero || !closestEnemy) return;
var bullet2 = new Bullet();
bullet2.x = hero.x;
bullet2.y = hero.y;
var dx2 = closestEnemy.x - hero.x;
var dy2 = closestEnemy.y - hero.y;
bullet2.angle = Math.atan2(dy2, dx2);
heroBullets.push(bullet2);
game.addChild(bullet2);
}, 120); // ~2 frames later
}
// After 25 kills, fire a third bullet in the opposite direction
if (hero.totalKills >= 25) {
var bullet3 = new Bullet();
bullet3.x = hero.x;
bullet3.y = hero.y;
// Opposite direction
bullet3.angle = Math.atan2(dy, dx) + Math.PI;
heroBullets.push(bullet3);
game.addChild(bullet3);
}
}
}
});
vampire hunter pixel art Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
pixel art vampire, single sprite Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
pixel art boomerang Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
fat demon. In-Game asset. 2d. High contrast. No shadows
archer goblin. In-Game asset. 2d. High contrast. No shadows