User prompt
Agac 2 ve desdroyhomeyi sil
User prompt
Delorasyonlari haritanin her yerine ekle karakterin yuruduyu yerde ortaya cikmasin
User prompt
Bu modeledim agaci haritanin rasgele yerlerine ekle
User prompt
Agac 2 yi modelle
User prompt
Haritadaki dekorasyonlari tum harita boyunca olsun yakin olmasin evler random yerlerde ağaclar random yerlerde olsun cimpar tum harita boyunca olsun
User prompt
Dekorasyonlar yakin yakin olmasin uzak uzak rasgele olsun tum haritayi kapsasin
User prompt
Haritayi sonsuz yap dusmanlarda karakterin yakinda dosun
User prompt
Haritaya ağaclar cimler yikilmis evler kamp atesi rasgele yerlere yerlesdir
User prompt
Bos ve dusmanlar hitboxun disindan vurmasinlar
User prompt
Karakterin hitboxunu yeniden yap
User prompt
Bosun saldirilarindan biride havadan yere kirmizi iz birakib mermi atsin
User prompt
Boosun en cok kullandi saldirisi mermi atmak olsun
User prompt
Boos saldirilarindan biride yerde kirmizi iz birakim oraya ziplasin
User prompt
Kasadan 10sansla level artilan esya ciksin
User prompt
Sandiklarin icinden 50sansla xb ciksin
User prompt
Kutulari modelle
User prompt
Haritada kutular olusun bu kutulari kirinci icinde can ciksin
User prompt
Fasterenemey olunce patlasin
User prompt
Simsek buyucusunun mermilerini modele
User prompt
UI secdiklerimizi buyut ve alt alta koy
User prompt
Her level atlayinca 3ozelik ciksin ve biz 1ini secelim
User prompt
Bosun mermilerini modelle
User prompt
Elektirik buyucusunun atti mermileri modelle ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Ozelik secerken oyun dursun ve secdiyimiz ozelikler alt alta dursunlar
User prompt
Her level atladimizda rasgele 3ozeliyimizden birini secib artira bilelim
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
/****
* Classes
****/
var BasicEnemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('basicEnemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 25;
self.maxHealth = 25;
self.damage = 15;
self.speed = 3;
self.scoreValue = 10;
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xFFFFFF, 200);
if (self.health <= 0) {
// Drop XP orb
var xpOrb = new XPOrb();
xpOrb.x = self.x;
xpOrb.y = self.y;
xpOrbs.push(xpOrb);
game.addChild(xpOrb);
self.destroy();
LK.setScore(LK.getScore() + self.scoreValue);
scoreTxt.setText(LK.getScore());
LK.getSound('enemyDestroy').play();
for (var i = enemies.length - 1; i >= 0; i--) {
if (enemies[i] === self) {
enemies.splice(i, 1);
break;
}
}
}
};
self.update = function () {
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
};
return self;
});
var Boss = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('wikingboss', {
anchorX: 0.5,
anchorY: 0.5
});
bossGraphics.tint = 0x8B4513; // Brown viking color
bossGraphics.scaleX = 4.0; // Much larger viking boss model
bossGraphics.scaleY = 4.0; // Much larger viking boss model
// Add viking boss aura effect
var auraGraphics = self.attachAsset('wikingboss', {
anchorX: 0.5,
anchorY: 0.5
});
auraGraphics.tint = 0xDAA520; // Golden viking aura
auraGraphics.alpha = 0.4;
auraGraphics.scaleX = 4.5; // Larger aura to match viking boss size
auraGraphics.scaleY = 4.5; // Larger aura to match viking boss size
// Add pulsing viking aura animation
tween(auraGraphics, {
scaleX: 5.0,
scaleY: 5.0,
alpha: 0.2
}, {
duration: 1500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(auraGraphics, {
scaleX: 4.5,
scaleY: 4.5,
alpha: 0.4
}, {
duration: 1500,
easing: tween.easeInOut
});
}
});
self.health = 400 + (currentWave - 3) * 85; // Much higher health for viking boss
self.maxHealth = self.health;
self.damage = 70; // Higher damage for intimidating viking boss
self.speed = 1.1; // Slightly slower due to massive viking size
self.scoreValue = 250; // Higher reward for defeating viking boss
self.lastLightningTime = 0;
self.lightningCooldown = 120; // 2 seconds at 60fps
self.lastChargeTime = 0;
self.chargeCooldown = 300; // 5 seconds at 60fps
self.isCharging = false;
self.chargeSpeed = 8;
self.chargeTargetX = 0;
self.chargeTargetY = 0;
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xFFFFFF, 200);
if (self.health <= 0) {
// Drop multiple XP orbs
for (var orbCount = 0; orbCount < 5; orbCount++) {
var xpOrb = new XPOrb();
xpOrb.x = self.x + (Math.random() - 0.5) * 100;
xpOrb.y = self.y + (Math.random() - 0.5) * 100;
xpOrbs.push(xpOrb);
game.addChild(xpOrb);
}
self.destroy();
LK.setScore(LK.getScore() + self.scoreValue);
scoreTxt.setText(LK.getScore());
LK.getSound('enemyDestroy').play();
for (var i = enemies.length - 1; i >= 0; i--) {
if (enemies[i] === self) {
enemies.splice(i, 1);
break;
}
}
}
};
self.shootBigBullets = function () {
// Create multiple big bullets
for (var bulletCount = 0; bulletCount < 5; bulletCount++) {
var bigBullet = new BossBullet();
bigBullet.x = self.x;
bigBullet.y = self.y;
// Spread bullets around hero
var angleOffset = (bulletCount - 2) * Math.PI / 8;
var targetX = hero.x + Math.cos(angleOffset) * 150;
var targetY = hero.y + Math.sin(angleOffset) * 150;
bigBullet.setTarget(targetX, targetY);
bossBullets.push(bigBullet);
game.addChild(bigBullet);
}
LK.effects.flashObject(self, 0xFF4500, 400);
};
self.startCharge = function () {
self.isCharging = true;
self.chargeTargetX = hero.x;
self.chargeTargetY = hero.y;
LK.effects.flashObject(self, 0xFF4500, 500);
// Viking boss grows larger during charge
tween(bossGraphics, {
scaleX: 4.5,
scaleY: 4.5
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
// Charge for 1 second then return to normal
LK.setTimeout(function () {
self.isCharging = false;
tween(bossGraphics, {
scaleX: 4.0,
scaleY: 4.0
}, {
duration: 200,
easing: tween.easeIn
});
}, 1000);
}
});
};
self.update = function () {
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var currentTime = LK.ticks;
// Big bullet attack
if (distance < 600 && currentTime - self.lastLightningTime > self.lightningCooldown) {
self.shootBigBullets();
self.lastLightningTime = currentTime;
}
// Charge attack
if (distance > 200 && distance < 500 && currentTime - self.lastChargeTime > self.chargeCooldown && !self.isCharging) {
self.startCharge();
self.lastChargeTime = currentTime;
}
// Movement behavior
if (self.isCharging) {
// Charge towards target position
var chargeDx = self.chargeTargetX - self.x;
var chargeDy = self.chargeTargetY - self.y;
var chargeDistance = Math.sqrt(chargeDx * chargeDx + chargeDy * chargeDy);
if (chargeDistance > 0) {
self.x += chargeDx / chargeDistance * self.chargeSpeed;
self.y += chargeDy / chargeDistance * self.chargeSpeed;
}
} else {
// Normal movement - maintain distance from hero
if (distance > 300) {
// Move closer
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
} else if (distance < 150) {
// Move away
if (distance > 0) {
self.x -= dx / distance * self.speed;
self.y -= dy / distance * self.speed;
}
}
}
};
return self;
});
var BossBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bossBullet', {
anchorX: 0.5,
anchorY: 0.5
});
bulletGraphics.scaleX = 1.5; // Scale for appropriate size
bulletGraphics.scaleY = 1.5; // Scale for appropriate size
// Add glowing effect to boss bullets
var glowGraphics = self.attachAsset('bossBullet', {
anchorX: 0.5,
anchorY: 0.5
});
glowGraphics.tint = 0xFF6600; // Orange glow
glowGraphics.alpha = 0.4;
glowGraphics.scaleX = 2;
glowGraphics.scaleY = 2;
// Pulsing glow animation
tween(glowGraphics, {
scaleX: 2.5,
scaleY: 2.5,
alpha: 0.2
}, {
duration: 500,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(glowGraphics, {
scaleX: 2,
scaleY: 2,
alpha: 0.4
}, {
duration: 500,
easing: tween.easeInOut
});
}
});
self.speed = 6;
self.damage = 50;
self.targetX = 0;
self.targetY = 0;
self.directionX = 0;
self.directionY = 0;
self.setTarget = function (x, y) {
self.targetX = x;
self.targetY = y;
var dx = x - self.x;
var dy = y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.directionX = dx / distance;
self.directionY = dy / distance;
}
// Rotate bullet to face direction
bulletGraphics.rotation = Math.atan2(dy, dx) + Math.PI / 2;
};
self.update = function () {
self.x += self.directionX * self.speed;
self.y += self.directionY * self.speed;
// Rotate the boss bullet for visual effect
self.rotation += 0.1;
// Remove bullet if it goes off screen
if (self.x < -50 || self.x > 8242 || self.y < -50 || self.y > 10978) {
self.destroy();
for (var i = bossBullets.length - 1; i >= 0; i--) {
if (bossBullets[i] === self) {
bossBullets.splice(i, 1);
break;
}
}
}
};
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 = Bullet.prototype.baseSpeed || 8;
self.damage = 25;
self.targetX = 0;
self.targetY = 0;
self.directionX = 0;
self.directionY = 0;
self.setTarget = function (x, y) {
self.targetX = x;
self.targetY = y;
var dx = x - self.x;
var dy = y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.directionX = dx / distance;
self.directionY = dy / distance;
}
// Rotate bullet to face direction
bulletGraphics.rotation = Math.atan2(dy, dx) + Math.PI / 2;
};
self.update = function () {
self.x += self.directionX * self.speed;
self.y += self.directionY * self.speed;
// Remove bullet if it goes off screen
if (self.x < -50 || self.x > 8242 || self.y < -50 || self.y > 10978) {
self.destroy();
for (var i = bullets.length - 1; i >= 0; i--) {
if (bullets[i] === self) {
bullets.splice(i, 1);
break;
}
}
}
};
return self;
});
var FastEnemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('fastEnemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 15;
self.maxHealth = 15;
self.damage = 10;
self.speed = 4.5;
self.scoreValue = 15;
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xFFFFFF, 200);
if (self.health <= 0) {
// Create explosion effect
LK.effects.flashScreen(0xFFA500, 300); // Orange flash
// Deal damage to nearby enemies
for (var j = 0; j < enemies.length; j++) {
var otherEnemy = enemies[j];
if (otherEnemy !== self) {
var explodeDx = otherEnemy.x - self.x;
var explodeDy = otherEnemy.y - self.y;
var explodeDistance = Math.sqrt(explodeDx * explodeDx + explodeDy * explodeDy);
// Damage enemies within 150 pixel radius
if (explodeDistance < 150) {
otherEnemy.takeDamage(20);
// Push enemies away from explosion
if (explodeDistance > 0) {
otherEnemy.x += explodeDx / explodeDistance * 50;
otherEnemy.y += explodeDy / explodeDistance * 50;
}
}
}
}
// Check if hero is in explosion radius
var heroDx = hero.x - self.x;
var heroDy = hero.y - self.y;
var heroDistance = Math.sqrt(heroDx * heroDx + heroDy * heroDy);
if (heroDistance < 150) {
hero.takeDamage(15);
}
// Drop XP orb
var xpOrb = new XPOrb();
xpOrb.x = self.x;
xpOrb.y = self.y;
xpOrbs.push(xpOrb);
game.addChild(xpOrb);
self.destroy();
LK.setScore(LK.getScore() + self.scoreValue);
scoreTxt.setText(LK.getScore());
LK.getSound('enemyDestroy').play();
for (var i = enemies.length - 1; i >= 0; i--) {
if (enemies[i] === self) {
enemies.splice(i, 1);
break;
}
}
}
};
self.update = function () {
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
};
return self;
});
var Hero = Container.expand(function () {
var self = Container.call(this);
var heroGraphics = self.attachAsset('hero', {
anchorX: 0.5,
anchorY: 0.5
});
var weaponGraphics = self.attachAsset('weapon', {
anchorX: 0.5,
anchorY: 0.9
});
weaponGraphics.x = 25;
weaponGraphics.y = -10;
self.maxHealth = 100;
self.health = self.maxHealth;
self.attackDamage = 25;
self.isInvulnerable = false;
self.takeDamage = function (damage) {
if (self.isInvulnerable) return;
self.health -= damage;
if (self.health <= 0) {
self.health = 0;
LK.showGameOver();
return;
}
// Flash red when taking damage
LK.effects.flashObject(self, 0xFF0000, 300);
LK.getSound('playerHit').play();
// Brief invulnerability
self.isInvulnerable = true;
LK.setTimeout(function () {
self.isInvulnerable = false;
}, 500);
};
self.attack = function (enemy) {
enemy.takeDamage(self.attackDamage);
LK.getSound('enemyHit').play();
// Weapon swing animation
tween(weaponGraphics, {
rotation: weaponGraphics.rotation + Math.PI / 3
}, {
duration: 100
});
};
self.updateWeapon = function (targetX, targetY) {
// Calculate angle to target
var dx = targetX - self.x;
var dy = targetY - self.y;
var angle = Math.atan2(dy, dx);
weaponGraphics.rotation = angle + Math.PI / 2;
};
self.shoot = function (targetX, targetY) {
var bullet = new Bullet();
bullet.x = self.x + Math.cos(weaponGraphics.rotation - Math.PI / 2) * 40;
bullet.y = self.y + Math.sin(weaponGraphics.rotation - Math.PI / 2) * 40;
bullet.setTarget(targetX, targetY);
bullets.push(bullet);
game.addChild(bullet);
LK.getSound('weaponShoot').play();
// Weapon recoil animation
tween(weaponGraphics, {
y: weaponGraphics.y + 5
}, {
duration: 50,
onComplete: function onComplete() {
tween(weaponGraphics, {
y: weaponGraphics.y - 5
}, {
duration: 50
});
}
});
};
self.isWalking = false;
self.moveSpeed = 4;
self.analogMove = function (deltaX, deltaY) {
// Analog movement with bounds checking
var newX = self.x + deltaX * self.moveSpeed;
var newY = self.y + deltaY * self.moveSpeed;
// Keep within bounds
self.x = Math.max(40, Math.min(8152, newX));
self.y = Math.max(40, Math.min(10888, newY));
};
self.walkTo = function (targetX, targetY) {
// Don't start new walk if already walking
if (self.isWalking) {
tween.stop(self, {
x: true,
y: true
});
}
self.isWalking = true;
// Keep within bounds
targetX = Math.max(40, Math.min(8152, targetX));
targetY = Math.max(40, Math.min(10888, targetY));
// Calculate distance for duration
var dx = targetX - self.x;
var dy = targetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var duration = distance * 2; // Adjust speed by changing multiplier
// Walking animation with slight bounce
tween(heroGraphics, {
scaleY: 0.9
}, {
duration: duration / 4,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(heroGraphics, {
scaleY: 1.1
}, {
duration: duration / 4,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(heroGraphics, {
scaleY: 1.0
}, {
duration: duration / 2,
easing: tween.easeOut
});
}
});
}
});
// Move to target position
tween(self, {
x: targetX,
y: targetY
}, {
duration: duration,
easing: tween.easeOut,
onFinish: function onFinish() {
self.isWalking = false;
}
});
};
return self;
});
var Lightning = Container.expand(function () {
var self = Container.call(this);
var lightningGraphics = self.attachAsset('lightningBolt', {
anchorX: 0.5,
anchorY: 0.5
});
// Add glowing effect to lightning bolt
var glowGraphics = self.attachAsset('lightningBolt', {
anchorX: 0.5,
anchorY: 0.5
});
glowGraphics.tint = 0xFFFF00; // Yellow glow
glowGraphics.alpha = 0.5;
glowGraphics.scaleX = 1.3;
glowGraphics.scaleY = 1.3;
self.speed = 7;
self.damage = 30;
self.targetX = 0;
self.targetY = 0;
self.directionX = 0;
self.directionY = 0;
self.lifetime = 0;
self.maxLifetime = 120; // 2 seconds at 60fps
// Lightning crackling effect
tween(lightningGraphics, {
alpha: 0.3
}, {
duration: 100,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(lightningGraphics, {
alpha: 1.0
}, {
duration: 100,
easing: tween.easeInOut
});
}
});
self.setTarget = function (x, y) {
self.targetX = x;
self.targetY = y;
var dx = x - self.x;
var dy = y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.directionX = dx / distance;
self.directionY = dy / distance;
}
// Rotate lightning to face direction
lightningGraphics.rotation = Math.atan2(dy, dx) + Math.PI / 2;
glowGraphics.rotation = Math.atan2(dy, dx) + Math.PI / 2;
};
self.update = function () {
self.x += self.directionX * self.speed;
self.y += self.directionY * self.speed;
self.lifetime++;
// Random flickering effect
if (Math.random() < 0.3) {
lightningGraphics.alpha = Math.random() * 0.5 + 0.5;
}
// Remove lightning after lifetime expires or goes off screen
if (self.lifetime > self.maxLifetime || self.x < -50 || self.x > 8242 || self.y < -50 || self.y > 10978) {
self.destroy();
for (var i = lightningBolts.length - 1; i >= 0; i--) {
if (lightningBolts[i] === self) {
lightningBolts.splice(i, 1);
break;
}
}
}
};
return self;
});
var StrongEnemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('strongEnemy', {
anchorX: 0.5,
anchorY: 0.5
});
self.health = 50;
self.maxHealth = 50;
self.damage = 25;
self.speed = 2.8;
self.scoreValue = 25;
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xFFFFFF, 200);
if (self.health <= 0) {
// Drop XP orb
var xpOrb = new XPOrb();
xpOrb.x = self.x;
xpOrb.y = self.y;
xpOrbs.push(xpOrb);
game.addChild(xpOrb);
self.destroy();
LK.setScore(LK.getScore() + self.scoreValue);
scoreTxt.setText(LK.getScore());
LK.getSound('enemyDestroy').play();
for (var i = enemies.length - 1; i >= 0; i--) {
if (enemies[i] === self) {
enemies.splice(i, 1);
break;
}
}
}
};
self.update = function () {
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
};
return self;
});
var UpgradeOption = Container.expand(function () {
var self = Container.call(this);
// Background for upgrade option - made larger
var bgGraphics = self.attachAsset('levelBarBg', {
anchorX: 0.5,
anchorY: 0.5
});
bgGraphics.scaleX = 3.5;
bgGraphics.scaleY = 4;
bgGraphics.tint = 0x2c3e50;
// Title text - made larger
self.titleText = new Text2('', {
size: 80,
fill: 0xFFD700
});
self.titleText.anchor.set(0.5, 0.5);
self.titleText.y = -100;
self.addChild(self.titleText);
// Description text - made larger
self.descText = new Text2('', {
size: 60,
fill: 0xFFFFFF
});
self.descText.anchor.set(0.5, 0.5);
self.descText.y = 0;
self.addChild(self.descText);
// Upgrade type
self.upgradeType = '';
self.setUpgrade = function (type, title, description) {
self.upgradeType = type;
self.titleText.setText(title);
self.descText.setText(description);
};
// Hover effect
self.down = function (x, y, obj) {
tween(bgGraphics, {
scaleX: 3.8,
scaleY: 4.3
}, {
duration: 100,
easing: tween.easeOut
});
};
self.up = function (x, y, obj) {
tween(bgGraphics, {
scaleX: 3.5,
scaleY: 4
}, {
duration: 100,
easing: tween.easeIn
});
// Apply the upgrade
applyUpgrade(self.upgradeType);
};
return self;
});
var Wizard = Container.expand(function () {
var self = Container.call(this);
var wizardGraphics = self.attachAsset('Wizard', {
anchorX: 0.5,
anchorY: 0.5
});
// Add magical aura effect using the wizard asset
var auraGraphics = self.attachAsset('Wizard', {
anchorX: 0.5,
anchorY: 0.5
});
auraGraphics.tint = 0x9370DB; // Purple aura
auraGraphics.alpha = 0.3;
auraGraphics.scaleX = 1.3;
auraGraphics.scaleY = 1.3;
// Add pulsing magical aura animation
tween(auraGraphics, {
scaleX: 1.8,
scaleY: 1.8,
alpha: 0.1
}, {
duration: 1000,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(auraGraphics, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0.3
}, {
duration: 1000,
easing: tween.easeInOut
});
}
});
self.health = 60;
self.maxHealth = 60;
self.damage = 20;
self.speed = 2.5;
self.scoreValue = 30;
self.lastLightningTime = 0;
self.lightningCooldown = 180; // 3 seconds at 60fps
self.lightningRange = 400;
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xFFFFFF, 200);
if (self.health <= 0) {
// Drop XP orb
var xpOrb = new XPOrb();
xpOrb.x = self.x;
xpOrb.y = self.y;
xpOrbs.push(xpOrb);
game.addChild(xpOrb);
self.destroy();
LK.setScore(LK.getScore() + self.scoreValue);
scoreTxt.setText(LK.getScore());
LK.getSound('enemyDestroy').play();
for (var i = enemies.length - 1; i >= 0; i--) {
if (enemies[i] === self) {
enemies.splice(i, 1);
break;
}
}
}
};
self.shootLightning = function () {
// Create lightning bolt
var lightning = new Lightning();
lightning.x = self.x;
lightning.y = self.y;
lightning.setTarget(hero.x, hero.y);
lightningBolts.push(lightning);
game.addChild(lightning);
// Enhanced lightning casting effects
LK.effects.flashObject(self, 0xFFFF00, 300);
LK.effects.flashObject(auraGraphics, 0xFFFFFF, 400);
// Dramatic casting animation - wizard grows larger then returns
tween(wizardGraphics, {
scaleX: 1.5,
scaleY: 1.5,
rotation: wizardGraphics.rotation + Math.PI / 6
}, {
duration: 150,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(wizardGraphics, {
scaleX: 1.2,
scaleY: 1.2,
rotation: wizardGraphics.rotation - Math.PI / 6
}, {
duration: 250,
easing: tween.easeIn
});
}
});
// Aura intensifies during casting
tween(auraGraphics, {
scaleX: 2.2,
scaleY: 2.2,
alpha: 0.6
}, {
duration: 200,
easing: tween.easeOut,
onFinish: function onFinish() {
tween(auraGraphics, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0.3
}, {
duration: 300,
easing: tween.easeIn
});
}
});
};
self.update = function () {
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Keep distance and shoot lightning
if (distance < self.lightningRange && distance > 150) {
// Stop moving and prepare to shoot
var currentTime = LK.ticks;
if (currentTime - self.lastLightningTime > self.lightningCooldown) {
self.shootLightning();
self.lastLightningTime = currentTime;
}
} else if (distance > self.lightningRange) {
// Move closer to hero
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
} else if (distance < 150) {
// Move away from hero
if (distance > 0) {
self.x -= dx / distance * self.speed;
self.y -= dy / distance * self.speed;
}
}
};
return self;
});
var XPOrb = Container.expand(function () {
var self = Container.call(this);
var orbGraphics = self.attachAsset('xpOrb', {
anchorX: 0.5,
anchorY: 0.5
});
self.xpValue = 5;
self.moveSpeed = 2;
self.attractRange = 150;
// Add pulsing animation to make XP orbs more attractive
tween(orbGraphics, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
tween(orbGraphics, {
scaleX: 1.0,
scaleY: 1.0
}, {
duration: 800,
easing: tween.easeInOut,
onFinish: function onFinish() {
// Restart the pulsing animation
tween(orbGraphics, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 800,
easing: tween.easeInOut
});
}
});
}
});
self.update = function () {
// XP orb magnetic attraction to other nearby orbs
for (var o = 0; o < xpOrbs.length; o++) {
var otherOrb = xpOrbs[o];
if (otherOrb !== self) {
var orbDx = otherOrb.x - self.x;
var orbDy = otherOrb.y - self.y;
var orbDistance = Math.sqrt(orbDx * orbDx + orbDy * orbDy);
// Attract to nearby orbs within 80 pixels
if (orbDistance < 80 && orbDistance > 0) {
var attractForce = 0.5;
self.x += orbDx / orbDistance * attractForce;
self.y += orbDy / orbDistance * attractForce;
}
}
}
// Move toward hero if within attract range
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < self.attractRange) {
if (distance > 0) {
self.x += dx / distance * self.moveSpeed;
self.y += dy / distance * self.moveSpeed;
}
}
// Check if collected by hero
if (distance < 30) {
// Give XP to player
currentXP += self.xpValue;
LK.setScore(LK.getScore() + self.xpValue);
scoreTxt.setText(LK.getScore());
LK.getSound('xpCollect').play();
// Remove from xpOrbs array
for (var i = xpOrbs.length - 1; i >= 0; i--) {
if (xpOrbs[i] === self) {
xpOrbs.splice(i, 1);
break;
}
}
self.destroy();
}
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x228B22
});
/****
* Game Code
****/
var hero;
var enemies = [];
var bullets = [];
var xpOrbs = [];
var lightningBolts = [];
var bossBullets = [];
var spawnTimer = 0;
var difficultyLevel = 1;
var scoreTxt;
var healthBar;
var healthBarBg;
var attackIndicator;
var lastShootTime = 0;
var joystickBase;
var joystickKnob;
var isJoystickActive = false;
var joystickStartX = 0;
var joystickStartY = 0;
var joystickRadius = 80;
var movementX = 0;
var movementY = 0;
var healthText;
var levelBar;
var levelBarBg;
var levelText;
var playerLevel = 1;
var currentXP = 0;
var xpToNextLevel = 30;
var currentWave = 1;
var waveStartTime = 0;
var waveDuration = 60000; // 1 minute in milliseconds
var waveEnemyCount = 0;
var baseEnemiesPerWave = 20;
var waveText;
var waveTimer;
var bossSpawned = false;
var upgradeSelectionContainer;
var isSelectingUpgrade = false;
var availableUpgrades = [{
type: 'health',
title: 'Health Boost',
description: '+20 Max Health'
}, {
type: 'damage',
title: 'Damage Up',
description: '+10 Attack Damage'
}, {
type: 'speed',
title: 'Speed Boost',
description: '+1 Movement Speed'
}, {
type: 'attackSpeed',
title: 'Attack Speed',
description: 'Faster Shooting'
}, {
type: 'bulletSpeed',
title: 'Bullet Speed',
description: 'Faster Bullets'
}, {
type: 'regen',
title: 'Regeneration',
description: 'Heal 1 HP/sec'
}];
var lastRegenTime = 0;
var hasRegen = false;
// Create score display
scoreTxt = new Text2('0', {
size: 80,
fill: 0xFFFFFF
});
scoreTxt.anchor.set(0.5, 0);
LK.gui.top.addChild(scoreTxt);
// Create health bar background
healthBarBg = LK.getAsset('healthBarBg', {
anchorX: 0,
anchorY: 0
});
healthBarBg.x = 150;
healthBarBg.y = 50;
LK.gui.topLeft.addChild(healthBarBg);
// Create health bar
healthBar = LK.getAsset('healthBar', {
anchorX: 0,
anchorY: 0
});
healthBar.x = 150;
healthBar.y = 50;
LK.gui.topLeft.addChild(healthBar);
// Create health text
healthText = new Text2('100/100', {
size: 40,
fill: 0xFFFFFF
});
healthText.anchor.set(0, 0.5);
healthText.x = 370;
healthText.y = 60;
LK.gui.topLeft.addChild(healthText);
// Create level bar background at bottom
levelBarBg = LK.getAsset('levelBarBg', {
anchorX: 0.5,
anchorY: 0.5
});
levelBarBg.x = 2048 / 2;
levelBarBg.y = 2732 - 60;
game.addChild(levelBarBg);
// Create level bar fill
levelBar = LK.getAsset('levelBar', {
anchorX: 0,
anchorY: 0.5
});
levelBar.x = levelBarBg.x - levelBarBg.width / 2;
levelBar.y = levelBarBg.y;
game.addChild(levelBar);
// Create level text
levelText = new Text2('Level 1', {
size: 50,
fill: 0xFFFFFF
});
levelText.anchor.set(0.5, 0.5);
levelText.x = levelBarBg.x;
levelText.y = levelBarBg.y - 50;
game.addChild(levelText);
// Create wave display
waveText = new Text2('Wave 1', {
size: 60,
fill: 0xFFD700
});
waveText.anchor.set(1, 0);
waveText.x = 2048 - 20;
waveText.y = 20;
LK.gui.topRight.addChild(waveText);
// Create wave timer display
waveTimer = new Text2('2:00', {
size: 50,
fill: 0xFFFFFF
});
waveTimer.anchor.set(0.5, 0);
waveTimer.x = 0;
waveTimer.y = 80;
LK.gui.top.addChild(waveTimer);
// Create upgrade selection container
upgradeSelectionContainer = new Container();
upgradeSelectionContainer.visible = false;
LK.gui.center.addChild(upgradeSelectionContainer);
// Create semi-transparent background
var upgradeBg = LK.getAsset('wallHorizontal', {
anchorX: 0.5,
anchorY: 0.5
});
upgradeBg.scaleX = 8;
upgradeBg.scaleY = 8;
upgradeBg.tint = 0x000000;
upgradeBg.alpha = 0.8;
upgradeSelectionContainer.addChild(upgradeBg);
// Create "Choose Upgrade" title
var upgradeTitle = new Text2('Choose Your Upgrade!', {
size: 80,
fill: 0xFFD700
});
upgradeTitle.anchor.set(0.5, 0.5);
upgradeTitle.y = -200;
upgradeSelectionContainer.addChild(upgradeTitle);
// Create boss health bar background
var bossHealthBarBg = LK.getAsset('healthBarBg', {
anchorX: 0.5,
anchorY: 0
});
bossHealthBarBg.x = 0;
bossHealthBarBg.y = 140;
bossHealthBarBg.visible = false;
bossHealthBarBg.scaleX = 2;
LK.gui.top.addChild(bossHealthBarBg);
// Create boss health bar
var bossHealthBar = LK.getAsset('healthBar', {
anchorX: 0.5,
anchorY: 0
});
bossHealthBar.x = 0;
bossHealthBar.y = 140;
bossHealthBar.visible = false;
bossHealthBar.scaleX = 2;
bossHealthBar.tint = 0xFF4444; // Red color for boss health
LK.gui.top.addChild(bossHealthBar);
// Create boss health text
var bossHealthText = new Text2('', {
size: 40,
fill: 0xFFFFFF
});
bossHealthText.anchor.set(0.5, 0);
bossHealthText.x = 0;
bossHealthText.y = 180;
bossHealthText.visible = false;
LK.gui.top.addChild(bossHealthText);
// Create hero
hero = game.addChild(new Hero());
hero.x = 4096;
hero.y = 5464;
// Camera following variables
var cameraX = 0;
var cameraY = 0;
var cameraFollowSpeed = 0.1;
var cameraSmoothing = true;
// Create attack range indicator (initially hidden)
attackIndicator = LK.getAsset('attackRange', {
anchorX: 0.5,
anchorY: 0.5
});
attackIndicator.alpha = 0.3;
attackIndicator.visible = false;
game.addChild(attackIndicator);
// Create analog joystick base
joystickBase = LK.getAsset('attackRange', {
anchorX: 0.5,
anchorY: 0.5
});
joystickBase.alpha = 0.2;
joystickBase.visible = false;
joystickBase.scaleX = 1.5;
joystickBase.scaleY = 1.5;
game.addChild(joystickBase);
// Create analog joystick knob
joystickKnob = LK.getAsset('hero', {
anchorX: 0.5,
anchorY: 0.5
});
joystickKnob.alpha = 0.7;
joystickKnob.visible = false;
joystickKnob.scaleX = 0.6;
joystickKnob.scaleY = 0.6;
game.addChild(joystickKnob);
// Create map boundary walls
var topWall = LK.getAsset('wallHorizontal', {
anchorX: 0.5,
anchorY: 0.5
});
topWall.x = 4096;
topWall.y = 20;
game.addChild(topWall);
var bottomWall = LK.getAsset('wallHorizontal', {
anchorX: 0.5,
anchorY: 0.5
});
bottomWall.x = 4096;
bottomWall.y = 10928 - 20;
game.addChild(bottomWall);
var leftWall = LK.getAsset('wallVertical', {
anchorX: 0.5,
anchorY: 0.5
});
leftWall.x = 20;
leftWall.y = 5464;
game.addChild(leftWall);
var rightWall = LK.getAsset('wallVertical', {
anchorX: 0.5,
anchorY: 0.5
});
rightWall.x = 8192 - 20;
rightWall.y = 5464;
game.addChild(rightWall);
function spawnEnemy() {
var enemyType = Math.random();
var enemy;
if (enemyType < 0.5) {
enemy = new BasicEnemy();
} else if (enemyType < 0.75) {
enemy = new FastEnemy();
} else if (enemyType < 0.95) {
enemy = new StrongEnemy();
} else {
enemy = new Wizard();
}
// Spawn at random edge position
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
// Top
enemy.x = Math.random() * 8192;
enemy.y = -50;
break;
case 1:
// Right
enemy.x = 8192 + 50;
enemy.y = Math.random() * 10928;
break;
case 2:
// Bottom
enemy.x = Math.random() * 8192;
enemy.y = 10928 + 50;
break;
case 3:
// Left
enemy.x = -50;
enemy.y = Math.random() * 10928;
break;
}
enemies.push(enemy);
game.addChild(enemy);
}
function updateHealthBar() {
var healthPercent = hero.health / hero.maxHealth;
healthBar.scaleX = healthPercent;
if (healthPercent > 0.5) {
healthBar.tint = 0x4CAF50; // Green
} else if (healthPercent > 0.25) {
healthBar.tint = 0xFFC107; // Yellow
} else {
healthBar.tint = 0xF44336; // Red
}
// Update health text
healthText.setText(Math.ceil(hero.health) + '/' + hero.maxHealth);
}
function updateLevelBar() {
var xpPercent = currentXP / xpToNextLevel;
levelBar.scaleX = xpPercent;
// Check for level up
if (currentXP >= xpToNextLevel) {
playerLevel++;
currentXP = 0;
xpToNextLevel = playerLevel * 30; // Increase XP requirement
levelText.setText('Level ' + playerLevel);
// Level up effects
LK.effects.flashScreen(0xFFD700, 500);
hero.maxHealth += 3;
hero.health = hero.maxHealth; // Full heal on level up
// Show upgrade selection
showUpgradeSelection();
}
}
function showUpgradeSelection() {
isSelectingUpgrade = true;
upgradeSelectionContainer.visible = true;
// Remove any existing upgrade options
for (var i = upgradeSelectionContainer.children.length - 1; i >= 0; i--) {
var child = upgradeSelectionContainer.children[i];
if (child instanceof UpgradeOption) {
child.destroy();
}
}
// Randomly select 3 different upgrades
var selectedUpgrades = [];
var tempUpgrades = availableUpgrades.slice(); // Copy array
for (var j = 0; j < 3 && tempUpgrades.length > 0; j++) {
var randomIndex = Math.floor(Math.random() * tempUpgrades.length);
selectedUpgrades.push(tempUpgrades[randomIndex]);
tempUpgrades.splice(randomIndex, 1);
}
// Create upgrade option buttons - vertical layout
for (var k = 0; k < selectedUpgrades.length; k++) {
var option = new UpgradeOption();
var upgrade = selectedUpgrades[k];
option.setUpgrade(upgrade.type, upgrade.title, upgrade.description);
option.x = 0; // Center horizontally
option.y = (k - 1) * 300; // Position vertically: -300, 0, 300
upgradeSelectionContainer.addChild(option);
}
}
function applyUpgrade(upgradeType) {
// Mark upgrade as applied
for (var i = 0; i < availableUpgrades.length; i++) {
if (availableUpgrades[i].type === upgradeType) {
availableUpgrades[i].applied = true;
break;
}
}
switch (upgradeType) {
case 'health':
hero.maxHealth += 20;
hero.health += 20;
updateHealthBar();
break;
case 'damage':
hero.attackDamage += 10;
break;
case 'speed':
hero.moveSpeed += 1;
break;
case 'attackSpeed':
// Handled in auto-shoot logic
break;
case 'bulletSpeed':
// Increase all future bullet speeds
Bullet.prototype.baseSpeed = 12; // Default is 8
break;
case 'regen':
hasRegen = true;
break;
}
// Hide upgrade selection
isSelectingUpgrade = false;
upgradeSelectionContainer.visible = false;
}
function updateBossHealthBar() {
// Find if there's a boss enemy alive
var currentBoss = null;
for (var i = 0; i < enemies.length; i++) {
if (enemies[i] instanceof Boss) {
currentBoss = enemies[i];
break;
}
}
// Show/hide boss health bar based on boss presence
if (currentBoss) {
bossHealthBarBg.visible = true;
bossHealthBar.visible = true;
bossHealthText.visible = true;
// Update boss health bar
var bossHealthPercent = currentBoss.health / currentBoss.maxHealth;
bossHealthBar.scaleX = bossHealthPercent * 2; // Scale to match background
// Update boss health text
bossHealthText.setText('Boss: ' + Math.ceil(currentBoss.health) + '/' + currentBoss.maxHealth);
} else {
bossHealthBarBg.visible = false;
bossHealthBar.visible = false;
bossHealthText.visible = false;
}
}
function startNewWave() {
currentWave++;
waveStartTime = Date.now();
waveEnemyCount = 0;
bossSpawned = false;
waveText.setText('Wave ' + currentWave);
// Wave start effects
LK.effects.flashScreen(0x00FF00, 800);
// Increase difficulty each wave
difficultyLevel = currentWave;
}
function updateWaveTimer() {
var currentTime = Date.now();
var timeElapsed = currentTime - waveStartTime;
var timeRemaining = Math.max(0, waveDuration - timeElapsed);
var minutes = Math.floor(timeRemaining / 60000);
var seconds = Math.floor(timeRemaining % 60000 / 1000);
var timeText = minutes + ':' + (seconds < 10 ? '0' : '') + seconds;
waveTimer.setText(timeText);
// Check if wave time is up
if (timeRemaining <= 0) {
startNewWave();
}
}
function updateCamera() {
// Calculate target camera position (center hero on screen)
var targetCameraX = -(hero.x - 2048 / 2);
var targetCameraY = -(hero.y - 2732 / 2);
// Apply camera bounds to prevent showing outside game world
var minCameraX = -8192; // Allow some movement beyond left edge
var maxCameraX = 8192; // Allow some movement beyond right edge
var minCameraY = -10928; // Allow some movement beyond top edge
var maxCameraY = 10928; // Allow some movement beyond bottom edge
targetCameraX = Math.max(minCameraX, Math.min(maxCameraX, targetCameraX));
targetCameraY = Math.max(minCameraY, Math.min(maxCameraY, targetCameraY));
if (cameraSmoothing) {
// Smooth camera following using interpolation
cameraX += (targetCameraX - cameraX) * cameraFollowSpeed;
cameraY += (targetCameraY - cameraY) * cameraFollowSpeed;
} else {
// Direct camera following
cameraX = targetCameraX;
cameraY = targetCameraY;
}
// Apply camera position to game container
game.x = cameraX;
game.y = cameraY;
// Update level bar position to follow hero
levelBarBg.x = hero.x;
levelBarBg.y = hero.y + 300; // Position below hero
levelBar.x = levelBarBg.x - levelBarBg.width / 2;
levelBar.y = levelBarBg.y;
levelText.x = levelBarBg.x;
levelText.y = levelBarBg.y - 50;
}
function handleMove(x, y, obj) {
// Handle analog joystick movement
if (isJoystickActive) {
var deltaX = x - joystickStartX;
var deltaY = y - joystickStartY;
var distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
// Limit joystick range
if (distance > joystickRadius) {
deltaX = deltaX / distance * joystickRadius;
deltaY = deltaY / distance * joystickRadius;
}
// Update joystick knob position
joystickKnob.x = joystickStartX + deltaX;
joystickKnob.y = joystickStartY + deltaY;
// Calculate movement values (-1 to 1)
movementX = deltaX / joystickRadius;
movementY = deltaY / joystickRadius;
}
}
game.move = handleMove;
game.down = function (x, y, obj) {
// Make hero walk to touch position
hero.walkTo(x, y);
};
game.up = function (x, y, obj) {
// Deactivate analog joystick
if (isJoystickActive) {
isJoystickActive = false;
joystickBase.visible = false;
joystickKnob.visible = false;
movementX = 0;
movementY = 0;
}
attackIndicator.visible = false;
};
game.update = function () {
// Initialize wave system on first update
if (waveStartTime === 0) {
waveStartTime = Date.now();
}
// Pause game logic during upgrade selection
if (isSelectingUpgrade) {
return;
}
// Update wave timer
updateWaveTimer();
// Apply regeneration if unlocked
if (hasRegen && hero.health < hero.maxHealth) {
var currentTime = LK.ticks;
if (currentTime - lastRegenTime > 60) {
// 60 ticks = 1 second
hero.health = Math.min(hero.health + 1, hero.maxHealth);
lastRegenTime = currentTime;
updateHealthBar();
}
}
// Process analog movement
if (isJoystickActive && (Math.abs(movementX) > 0.1 || Math.abs(movementY) > 0.1)) {
hero.analogMove(movementX, movementY);
}
spawnTimer++;
// Wave-based enemy spawning
var maxEnemiesThisWave = baseEnemiesPerWave + (currentWave - 1) * 5;
var spawnRate = Math.max(60 - currentWave * 3, 15);
// Only spawn if we haven't reached the wave enemy limit
if (spawnTimer >= spawnRate && waveEnemyCount < maxEnemiesThisWave) {
spawnEnemy();
waveEnemyCount++;
spawnTimer = 0;
}
// Boss spawning for wave 1 and above
if (currentWave >= 1 && !bossSpawned && waveEnemyCount >= maxEnemiesThisWave / 2) {
var boss = new Boss();
// Spawn boss at random edge position
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
// Top
boss.x = Math.random() * 8192;
boss.y = -100;
break;
case 1:
// Right
boss.x = 8192 + 100;
boss.y = Math.random() * 10928;
break;
case 2:
// Bottom
boss.x = Math.random() * 8192;
boss.y = 10928 + 100;
break;
case 3:
// Left
boss.x = -100;
boss.y = Math.random() * 10928;
break;
}
enemies.push(boss);
game.addChild(boss);
bossSpawned = true;
// Boss spawn effects
LK.effects.flashScreen(0xFF0000, 1000);
}
// Update weapon to point towards nearest enemy
var nearestEnemy = null;
var nearestDistance = Infinity;
for (var j = 0; j < enemies.length; j++) {
var tempEnemy = enemies[j];
var tempDx = hero.x - tempEnemy.x;
var tempDy = hero.y - tempEnemy.y;
var tempDistance = Math.sqrt(tempDx * tempDx + tempDy * tempDy);
if (tempDistance < nearestDistance) {
nearestEnemy = tempEnemy;
nearestDistance = tempDistance;
}
}
if (nearestEnemy) {
hero.updateWeapon(nearestEnemy.x, nearestEnemy.y);
// Auto-shoot while moving - shoot at nearest enemy every 40 ticks
var currentTime = LK.ticks;
var shootCooldown = 80;
// Check if attack speed upgrade was selected
for (var u = 0; u < availableUpgrades.length; u++) {
if (availableUpgrades[u].type === 'attackSpeed' && availableUpgrades[u].applied) {
shootCooldown = 40; // Faster shooting
break;
}
}
if (currentTime - lastShootTime > shootCooldown && nearestDistance < 800) {
hero.shoot(nearestEnemy.x, nearestEnemy.y);
lastShootTime = currentTime;
}
}
// Check bullet collisions with enemies
for (var b = bullets.length - 1; b >= 0; b--) {
var bullet = bullets[b];
var bulletHit = false;
for (var e = enemies.length - 1; e >= 0; e--) {
var enemy = enemies[e];
if (bullet.intersects(enemy)) {
// Bullet hits enemy
enemy.takeDamage(bullet.damage);
bullet.destroy();
bullets.splice(b, 1);
bulletHit = true;
break;
}
}
}
// Check lightning bolt collisions with hero
for (var l = lightningBolts.length - 1; l >= 0; l--) {
var lightning = lightningBolts[l];
if (lightning.intersects(hero)) {
// Lightning hits hero
hero.takeDamage(lightning.damage);
LK.effects.flashObject(hero, 0xFFFF00, 300);
lightning.destroy();
lightningBolts.splice(l, 1);
}
}
// Check boss bullet collisions with hero
for (var bb = bossBullets.length - 1; bb >= 0; bb--) {
var bossBullet = bossBullets[bb];
if (bossBullet.intersects(hero)) {
// Boss bullet hits hero
hero.takeDamage(bossBullet.damage);
LK.effects.flashObject(hero, 0xFF4500, 300);
bossBullet.destroy();
bossBullets.splice(bb, 1);
}
}
// Check collisions and close combat between hero and enemies
for (var i = enemies.length - 1; i >= 0; i--) {
var enemy = enemies[i];
var dx = hero.x - enemy.x;
var dy = hero.y - enemy.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Auto-attack when very close (melee range)
if (distance < 60 && !enemy.justAttacked) {
hero.attack(enemy);
enemy.justAttacked = true;
// Reset attack flag after short delay
LK.setTimeout(function () {
if (enemy && !enemy.destroyed) {
enemy.justAttacked = false;
}
}, 300);
} else if (hero.intersects(enemy) && !enemy.justHitHero) {
// Take damage from collision but don't destroy enemy
hero.takeDamage(enemy.damage);
enemy.justHitHero = true;
// Reset hit flag after short delay to prevent rapid damage
LK.setTimeout(function () {
if (enemy && !enemy.destroyed) {
enemy.justHitHero = false;
}
}, 1000); // 1 second cooldown between hits
}
// Remove enemies that are too far off screen
if (enemy.x < -200 || enemy.x > 8392 || enemy.y < -200 || enemy.y > 11128) {
enemy.destroy();
enemies.splice(i, 1);
}
}
// Update health bar
updateHealthBar();
// Update level bar
updateLevelBar();
// Update boss health bar
updateBossHealthBar();
// Update camera to follow hero
updateCamera();
scoreTxt.setText(LK.getScore());
}; ===================================================================
--- original.js
+++ change.js
@@ -339,8 +339,35 @@
self.takeDamage = function (damage) {
self.health -= damage;
LK.effects.flashObject(self, 0xFFFFFF, 200);
if (self.health <= 0) {
+ // Create explosion effect
+ LK.effects.flashScreen(0xFFA500, 300); // Orange flash
+ // Deal damage to nearby enemies
+ for (var j = 0; j < enemies.length; j++) {
+ var otherEnemy = enemies[j];
+ if (otherEnemy !== self) {
+ var explodeDx = otherEnemy.x - self.x;
+ var explodeDy = otherEnemy.y - self.y;
+ var explodeDistance = Math.sqrt(explodeDx * explodeDx + explodeDy * explodeDy);
+ // Damage enemies within 150 pixel radius
+ if (explodeDistance < 150) {
+ otherEnemy.takeDamage(20);
+ // Push enemies away from explosion
+ if (explodeDistance > 0) {
+ otherEnemy.x += explodeDx / explodeDistance * 50;
+ otherEnemy.y += explodeDy / explodeDistance * 50;
+ }
+ }
+ }
+ }
+ // Check if hero is in explosion radius
+ var heroDx = hero.x - self.x;
+ var heroDy = hero.y - self.y;
+ var heroDistance = Math.sqrt(heroDx * heroDx + heroDy * heroDy);
+ if (heroDistance < 150) {
+ hero.takeDamage(15);
+ }
// Drop XP orb
var xpOrb = new XPOrb();
xpOrb.x = self.x;
xpOrb.y = self.y;
Ucan bomba. In-Game asset. 2d. High contrast. No shadows
Qanli iskelet. In-Game asset. 2d. High contrast. No shadows
Beyaz zirhli sovalye. In-Game asset. 2d. High contrast. No shadows
Iskeleten Elektirik buycusu. In-Game asset. 2d. High contrast. No shadows
Wiking boss. In-Game asset. 2d. High contrast. No shadows
Mavi tatli kucuk slime gozleri parildasin. In-Game asset. 2d. High contrast. No shadows
Yesil top halinde tukuruk. In-Game asset. 2d. High contrast. No shadows
Simsek topu. In-Game asset. 2d. High contrast. No shadows
Sandik. In-Game asset. 2d. High contrast. No shadows
Ağac. In-Game asset. 2d. High contrast. No shadows
Cim yesilik. In-Game asset. 2d. High contrast. No shadows
Kamp atesi. In-Game asset. 2d. High contrast. No shadows
Madeni para. In-Game asset. 2d. High contrast. No shadows
Bullet. In-Game asset. 2d. High contrast. No shadows
Lasergun. In-Game asset. 2d. High contrast. No shadows