User prompt
Please fix the bug: 'Error: Invalid value. Only literals or 1-level deep objects/arrays containing literals are allowed.' in or related to this line: 'storage.playerInventory = storageInventory;' Line Number: 663 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Error: Invalid value. Only literals or 1-level deep objects/arrays containing literals are allowed.' in or related to this line: 'storage.playerInventory = storageInventory;' Line Number: 657 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Error: Invalid value. Only literals or 1-level deep objects/arrays containing literals are allowed.' in or related to this line: 'storage.playerInventory = playerInventory;' Line Number: 643 ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'down')' in or related to this line: 'petCloseBtn.down = function () {' Line Number: 3690
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'down')' in or related to this line: 'inventoryCloseBtn.down = function () {' Line Number: 3671
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'addChild')' in or related to this line: 'inventoryContainer.addChild(inventoryCloseBtn);' Line Number: 3678
User prompt
Implement an offline progress system: when the player returns, calculate gold, XP, and waves cleared while away. Use formulas like DPS * time * wave multiplier to simulate progress. Add a visual summary on return. ↪💡 Consider importing and using the following plugins: @upit/storage.v1
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'down')' in or related to this line: 'inventoryCloseBtn.down = function () {' Line Number: 3488
User prompt
Please fix the bug: 'inventoryBtn is not defined' in or related to this line: 'inventoryBtn.down = function () {' Line Number: 3472
User prompt
Please fix the bug: 'inventoryBtn is not defined' in or related to this line: 'inventoryBtn.down = function () {' Line Number: 3472
User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'down')' in or related to this line: 'inventoryBtn.down = function () {' Line Number: 3463
User prompt
Introduce a pet or companion system. Pets follow the player and offer passive bonuses or attacks. Examples: "Fire Spirit: shoots fireballs", "Fairy: heals player over time", "Goblin: collects gold automatically". Pets can level up or evolve. ↪💡 Consider importing and using the following plugins: @upit/tween.v1, @upit/storage.v1
User prompt
Extend the equipment system. Each equipment drop has a type (e.g., Sword, Wand, Bow), a rarity (Common, Rare, Epic, Legendary), and possible bonus effects (e.g., +crit chance, +burn damage). Equipment should visually change the hero (e.g., glowing sword, icy staff). Add an equipment inventory menu with stats and upgrade options. ↪💡 Consider importing and using the following plugins: @upit/storage.v1, @upit/tween.v1
User prompt
Add three difficulty modes: Easy, Normal, Nightmare. In Nightmare mode, enemies have +50% health and damage, but drop +50% more gold and XP. Let players choose mode at the beginning, and display it in the UI. ↪💡 Consider importing and using the following plugins: @upit/storage.v1, @upit/tween.v1
User prompt
Add a biome system that changes the background and enemy types every 10 waves. Example biomes: Forest, Cave, Volcano, Ice. Each biome should have themed enemies and visual effects (e.g., fog in forest, lava cracks in volcano). Adjust music and environment accordingly. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Introduce unique boss enemies that spawn every 5 or 10 waves. Bosses have special mechanics like jumping, poisoning, summoning minions, or charging at the player. Make them visually distinct and drop better loot or exclusive relics. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
Add a prestige system: when the player reaches a certain wave, allow them to reset progress in exchange for permanent global buffs (e.g., "+5% gold income", "+10 mana capacity"). Keep track of the number of prestiges and make rewards scalable. ↪💡 Consider importing and using the following plugins: @upit/storage.v1, @upit/tween.v1
User prompt
Add a daily reward system that gives gold or bonuses for logging in. Also implement an achievement system with tasks like "Reach wave 10", "Kill 500 enemies", "Collect 100 equipment". Display progress visually and reward players with gold, items, or permanent buffs. ↪💡 Consider importing and using the following plugins: @upit/storage.v1, @upit/tween.v1
User prompt
Introduce a relic system: permanent passive items that drop randomly from enemies or can be purchased in the shop. Each relic gives a unique bonus, e.g., "Vampire Tooth: heals 5% of damage dealt", "Clockwork: +10% attack speed", "Golden Feather: +20% gold pickup range". Stackable and collectible. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
skill tree daha anlaşılır az olsun. okunaklı olsun.
User prompt
Please fix the bug: 'Cannot read properties of undefined (reading 'offense')' in or related to this line: 'var skill = skillTreeData[branch][skillKey];' Line Number: 850
User prompt
Add a skill tree system where the player can unlock passive abilities using earned points. Divide skills into branches: Offense (e.g., "+15% damage", "Critical Hit chance"), Defense (e.g., "+25 HP", "Auto Heal"), and Utility (e.g., "+20% gold gain", "+10% mana regen"). Make each upgrade tiered and visually represented in a tree-like menu. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
sağ üstte oyunu hızlandırma butonu olsun 1x 2x 3x olarak
User prompt
düşen manaları da toplasın karakter altınlar gibi
User prompt
ekranın sağ tarafına Aktif skiller ekleyelim. örneğin ekranki tüm düşmanlara yıldırım şoku veren bir skill. 30 saniyede bir aktif olabilsin. kendine koruma kalkanı yapsın 1 dakikada bir 10 saniyeliğine. Tüm düşmanları donduran skill olsun 30 saniyede bir aktif olabilsin. bunlar mana harcasın. mana barımız olsun. düşmanlardan mana potu düşsün. her öldürüdğümüz düşman 1 nama puanı versin. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
/****
* Plugins
****/
var tween = LK.import("@upit/tween.v1");
var storage = LK.import("@upit/storage.v1");
/****
* Classes
****/
var Bullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
self.velocityX = 0;
self.velocityY = 0;
self.damage = 10;
self.lifetime = 120; // frames
self.update = function () {
self.x += self.velocityX * gameSpeed;
self.y += self.velocityY * gameSpeed;
self.lifetime -= gameSpeed;
// Check collision with enemies
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
if (self.intersects(enemy)) {
var finalDamage = self.damage * (skillBonuses.damageMultiplier + skillBonuses.relicDamage);
// Apply critical hit
if (Math.random() < skillBonuses.critChance) {
finalDamage *= 2;
LK.effects.flashObject(enemy, 0xffff00, 200);
}
enemy.takeDamage(finalDamage);
// Vampire healing from relics
if (skillBonuses.vampireHealing > 0) {
var healAmount = finalDamage * skillBonuses.vampireHealing;
hero.health = Math.min(hero.maxHealth, hero.health + healAmount);
}
self.destroy();
var index = bullets.indexOf(self);
if (index > -1) {
bullets.splice(index, 1);
}
return;
}
}
// Remove if lifetime expired or off screen
if (self.lifetime <= 0 || self.x < -100 || self.x > 2148 || self.y < -100 || self.y > 2832) {
self.destroy();
var index = bullets.indexOf(self);
if (index > -1) {
bullets.splice(index, 1);
}
}
};
return self;
});
var ChargeBoss = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('chargeBoss', {
anchorX: 0.5,
anchorY: 0.5
});
bossGraphics.tint = 0xDC143C;
self.health = 350;
self.maxHealth = 350;
self.damage = 30;
self.speed = 0.5;
self.goldReward = 250;
self.chargeTimer = 0;
self.chargeCooldown = 360; // 6 seconds
self.isCharging = false;
self.chargeDuration = 0;
self.chargeMaxDuration = 90; // 1.5 seconds
self.chargeTarget = {
x: 0,
y: 0
};
self.chargeSpeed = 15;
self.update = function () {
if (self.frozenTimer > 0) {
self.frozenTimer -= gameSpeed;
if (self.frozenTimer <= 0) {
self.speed = self.originalSpeed;
tween(self, {
tint: 0xDC143C
}, {
duration: 200
});
}
return;
}
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
self.chargeTimer -= gameSpeed;
if (!self.isCharging) {
// Normal movement
if (distance > 0) {
self.x += dx / distance * self.speed * gameSpeed;
self.y += dy / distance * self.speed * gameSpeed;
}
// Charge attack when ready
if (self.chargeTimer <= 0 && distance <= 500) {
self.isCharging = true;
self.chargeDuration = self.chargeMaxDuration;
self.chargeTarget.x = hero.x;
self.chargeTarget.y = hero.y;
self.chargeTimer = self.chargeCooldown;
// Visual charge effect
tween(self, {
tint: 0xFF0000
}, {
duration: 100
});
LK.getSound('bossCharge').play();
}
} else {
// Charge movement
self.chargeDuration -= gameSpeed;
var chargeDx = self.chargeTarget.x - self.x;
var chargeDy = self.chargeTarget.y - self.y;
var chargeDistance = Math.sqrt(chargeDx * chargeDx + chargeDy * chargeDy);
if (chargeDistance > 0) {
self.x += chargeDx / chargeDistance * self.chargeSpeed * gameSpeed;
self.y += chargeDy / chargeDistance * self.chargeSpeed * gameSpeed;
}
// Check collision during charge
var heroDistance = Math.sqrt(dx * dx + dy * dy);
if (heroDistance < 80) {
hero.takeDamage(self.damage * 1.5);
LK.effects.flashScreen(0xFF0000, 400);
}
if (self.chargeDuration <= 0) {
self.isCharging = false;
// Reset color
tween(self, {
tint: 0xDC143C
}, {
duration: 300
});
}
}
// Normal collision when not charging
if (!self.isCharging && distance < 60) {
hero.takeDamage(self.damage);
self.destroy();
var index = enemies.indexOf(self);
if (index > -1) {
enemies.splice(index, 1);
}
}
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.die();
}
};
self.die = function () {
totalEnemyKills++;
storage.totalEnemyKills = totalEnemyKills;
// Better loot drops
for (var i = 0; i < 4; i++) {
var gold = new Gold();
gold.x = self.x + (Math.random() - 0.5) * 130;
gold.y = self.y + (Math.random() - 0.5) * 130;
gold.value = self.goldReward / 4;
goldItems.push(gold);
game.addChild(gold);
}
// Guaranteed equipment drop
var equipment = new Equipment();
equipment.x = self.x;
equipment.y = self.y;
equipmentItems.push(equipment);
game.addChild(equipment);
// High chance for exclusive relic
if (Math.random() < 0.6) {
var exclusiveRelics = ['ironShield', 'crystalCore', 'vampireTooth'];
var randomType = exclusiveRelics[Math.floor(Math.random() * exclusiveRelics.length)];
var relic = new Relic(randomType);
relic.x = self.x;
relic.y = self.y;
relicItems.push(relic);
game.addChild(relic);
}
skillPoints += 15;
playerMana = Math.min(maxMana, playerMana + 30);
self.destroy();
var index = enemies.indexOf(self);
if (index > -1) {
enemies.splice(index, 1);
}
LK.getSound('enemyHit').play();
};
return self;
});
var Enemy = Container.expand(function (type) {
var self = Container.call(this);
type = type || 'enemy1';
self.type = type;
// Set different assets and colors based on type
var assetName = 'enemy1';
var enemyColor = 0xff6b6b;
if (type === 'enemy1') {
assetName = 'enemy1';
enemyColor = 0xff6b6b;
} else if (type === 'enemy2') {
assetName = 'enemy2';
enemyColor = 0xff9f43;
} else if (type === 'enemy3') {
assetName = 'enemy3';
enemyColor = 0x8b5cf6;
} else if (type === 'enemy4') {
assetName = 'enemy4';
enemyColor = 0xf59e0b;
} else if (type === 'enemy5') {
assetName = 'enemy5';
enemyColor = 0x10b981;
} else if (type === 'enemy6') {
assetName = 'enemy1';
enemyColor = 0xef4444;
} else if (type === 'enemy7') {
assetName = 'enemy1';
enemyColor = 0x06b6d4;
}
var enemyGraphics = self.attachAsset(assetName, {
anchorX: 0.5,
anchorY: 0.5
});
enemyGraphics.tint = enemyColor;
// Set stats based on type
if (type === 'enemy1') {
// Basic enemy
self.health = 10;
self.maxHealth = 10;
self.damage = 5;
self.speed = 1;
self.goldReward = 5;
} else if (type === 'enemy2') {
// Fast enemy
self.health = 8;
self.maxHealth = 8;
self.damage = 4;
self.speed = 2.5;
self.goldReward = 8;
} else if (type === 'enemy3') {
// Tank enemy
self.health = 40;
self.maxHealth = 40;
self.damage = 8;
self.speed = 0.7;
self.goldReward = 15;
} else if (type === 'enemy4') {
// Boss enemy
self.health = 100;
self.maxHealth = 100;
self.damage = 15;
self.speed = 1.2;
self.goldReward = 50;
enemyGraphics.scaleX = 1.5;
enemyGraphics.scaleY = 1.5;
} else if (type === 'enemy5') {
// Archer enemy
self.health = 15;
self.maxHealth = 15;
self.damage = 6;
self.speed = 0.8;
self.goldReward = 12;
self.range = 300;
self.shootTimer = 0;
self.shootCooldown = 90;
} else if (type === 'enemy6') {
// Exploder enemy
self.health = 8;
self.maxHealth = 8;
self.damage = 20;
self.speed = 1.8;
self.goldReward = 10;
self.explodeRadius = 120;
} else if (type === 'enemy7') {
// Healer enemy
self.health = 25;
self.maxHealth = 25;
self.damage = 2;
self.speed = 0.9;
self.goldReward = 18;
self.healRange = 150;
self.healAmount = 3;
self.healCooldown = 120;
self.healTimer = 0;
}
self.update = function () {
// Handle frozen state
if (self.frozenTimer > 0) {
self.frozenTimer -= gameSpeed;
if (self.frozenTimer <= 0) {
self.speed = self.originalSpeed;
tween(self, {
tint: 0xffffff
}, {
duration: 200
});
}
return;
}
// Move towards hero
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Special behavior for archer enemies (enemy5)
if (self.type === 'enemy5') {
self.shootTimer -= gameSpeed;
// Keep distance and shoot
if (distance > self.range) {
self.x += dx / distance * self.speed * gameSpeed;
self.y += dy / distance * self.speed * gameSpeed;
}
// Shoot at hero when in range
if (distance <= self.range && self.shootTimer <= 0) {
var enemyBullet = new EnemyBullet();
enemyBullet.x = self.x;
enemyBullet.y = self.y;
enemyBullet.velocityX = dx / distance * 4;
enemyBullet.velocityY = dy / distance * 4;
enemyBullet.damage = self.damage;
enemyBullets.push(enemyBullet);
game.addChild(enemyBullet);
self.shootTimer = self.shootCooldown;
}
} else if (self.type === 'enemy7') {
// Healer behavior - heal nearby enemies
self.healTimer -= gameSpeed;
if (self.healTimer <= 0) {
for (var i = 0; i < enemies.length; i++) {
var ally = enemies[i];
if (ally !== self) {
var healDx = ally.x - self.x;
var healDy = ally.y - self.y;
var healDistance = Math.sqrt(healDx * healDx + healDy * healDy);
if (healDistance <= self.healRange && ally.health < ally.maxHealth) {
ally.health = Math.min(ally.maxHealth, ally.health + self.healAmount);
// Visual effect for healing
LK.effects.flashObject(ally, 0x00ff00, 300);
self.healTimer = self.healCooldown;
break;
}
}
}
}
// Move towards hero normally
if (distance > 0) {
self.x += dx / distance * self.speed * gameSpeed;
self.y += dy / distance * self.speed * gameSpeed;
}
} else if (self.type === 'enemy6') {
// Exploder behavior - explode when close to hero
if (distance <= self.explodeRadius) {
// Explode and damage hero
hero.takeDamage(self.damage);
// Visual explosion effect
LK.effects.flashScreen(0xff4444, 500);
self.destroy();
var index = enemies.indexOf(self);
if (index > -1) {
enemies.splice(index, 1);
}
return;
}
// Move towards hero faster
if (distance > 0) {
self.x += dx / distance * self.speed * gameSpeed;
self.y += dy / distance * self.speed * gameSpeed;
}
} else {
// Normal movement for other enemy types
if (distance > 0) {
self.x += dx / distance * self.speed * gameSpeed;
self.y += dy / distance * self.speed * gameSpeed;
}
}
// Check collision with hero (except for archer and exploder)
if (distance < 50 && self.type !== 'enemy5' && self.type !== 'enemy6') {
hero.takeDamage(self.damage);
self.destroy();
var index = enemies.indexOf(self);
if (index > -1) {
enemies.splice(index, 1);
}
}
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.die();
}
};
self.die = function () {
// Track kills for achievements
totalEnemyKills++;
storage.totalEnemyKills = totalEnemyKills;
// Drop gold
var gold = new Gold();
gold.x = self.x;
gold.y = self.y;
gold.value = self.goldReward;
goldItems.push(gold);
game.addChild(gold);
// Drop health potion (10% chance)
if (Math.random() < 0.1) {
var healthPotion = new HealthPotion();
healthPotion.x = self.x;
healthPotion.y = self.y;
healthPotions.push(healthPotion);
game.addChild(healthPotion);
}
// Drop mana potion (15% chance)
if (Math.random() < 0.15) {
var manaPotion = new ManaPotion();
manaPotion.x = self.x;
manaPotion.y = self.y;
manaPotions.push(manaPotion);
game.addChild(manaPotion);
}
// Give 1 mana point per kill
playerMana = Math.min(maxMana, playerMana + 1);
// Give skill points based on enemy type
var pointsToGive = 1;
if (self.type === 'enemy4') pointsToGive = 5; // Boss
else if (self.type === 'enemy3') pointsToGive = 3; // Tank
else if (self.type === 'enemy7') pointsToGive = 2; // Healer
skillPoints += pointsToGive;
// Drop equipment (15% chance for boss, 8% for tank, 5% for others)
var equipmentChance = 0.05;
if (self.type === 'enemy4') {
equipmentChance = 0.15;
} else if (self.type === 'enemy3') {
equipmentChance = 0.08;
}
if (Math.random() < equipmentChance) {
var equipment = new Equipment();
equipment.x = self.x;
equipment.y = self.y;
equipmentItems.push(equipment);
game.addChild(equipment);
}
// Drop relics (rare chance)
var relicChance = 0.03;
if (self.type === 'enemy4') {
relicChance = 0.15; // Boss
} else if (self.type === 'enemy3') {
relicChance = 0.08; // Tank
} else if (self.type === 'enemy7') {
relicChance = 0.05; // Healer
}
if (Math.random() < relicChance) {
var relicTypes = ['vampireTooth', 'clockwork', 'goldenFeather', 'crystalCore', 'ironShield', 'luckyCharm'];
var randomType = relicTypes[Math.floor(Math.random() * relicTypes.length)];
var relic = new Relic(randomType);
relic.x = self.x;
relic.y = self.y;
relicItems.push(relic);
game.addChild(relic);
}
self.destroy();
var index = enemies.indexOf(self);
if (index > -1) {
enemies.splice(index, 1);
}
LK.getSound('enemyHit').play();
};
return self;
});
var EnemyBullet = Container.expand(function () {
var self = Container.call(this);
var bulletGraphics = self.attachAsset('bullet', {
anchorX: 0.5,
anchorY: 0.5
});
bulletGraphics.tint = 0xff4444; // Red tint for enemy bullets
self.velocityX = 0;
self.velocityY = 0;
self.damage = 5;
self.lifetime = 120;
self.update = function () {
self.x += self.velocityX * gameSpeed;
self.y += self.velocityY * gameSpeed;
self.lifetime -= gameSpeed;
// Check collision with hero
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 40) {
hero.takeDamage(self.damage);
self.destroy();
var index = enemyBullets.indexOf(self);
if (index > -1) {
enemyBullets.splice(index, 1);
}
return;
}
// Remove if lifetime expired or off screen
if (self.lifetime <= 0 || self.x < -100 || self.x > 2148 || self.y < -100 || self.y > 2832) {
self.destroy();
var index = enemyBullets.indexOf(self);
if (index > -1) {
enemyBullets.splice(index, 1);
}
}
};
return self;
});
var Equipment = Container.expand(function () {
var self = Container.call(this);
var equipmentGraphics = self.attachAsset('equipment', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = 'sword';
self.level = 0;
self.magnetRange = 20000;
self.magnetSpeed = 3;
self.update = function () {
// Magnetic pull towards hero
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < self.magnetRange * skillBonuses.magnetMultiplier) {
self.x += dx / distance * self.magnetSpeed * gameSpeed;
self.y += dy / distance * self.magnetSpeed * gameSpeed;
}
// Automatic collection when close
if (distance < 60) {
playerEquipment.push(self.type);
totalEquipmentCollected++;
storage.totalEquipmentCollected = totalEquipmentCollected;
self.destroy();
var index = equipmentItems.indexOf(self);
if (index > -1) {
equipmentItems.splice(index, 1);
}
LK.getSound('pickup').play();
}
};
return self;
});
var Gold = Container.expand(function () {
var self = Container.call(this);
var goldGraphics = self.attachAsset('goldCoin', {
anchorX: 0.5,
anchorY: 0.5
});
self.value = 5;
self.magnetRange = 2500;
self.magnetSpeed = 4;
self.update = function () {
// Magnetic pull towards hero
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < self.magnetRange * (skillBonuses.magnetMultiplier + skillBonuses.relicGoldRange)) {
self.x += dx / distance * self.magnetSpeed * gameSpeed;
self.y += dy / distance * self.magnetSpeed * gameSpeed;
}
// Automatic collection when close
if (distance < 60) {
var goldAmount = Math.floor(self.value * (skillBonuses.goldMultiplier + skillBonuses.relicGoldGain) * (1 + prestigeBonuses.goldIncome));
playerGold += goldAmount;
totalGoldCollected += goldAmount;
storage.totalGoldCollected = totalGoldCollected;
goldText.setText('Gold: ' + playerGold);
self.destroy();
var index = goldItems.indexOf(self);
if (index > -1) {
goldItems.splice(index, 1);
}
LK.getSound('pickup').play();
}
};
return self;
});
var HealthPotion = Container.expand(function () {
var self = Container.call(this);
var potionGraphics = self.attachAsset('healthPotion', {
anchorX: 0.5,
anchorY: 0.5
});
self.healAmount = 20;
self.magnetRange = 2000;
self.magnetSpeed = 4;
self.update = function () {
// Magnetic pull towards hero
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < self.magnetRange * skillBonuses.magnetMultiplier) {
self.x += dx / distance * self.magnetSpeed * gameSpeed;
self.y += dy / distance * self.magnetSpeed * gameSpeed;
}
// Automatic collection when close
if (distance < 60) {
hero.health = Math.min(hero.maxHealth, hero.health + self.healAmount);
self.destroy();
var index = healthPotions.indexOf(self);
if (index > -1) {
healthPotions.splice(index, 1);
}
LK.getSound('pickup').play();
}
};
return self;
});
var Hero = Container.expand(function () {
var self = Container.call(this);
var heroGraphics = self.attachAsset('hero', {
anchorX: 0.5,
anchorY: 0.5
});
var rangeCircle = self.attachAsset('rangeCircle', {
anchorX: 0.5,
anchorY: 0.5
});
rangeCircle.alpha = 0.1;
rangeCircle.scaleX = 0.5;
rangeCircle.scaleY = 0.5;
self.rangeCircle = rangeCircle;
var shieldEffect = self.attachAsset('shieldEffect', {
anchorX: 0.5,
anchorY: 0.5
});
shieldEffect.alpha = 0;
self.shieldEffect = shieldEffect;
self.health = 100;
self.maxHealth = 100;
self.damage = 40;
self.attackSpeed = 60; // frames between shots
self.range = 1000;
self.shootTimer = 0;
self.target = null;
self.update = function () {
self.shootTimer -= gameSpeed;
// Apply health regeneration
if (skillBonuses.healthRegen > 0 && LK.ticks % 60 === 0) {
self.health = Math.min(self.maxHealth, self.health + skillBonuses.healthRegen);
}
// Update range circle scale
var scale = self.range / 1200;
self.rangeCircle.scaleX = scale * 0.5;
self.rangeCircle.scaleY = scale * 0.5;
// Find nearest enemy in range
var nearestEnemy = null;
var nearestDistance = Infinity;
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= self.range && distance < nearestDistance) {
nearestDistance = distance;
nearestEnemy = enemy;
}
}
self.target = nearestEnemy;
// Shoot at target
if (self.target && self.shootTimer <= 0) {
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Calculate rotation angle and smoothly rotate hero towards target
var targetAngle = Math.atan2(dy, dx);
tween(heroGraphics, {
rotation: targetAngle
}, {
duration: 100,
easing: tween.easeOut
});
bullet.velocityX = dx / distance * 8;
bullet.velocityY = dy / distance * 8;
bullet.damage = self.damage;
bullets.push(bullet);
game.addChild(bullet);
self.shootTimer = self.attackSpeed / (skillBonuses.attackSpeedMultiplier + skillBonuses.relicAttackSpeed);
LK.getSound('shoot').play();
}
};
self.takeDamage = function (damage) {
if (shieldActive) {
// Shield blocks damage
return;
}
var finalDamage = damage * (1 - (skillBonuses.damageReduction + skillBonuses.relicArmor));
self.health -= finalDamage;
if (self.health <= 0) {
LK.showGameOver();
}
};
return self;
});
var JumpBoss = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('jumpBoss', {
anchorX: 0.5,
anchorY: 0.5
});
bossGraphics.tint = 0x8B0000;
self.health = 300;
self.maxHealth = 300;
self.damage = 25;
self.speed = 0.8;
self.goldReward = 200;
self.jumpCooldown = 0;
self.jumpMaxCooldown = 180; // 3 seconds
self.isJumping = false;
self.jumpTarget = {
x: 0,
y: 0
};
self.jumpDuration = 0;
self.jumpMaxDuration = 30; // 0.5 seconds
self.update = function () {
if (self.frozenTimer > 0) {
self.frozenTimer -= gameSpeed;
if (self.frozenTimer <= 0) {
self.speed = self.originalSpeed;
tween(self, {
tint: 0x8B0000
}, {
duration: 200
});
}
return;
}
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
self.jumpCooldown -= gameSpeed;
if (!self.isJumping) {
// Normal movement
if (distance > 0) {
self.x += dx / distance * self.speed * gameSpeed;
self.y += dy / distance * self.speed * gameSpeed;
}
// Jump attack when in range and cooldown ready
if (distance <= 400 && self.jumpCooldown <= 0) {
self.isJumping = true;
self.jumpDuration = self.jumpMaxDuration;
self.jumpTarget.x = hero.x;
self.jumpTarget.y = hero.y;
self.jumpCooldown = self.jumpMaxCooldown;
// Visual jump effect
tween(self, {
scaleX: 1.5,
scaleY: 1.5
}, {
duration: 150,
easing: tween.easeOut
});
LK.getSound('bossJump').play();
}
} else {
// Jump movement
self.jumpDuration -= gameSpeed;
var jumpProgress = 1 - self.jumpDuration / self.jumpMaxDuration;
var jumpDx = self.jumpTarget.x - self.x;
var jumpDy = self.jumpTarget.y - self.y;
var jumpDistance = Math.sqrt(jumpDx * jumpDx + jumpDy * jumpDy);
if (jumpDistance > 0) {
self.x += jumpDx / jumpDistance * 12 * gameSpeed;
self.y += jumpDy / jumpDistance * 12 * gameSpeed;
}
if (self.jumpDuration <= 0) {
self.isJumping = false;
// Landing damage
var landingDx = hero.x - self.x;
var landingDy = hero.y - self.y;
var landingDistance = Math.sqrt(landingDx * landingDx + landingDy * landingDy);
if (landingDistance <= 100) {
hero.takeDamage(self.damage * 2);
}
// Reset scale
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
// Screen shake effect
LK.effects.flashScreen(0xFF4444, 300);
}
}
// Normal collision when not jumping
if (!self.isJumping && distance < 60) {
hero.takeDamage(self.damage);
self.destroy();
var index = enemies.indexOf(self);
if (index > -1) {
enemies.splice(index, 1);
}
}
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.die();
}
};
self.die = function () {
totalEnemyKills++;
storage.totalEnemyKills = totalEnemyKills;
// Better loot drops
for (var i = 0; i < 3; i++) {
var gold = new Gold();
gold.x = self.x + (Math.random() - 0.5) * 100;
gold.y = self.y + (Math.random() - 0.5) * 100;
gold.value = self.goldReward / 3;
goldItems.push(gold);
game.addChild(gold);
}
// Guaranteed equipment drop
var equipment = new Equipment();
equipment.x = self.x;
equipment.y = self.y;
equipmentItems.push(equipment);
game.addChild(equipment);
// High chance for exclusive relic
if (Math.random() < 0.5) {
var exclusiveRelics = ['vampireTooth', 'crystalCore', 'ironShield'];
var randomType = exclusiveRelics[Math.floor(Math.random() * exclusiveRelics.length)];
var relic = new Relic(randomType);
relic.x = self.x;
relic.y = self.y;
relicItems.push(relic);
game.addChild(relic);
}
skillPoints += 10;
playerMana = Math.min(maxMana, playerMana + 20);
self.destroy();
var index = enemies.indexOf(self);
if (index > -1) {
enemies.splice(index, 1);
}
LK.getSound('enemyHit').play();
};
return self;
});
var ManaPotion = Container.expand(function () {
var self = Container.call(this);
var potionGraphics = self.attachAsset('manaPotion', {
anchorX: 0.5,
anchorY: 0.5
});
self.manaAmount = 20;
self.magnetRange = 2000;
self.magnetSpeed = 4;
self.update = function () {
// Magnetic pull towards hero
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < self.magnetRange * skillBonuses.magnetMultiplier) {
self.x += dx / distance * self.magnetSpeed * gameSpeed;
self.y += dy / distance * self.magnetSpeed * gameSpeed;
}
// Automatic collection when close
if (distance < 60) {
playerMana = Math.min(maxMana, playerMana + self.manaAmount);
self.destroy();
var index = manaPotions.indexOf(self);
if (index > -1) {
manaPotions.splice(index, 1);
}
LK.getSound('pickup').play();
}
};
// Lightning skill button handler
lightningBtn.down = function () {
if (playerMana >= lightningManaCost && lightningCooldown <= 0) {
playerMana -= lightningManaCost;
lightningCooldown = lightningMaxCooldown;
// Damage all enemies on screen
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
enemy.takeDamage(60);
// Lightning effect
tween(enemy, {
tint: 0xffff00
}, {
duration: 100,
onFinish: function onFinish() {
tween(enemy, {
tint: 0xffffff
}, {
duration: 100
});
}
});
}
LK.getSound('lightning').play();
LK.effects.flashScreen(0xffff00, 200);
}
};
// Freeze skill button handler
freezeBtn.down = function () {
if (playerMana >= freezeManaCost && freezeCooldown <= 0) {
playerMana -= freezeManaCost;
freezeCooldown = freezeMaxCooldown;
// Freeze all enemies for 5 seconds
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
enemy.originalSpeed = enemy.speed;
enemy.speed = 0;
enemy.frozenTimer = 300; // 5 seconds
tween(enemy, {
tint: 0x00ffff
}, {
duration: 200
});
}
LK.getSound('freeze').play();
LK.effects.flashScreen(0x00ffff, 300);
}
};
// Shield skill button handler
shieldBtn.down = function () {
if (playerMana >= shieldManaCost && shieldCooldown <= 0) {
playerMana -= shieldManaCost;
shieldCooldown = shieldMaxCooldown;
shieldActive = true;
shieldDuration = shieldMaxDuration;
// Show shield effect
hero.shieldEffect.alpha = 0.6;
tween(hero.shieldEffect, {
scaleX: 1.2,
scaleY: 1.2
}, {
duration: 300
});
LK.getSound('shield').play();
}
};
return self;
});
var PoisonBoss = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('poisonBoss', {
anchorX: 0.5,
anchorY: 0.5
});
bossGraphics.tint = 0x228B22;
self.health = 250;
self.maxHealth = 250;
self.damage = 15;
self.speed = 1.2;
self.goldReward = 180;
self.poisonTimer = 0;
self.poisonCooldown = 240; // 4 seconds
self.poisonDuration = 0;
self.poisonMaxDuration = 600; // 10 seconds
self.update = function () {
if (self.frozenTimer > 0) {
self.frozenTimer -= gameSpeed;
if (self.frozenTimer <= 0) {
self.speed = self.originalSpeed;
tween(self, {
tint: 0x228B22
}, {
duration: 200
});
}
return;
}
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Move towards hero
if (distance > 0) {
self.x += dx / distance * self.speed * gameSpeed;
self.y += dy / distance * self.speed * gameSpeed;
}
self.poisonTimer -= gameSpeed;
// Poison attack
if (distance <= 200 && self.poisonTimer <= 0) {
self.poisonTimer = self.poisonCooldown;
heroPoisonDuration = self.poisonMaxDuration;
// Visual poison effect
tween(self, {
tint: 0x00FF00
}, {
duration: 300,
onFinish: function onFinish() {
tween(self, {
tint: 0x228B22
}, {
duration: 200
});
}
});
LK.effects.flashScreen(0x00FF00, 500);
}
// Normal collision
if (distance < 60) {
hero.takeDamage(self.damage);
self.destroy();
var index = enemies.indexOf(self);
if (index > -1) {
enemies.splice(index, 1);
}
}
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.die();
}
};
self.die = function () {
totalEnemyKills++;
storage.totalEnemyKills = totalEnemyKills;
// Better loot drops
for (var i = 0; i < 3; i++) {
var gold = new Gold();
gold.x = self.x + (Math.random() - 0.5) * 100;
gold.y = self.y + (Math.random() - 0.5) * 100;
gold.value = self.goldReward / 3;
goldItems.push(gold);
game.addChild(gold);
}
// Guaranteed equipment drop
var equipment = new Equipment();
equipment.x = self.x;
equipment.y = self.y;
equipmentItems.push(equipment);
game.addChild(equipment);
// High chance for exclusive relic
if (Math.random() < 0.5) {
var exclusiveRelics = ['vampireTooth', 'goldenFeather', 'luckyCharm'];
var randomType = exclusiveRelics[Math.floor(Math.random() * exclusiveRelics.length)];
var relic = new Relic(randomType);
relic.x = self.x;
relic.y = self.y;
relicItems.push(relic);
game.addChild(relic);
}
skillPoints += 10;
playerMana = Math.min(maxMana, playerMana + 20);
self.destroy();
var index = enemies.indexOf(self);
if (index > -1) {
enemies.splice(index, 1);
}
LK.getSound('enemyHit').play();
};
return self;
});
var Relic = Container.expand(function (relicType) {
var self = Container.call(this);
var relicGraphics = self.attachAsset('relic', {
anchorX: 0.5,
anchorY: 0.5
});
self.relicType = relicType || 'vampireTooth';
self.magnetRange = 1500;
self.magnetSpeed = 3;
// Set relic properties and colors based on type
if (relicType === 'vampireTooth') {
relicGraphics.tint = 0x8B0000;
self.name = 'Vampire Tooth';
self.description = 'Heal 5% of damage dealt';
self.bonus = 0.05;
} else if (relicType === 'clockwork') {
relicGraphics.tint = 0xFFD700;
self.name = 'Clockwork';
self.description = '+10% attack speed';
self.bonus = 0.10;
} else if (relicType === 'goldenFeather') {
relicGraphics.tint = 0xFFA500;
self.name = 'Golden Feather';
self.description = '+20% gold pickup range';
self.bonus = 0.20;
} else if (relicType === 'crystalCore') {
relicGraphics.tint = 0x4169E1;
self.name = 'Crystal Core';
self.description = '+15% damage';
self.bonus = 0.15;
} else if (relicType === 'ironShield') {
relicGraphics.tint = 0x708090;
self.name = 'Iron Shield';
self.description = '+10% damage reduction';
self.bonus = 0.10;
} else if (relicType === 'luckyCharm') {
relicGraphics.tint = 0x32CD32;
self.name = 'Lucky Charm';
self.description = '+25% gold gain';
self.bonus = 0.25;
}
self.update = function () {
// Magnetic pull towards hero
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < self.magnetRange) {
self.x += dx / distance * self.magnetSpeed * gameSpeed;
self.y += dy / distance * self.magnetSpeed * gameSpeed;
}
// Automatic collection when close
if (distance < 60) {
playerRelics.push(self);
totalRelicsCollected++;
storage.totalRelicsCollected = totalRelicsCollected;
applyRelicBonus(self);
self.destroy();
var index = relicItems.indexOf(self);
if (index > -1) {
relicItems.splice(index, 1);
}
LK.getSound('pickup').play();
}
};
return self;
});
var SummonBoss = Container.expand(function () {
var self = Container.call(this);
var bossGraphics = self.attachAsset('summonBoss', {
anchorX: 0.5,
anchorY: 0.5
});
bossGraphics.tint = 0x4B0082;
self.health = 200;
self.maxHealth = 200;
self.damage = 20;
self.speed = 0.6;
self.goldReward = 220;
self.summonTimer = 0;
self.summonCooldown = 300; // 5 seconds
self.maxMinions = 3;
self.update = function () {
if (self.frozenTimer > 0) {
self.frozenTimer -= gameSpeed;
if (self.frozenTimer <= 0) {
self.speed = self.originalSpeed;
tween(self, {
tint: 0x4B0082
}, {
duration: 200
});
}
return;
}
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Move towards hero slowly
if (distance > 150) {
self.x += dx / distance * self.speed * gameSpeed;
self.y += dy / distance * self.speed * gameSpeed;
}
self.summonTimer -= gameSpeed;
// Summon minions
if (self.summonTimer <= 0) {
var currentMinions = 0;
for (var i = 0; i < enemies.length; i++) {
if (enemies[i].isSummon) {
currentMinions++;
}
}
if (currentMinions < self.maxMinions) {
self.summonTimer = self.summonCooldown;
// Summon 1-2 minions
var minionsToSummon = Math.floor(Math.random() * 2) + 1;
for (var j = 0; j < minionsToSummon; j++) {
var minion = new Enemy('enemy1');
minion.isSummon = true;
minion.x = self.x + (Math.random() - 0.5) * 200;
minion.y = self.y + (Math.random() - 0.5) * 200;
minion.health = 15;
minion.maxHealth = 15;
minion.speed = 1.5;
minion.goldReward = 8;
enemies.push(minion);
game.addChild(minion);
}
// Visual summoning effect
tween(self, {
scaleX: 1.3,
scaleY: 1.3
}, {
duration: 200,
onFinish: function onFinish() {
tween(self, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
});
LK.effects.flashScreen(0x4B0082, 400);
}
}
// Normal collision
if (distance < 60) {
hero.takeDamage(self.damage);
self.destroy();
var index = enemies.indexOf(self);
if (index > -1) {
enemies.splice(index, 1);
}
}
};
self.takeDamage = function (damage) {
self.health -= damage;
if (self.health <= 0) {
self.die();
}
};
self.die = function () {
totalEnemyKills++;
storage.totalEnemyKills = totalEnemyKills;
// Better loot drops
for (var i = 0; i < 4; i++) {
var gold = new Gold();
gold.x = self.x + (Math.random() - 0.5) * 120;
gold.y = self.y + (Math.random() - 0.5) * 120;
gold.value = self.goldReward / 4;
goldItems.push(gold);
game.addChild(gold);
}
// Guaranteed equipment drop
var equipment = new Equipment();
equipment.x = self.x;
equipment.y = self.y;
equipmentItems.push(equipment);
game.addChild(equipment);
// High chance for exclusive relic
if (Math.random() < 0.6) {
var exclusiveRelics = ['clockwork', 'crystalCore', 'luckyCharm'];
var randomType = exclusiveRelics[Math.floor(Math.random() * exclusiveRelics.length)];
var relic = new Relic(randomType);
relic.x = self.x;
relic.y = self.y;
relicItems.push(relic);
game.addChild(relic);
}
skillPoints += 12;
playerMana = Math.min(maxMana, playerMana + 25);
self.destroy();
var index = enemies.indexOf(self);
if (index > -1) {
enemies.splice(index, 1);
}
LK.getSound('enemyHit').play();
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x0d1117
});
/****
* Game Code
****/
// Game variables
LK.getSound('metin2likethat').play();
var hero;
var enemies = [];
var bullets = [];
var enemyBullets = [];
var goldItems = [];
var equipmentItems = [];
var healthPotions = [];
var playerGold = 0;
var playerEquipment = [];
var playerRelics = [];
var relicItems = [];
var waveNumber = 1;
var enemySpawnTimer = 0;
var enemiesPerWave = 3;
// Boss system variables
var bossSpawned = false;
var bossWaveInterval = 5; // Boss every 5 waves
var heroPoisonDuration = 0;
var poisonDamageTimer = 0;
// Biome system variables
var currentBiome = 'forest';
var biomeWaveInterval = 10; // Change biome every 10 waves
var biomeEffectTimer = 0;
var biomeEffects = [];
var biomeColors = {
forest: 0x228B22,
cave: 0x2F4F4F,
volcano: 0x8B0000,
ice: 0x87CEEB
};
// Prestige system
var prestigeLevel = storage.prestigeLevel || 0;
var prestigeUnlockWave = 15; // Minimum wave to unlock prestige
var prestigeBonuses = {
goldIncome: storage.prestigeGoldIncome || 0,
manaCapacity: storage.prestigeManaCapacity || 0,
startingGold: storage.prestigeStartingGold || 0,
experienceGain: storage.prestigeExperienceGain || 0
};
// Daily reward system
var dailyRewards = [{
type: 'gold',
amount: 100,
claimed: false
}, {
type: 'gold',
amount: 200,
claimed: false
}, {
type: 'gold',
amount: 300,
claimed: false
}, {
type: 'skillPoints',
amount: 5,
claimed: false
}, {
type: 'gold',
amount: 500,
claimed: false
}, {
type: 'mana',
amount: 50,
claimed: false
}, {
type: 'gold',
amount: 1000,
claimed: false
}];
// Achievement system
var achievements = {
wave10: {
name: 'Wave Master',
desc: 'Reach wave 10',
target: 10,
current: 0,
completed: false,
reward: {
type: 'gold',
amount: 500
}
},
kills500: {
name: 'Exterminator',
desc: 'Kill 500 enemies',
target: 500,
current: 0,
completed: false,
reward: {
type: 'skillPoints',
amount: 10
}
},
equipment100: {
name: 'Collector',
desc: 'Collect 100 equipment',
target: 100,
current: 0,
completed: false,
reward: {
type: 'gold',
amount: 300
}
},
gold5000: {
name: 'Wealthy',
desc: 'Collect 5000 gold',
target: 5000,
current: 0,
completed: false,
reward: {
type: 'mana',
amount: 100
}
},
relics10: {
name: 'Relic Hunter',
desc: 'Collect 10 relics',
target: 10,
current: 0,
completed: false,
reward: {
type: 'skillPoints',
amount: 5
}
}
};
var totalEnemyKills = storage.totalEnemyKills || 0;
var totalGoldCollected = storage.totalGoldCollected || 0;
var totalEquipmentCollected = storage.totalEquipmentCollected || 0;
var totalRelicsCollected = storage.totalRelicsCollected || 0;
var lastLoginDate = storage.lastLoginDate || '';
var claimedRewards = storage.claimedRewards || [];
var completedAchievements = storage.completedAchievements || [];
// UI Elements
var goldText = new Text2('Gold: 0', {
size: 40,
fill: '#FFD700'
});
goldText.anchor.set(0, 0);
goldText.x = 120;
goldText.y = 50;
LK.gui.topLeft.addChild(goldText);
var waveText = new Text2('Wave: 1', {
size: 40,
fill: '#FFFFFF'
});
waveText.anchor.set(0.5, 0);
waveText.x = 0;
waveText.y = 50;
LK.gui.top.addChild(waveText);
var healthText = new Text2('Health: 100', {
size: 40,
fill: '#FF0000'
});
healthText.anchor.set(1, 0);
healthText.x = 0;
healthText.y = 50;
LK.gui.topRight.addChild(healthText);
// Speed button
var speedBtn = new Text2('Speed: 1x', {
size: 35,
fill: '#00FF00'
});
speedBtn.anchor.set(1, 0);
speedBtn.x = 0;
speedBtn.y = 100;
LK.gui.topRight.addChild(speedBtn);
// Upgrade buttons
var damageUpgradeBtn = new Text2('Damage +10 (Cost: 50)', {
size: 35,
fill: '#FFFFFF'
});
damageUpgradeBtn.anchor.set(0.5, 1);
damageUpgradeBtn.x = 0;
damageUpgradeBtn.y = -200;
LK.gui.bottom.addChild(damageUpgradeBtn);
var speedUpgradeBtn = new Text2('Speed +10 (Cost: 75)', {
size: 35,
fill: '#FFFFFF'
});
speedUpgradeBtn.anchor.set(0.5, 1);
speedUpgradeBtn.x = 0;
speedUpgradeBtn.y = -150;
LK.gui.bottom.addChild(speedUpgradeBtn);
var rangeUpgradeBtn = new Text2('Range +50 (Cost: 100)', {
size: 35,
fill: '#FFFFFF'
});
rangeUpgradeBtn.anchor.set(0.5, 1);
rangeUpgradeBtn.x = 0;
rangeUpgradeBtn.y = -100;
LK.gui.bottom.addChild(rangeUpgradeBtn);
var healthUpgradeBtn = new Text2('Health +25 (Cost: 60)', {
size: 35,
fill: '#FFFFFF'
});
healthUpgradeBtn.anchor.set(0.5, 1);
healthUpgradeBtn.x = 0;
healthUpgradeBtn.y = -50;
LK.gui.bottom.addChild(healthUpgradeBtn);
var equipmentUpgradeBtn = new Text2('Upgrade Equipment (Cost: 200)', {
size: 35,
fill: '#FFFFFF'
});
equipmentUpgradeBtn.anchor.set(0.5, 1);
equipmentUpgradeBtn.x = 0;
equipmentUpgradeBtn.y = 0;
LK.gui.bottom.addChild(equipmentUpgradeBtn);
var equipmentLevelText = new Text2('Equipment Level: 0', {
size: 30,
fill: '#8a2be2'
});
equipmentLevelText.anchor.set(0, 0);
equipmentLevelText.x = 120;
equipmentLevelText.y = 100;
LK.gui.topLeft.addChild(equipmentLevelText);
var relicCountText = new Text2('Relics: 0', {
size: 30,
fill: '#ff6b6b'
});
relicCountText.anchor.set(0, 0);
relicCountText.x = 120;
relicCountText.y = 220;
LK.gui.topLeft.addChild(relicCountText);
// Boss warning display
var bossWarningText = new Text2('', {
size: 50,
fill: '#FF0000'
});
bossWarningText.anchor.set(0.5, 0.5);
bossWarningText.x = 0;
bossWarningText.y = 0;
LK.gui.center.addChild(bossWarningText);
// Biome display
var biomeText = new Text2('Biome: Forest', {
size: 35,
fill: '#00FF00'
});
biomeText.anchor.set(0.5, 0);
biomeText.x = 0;
biomeText.y = 100;
LK.gui.top.addChild(biomeText);
// Skill points display
var skillPointsText = new Text2('Skill Points: 0', {
size: 30,
fill: '#ffd700'
});
skillPointsText.anchor.set(0, 0);
skillPointsText.x = 120;
skillPointsText.y = 180;
LK.gui.topLeft.addChild(skillPointsText);
// Skill tree button
var skillTreeBtn = new Text2('Skill Tree', {
size: 35,
fill: '#ff6b6b'
});
skillTreeBtn.anchor.set(0.5, 0);
skillTreeBtn.x = 0;
skillTreeBtn.y = 150;
LK.gui.top.addChild(skillTreeBtn);
// Daily reward button
var dailyRewardBtn = new Text2('Daily Reward', {
size: 35,
fill: '#ffd700'
});
dailyRewardBtn.anchor.set(0.5, 0);
dailyRewardBtn.x = 0;
dailyRewardBtn.y = 200;
LK.gui.top.addChild(dailyRewardBtn);
// Achievement button
var achievementBtn = new Text2('Achievements', {
size: 35,
fill: '#4a90e2'
});
achievementBtn.anchor.set(0.5, 0);
achievementBtn.x = 0;
achievementBtn.y = 250;
LK.gui.top.addChild(achievementBtn);
// Prestige button
var prestigeBtn = new Text2('Prestige', {
size: 35,
fill: '#ff6b6b'
});
prestigeBtn.anchor.set(0.5, 0);
prestigeBtn.x = 0;
prestigeBtn.y = 300;
LK.gui.top.addChild(prestigeBtn);
// Prestige level display
var prestigeLevelText = new Text2('Prestige: ' + prestigeLevel, {
size: 30,
fill: '#ff6b6b'
});
prestigeLevelText.anchor.set(0, 0);
prestigeLevelText.x = 120;
prestigeLevelText.y = 260;
LK.gui.topLeft.addChild(prestigeLevelText);
// Daily reward UI (initially hidden)
var dailyRewardContainer = new Container();
dailyRewardContainer.visible = false;
LK.gui.center.addChild(dailyRewardContainer);
var dailyRewardBg = LK.getAsset('rangeCircle', {
width: 1600,
height: 1200,
anchorX: 0.5,
anchorY: 0.5,
color: 0x000000
});
dailyRewardBg.alpha = 0.8;
dailyRewardContainer.addChild(dailyRewardBg);
var dailyRewardTitle = new Text2('DAILY REWARDS', {
size: 60,
fill: '#ffd700'
});
dailyRewardTitle.anchor.set(0.5, 0.5);
dailyRewardTitle.x = 0;
dailyRewardTitle.y = -500;
dailyRewardContainer.addChild(dailyRewardTitle);
var dailyCloseBtn = new Text2('X', {
size: 60,
fill: '#ff0000'
});
dailyCloseBtn.anchor.set(0.5, 0.5);
dailyCloseBtn.x = 750;
dailyCloseBtn.y = -550;
dailyRewardContainer.addChild(dailyCloseBtn);
// Achievement UI (initially hidden)
var achievementContainer = new Container();
achievementContainer.visible = false;
LK.gui.center.addChild(achievementContainer);
// Prestige UI (initially hidden)
var prestigeContainer = new Container();
prestigeContainer.visible = false;
LK.gui.center.addChild(prestigeContainer);
var prestigeBg = LK.getAsset('rangeCircle', {
width: 1600,
height: 1200,
anchorX: 0.5,
anchorY: 0.5,
color: 0x000000
});
prestigeBg.alpha = 0.8;
prestigeContainer.addChild(prestigeBg);
var prestigeTitle = new Text2('PRESTIGE SYSTEM', {
size: 60,
fill: '#ff6b6b'
});
prestigeTitle.anchor.set(0.5, 0.5);
prestigeTitle.x = 0;
prestigeTitle.y = -500;
prestigeContainer.addChild(prestigeTitle);
var prestigeCloseBtn = new Text2('X', {
size: 60,
fill: '#ff0000'
});
prestigeCloseBtn.anchor.set(0.5, 0.5);
prestigeCloseBtn.x = 750;
prestigeCloseBtn.y = -550;
prestigeContainer.addChild(prestigeCloseBtn);
var achievementBg = LK.getAsset('rangeCircle', {
width: 1800,
height: 1400,
anchorX: 0.5,
anchorY: 0.5,
color: 0x000000
});
achievementBg.alpha = 0.8;
achievementContainer.addChild(achievementBg);
var achievementTitle = new Text2('ACHIEVEMENTS', {
size: 60,
fill: '#4a90e2'
});
achievementTitle.anchor.set(0.5, 0.5);
achievementTitle.x = 0;
achievementTitle.y = -600;
achievementContainer.addChild(achievementTitle);
var achievementCloseBtn = new Text2('X', {
size: 60,
fill: '#ff0000'
});
achievementCloseBtn.anchor.set(0.5, 0.5);
achievementCloseBtn.x = 850;
achievementCloseBtn.y = -650;
achievementContainer.addChild(achievementCloseBtn);
// Skill tree UI containers (initially hidden)
var skillTreeContainer = new Container();
skillTreeContainer.visible = false;
LK.gui.center.addChild(skillTreeContainer);
// Background for skill tree
var skillTreeBg = LK.getAsset('rangeCircle', {
width: 1800,
height: 1400,
anchorX: 0.5,
anchorY: 0.5,
color: 0x000000
});
skillTreeBg.alpha = 0.8;
skillTreeContainer.addChild(skillTreeBg);
// Close button
var closeBtn = new Text2('X', {
size: 60,
fill: '#ff0000'
});
closeBtn.anchor.set(0.5, 0.5);
closeBtn.x = 850;
closeBtn.y = -650;
skillTreeContainer.addChild(closeBtn);
// Branch titles
var offenseTitle = new Text2('ATTACK', {
size: 50,
fill: '#ff4444'
});
offenseTitle.anchor.set(0.5, 0.5);
offenseTitle.x = -500;
offenseTitle.y = -450;
skillTreeContainer.addChild(offenseTitle);
var defenseTitle = new Text2('DEFENSE', {
size: 50,
fill: '#44ff44'
});
defenseTitle.anchor.set(0.5, 0.5);
defenseTitle.x = 0;
defenseTitle.y = -450;
skillTreeContainer.addChild(defenseTitle);
var utilityTitle = new Text2('SUPPORT', {
size: 50,
fill: '#4444ff'
});
utilityTitle.anchor.set(0.5, 0.5);
utilityTitle.x = 500;
utilityTitle.y = -450;
skillTreeContainer.addChild(utilityTitle);
var manaText = new Text2('Mana: 100/100', {
size: 35,
fill: '#4a90e2'
});
manaText.anchor.set(0, 0);
manaText.x = 120;
manaText.y = 140;
LK.gui.topLeft.addChild(manaText);
// Initialize hero at center
hero = new Hero();
hero.x = 1024;
hero.y = 1366;
game.addChild(hero);
// Skill tree system
var skillPoints = 0;
var showSkillTree = false;
var skillTreeData = {
offense: {
damage: {
unlocked: false,
cost: 2,
name: "Power",
desc: "+50% damage"
},
crit: {
unlocked: false,
cost: 3,
name: "Critical",
desc: "25% crit chance"
},
speed: {
unlocked: false,
cost: 2,
name: "Speed",
desc: "+50% attack speed"
}
},
defense: {
health: {
unlocked: false,
cost: 2,
name: "Vitality",
desc: "+100 HP"
},
regen: {
unlocked: false,
cost: 3,
name: "Regeneration",
desc: "Heal 3 HP/sec"
},
armor: {
unlocked: false,
cost: 2,
name: "Armor",
desc: "-30% damage taken"
}
},
utility: {
gold: {
unlocked: false,
cost: 2,
name: "Wealth",
desc: "+100% gold gain"
},
mana: {
unlocked: false,
cost: 3,
name: "Mana Flow",
desc: "+50% mana regen"
},
magnet: {
unlocked: false,
cost: 2,
name: "Magnet",
desc: "+200% pickup range"
}
}
};
// Skill bonuses
var skillBonuses = {
damageMultiplier: 1.0,
critChance: 0.0,
attackSpeedMultiplier: 1.0,
healthBonus: 0,
healthRegen: 0,
damageReduction: 0.0,
goldMultiplier: 1.0,
manaRegen: 0.0,
magnetMultiplier: 1.0,
vampireHealing: 0.0,
relicAttackSpeed: 0.0,
relicGoldRange: 0.0,
relicDamage: 0.0,
relicArmor: 0.0,
relicGoldGain: 0.0
};
// Create skill tree nodes
var skillNodes = {};
function createSkillNode(branch, skillKey, x, y) {
var skill = skillTreeData[branch][skillKey];
var node = new Container();
// Node background
var bg = LK.getAsset('rangeCircle', {
width: 160,
height: 160,
anchorX: 0.5,
anchorY: 0.5,
color: skill.unlocked ? 0x00ff00 : 0x666666
});
bg.alpha = 0.8;
node.addChild(bg);
// Node text
var text = new Text2(skill.name, {
size: 24,
fill: skill.unlocked ? '#ffffff' : '#aaaaaa'
});
text.anchor.set(0.5, 0.5);
text.y = -15;
node.addChild(text);
// Cost text
var costText = new Text2(skill.cost + ' pts', {
size: 18,
fill: '#ffff00'
});
costText.anchor.set(0.5, 0.5);
costText.y = 15;
node.addChild(costText);
node.x = x;
node.y = y;
node.skillKey = skillKey;
node.branch = branch;
// Click handler
node.down = function () {
if (!skill.unlocked && skillPoints >= skill.cost) {
// Check requirements
if (skill.requires && !skillTreeData[branch][skill.requires].unlocked) {
return;
}
// Unlock skill
skill.unlocked = true;
skillPoints -= skill.cost;
applySkillBonus(branch, skillKey);
updateSkillTreeUI();
LK.getSound('upgrade').play();
}
};
skillTreeContainer.addChild(node);
skillNodes[branch + '_' + skillKey] = node;
}
// Create all skill nodes
// Offense branch
createSkillNode('offense', 'damage', -500, -300);
createSkillNode('offense', 'crit', -500, -100);
createSkillNode('offense', 'speed', -500, 100);
// Defense branch
createSkillNode('defense', 'health', 0, -300);
createSkillNode('defense', 'regen', 0, -100);
createSkillNode('defense', 'armor', 0, 100);
// Utility branch
createSkillNode('utility', 'gold', 500, -300);
createSkillNode('utility', 'mana', 500, -100);
createSkillNode('utility', 'magnet', 500, 100);
function updateSkillTreeUI() {
skillPointsText.setText('Skill Points: ' + skillPoints);
// Update all nodes
for (var branch in skillTreeData) {
for (var skillKey in skillTreeData[branch]) {
var skill = skillTreeData[branch][skillKey];
var node = skillNodes[branch + '_' + skillKey];
if (node) {
var bg = node.children[0];
var text = node.children[1];
bg.tint = skill.unlocked ? 0x00ff00 : 0x666666;
text.tint = skill.unlocked ? 0xffffff : 0xaaaaaa;
// Check if can unlock
var canUnlock = !skill.unlocked && skillPoints >= skill.cost;
if (skill.requires && !skillTreeData[branch][skill.requires].unlocked) {
canUnlock = false;
}
if (canUnlock) {
bg.tint = 0xffff00;
}
}
}
}
}
function applySkillBonus(branch, skillKey) {
var skill = skillTreeData[branch][skillKey];
// Apply bonuses based on skill
if (skillKey === 'damage') {
skillBonuses.damageMultiplier += 0.50;
} else if (skillKey === 'crit') {
skillBonuses.critChance += 0.25;
} else if (skillKey === 'speed') {
skillBonuses.attackSpeedMultiplier += 0.50;
} else if (skillKey === 'health') {
skillBonuses.healthBonus += 100;
hero.maxHealth += 100;
hero.health = Math.min(hero.health + 100, hero.maxHealth);
} else if (skillKey === 'regen') {
skillBonuses.healthRegen += 3;
} else if (skillKey === 'armor') {
skillBonuses.damageReduction += 0.30;
} else if (skillKey === 'gold') {
skillBonuses.goldMultiplier += 1.00;
} else if (skillKey === 'mana') {
skillBonuses.manaRegen += 0.50;
} else if (skillKey === 'magnet') {
skillBonuses.magnetMultiplier += 2.00;
}
}
function applyRelicBonus(relic) {
if (relic.relicType === 'vampireTooth') {
skillBonuses.vampireHealing += relic.bonus;
} else if (relic.relicType === 'clockwork') {
skillBonuses.relicAttackSpeed += relic.bonus;
} else if (relic.relicType === 'goldenFeather') {
skillBonuses.relicGoldRange += relic.bonus;
} else if (relic.relicType === 'crystalCore') {
skillBonuses.relicDamage += relic.bonus;
} else if (relic.relicType === 'ironShield') {
skillBonuses.relicArmor += relic.bonus;
} else if (relic.relicType === 'luckyCharm') {
skillBonuses.relicGoldGain += relic.bonus;
}
}
function checkDailyReward() {
var today = new Date().toDateString();
if (lastLoginDate !== today) {
// Reset daily rewards for new day
for (var i = 0; i < dailyRewards.length; i++) {
dailyRewards[i].claimed = false;
}
lastLoginDate = today;
storage.lastLoginDate = today;
storage.claimedRewards = [];
}
}
function createDailyRewardUI() {
// Clear existing reward items
var rewardItems = [];
for (var i = 0; i < dailyRewards.length; i++) {
var reward = dailyRewards[i];
var rewardItem = new Container();
var bg = LK.getAsset('rangeCircle', {
width: 180,
height: 180,
anchorX: 0.5,
anchorY: 0.5,
color: reward.claimed ? 0x666666 : 0x4a90e2
});
bg.alpha = 0.8;
rewardItem.addChild(bg);
var dayText = new Text2('Day ' + (i + 1), {
size: 20,
fill: '#ffffff'
});
dayText.anchor.set(0.5, 0.5);
dayText.y = -30;
rewardItem.addChild(dayText);
var rewardText = new Text2(reward.type === 'gold' ? reward.amount + ' Gold' : reward.type === 'skillPoints' ? reward.amount + ' SP' : reward.amount + ' Mana', {
size: 18,
fill: '#ffff00'
});
rewardText.anchor.set(0.5, 0.5);
rewardText.y = 10;
rewardItem.addChild(rewardText);
var statusText = new Text2(reward.claimed ? 'Claimed' : 'Claim', {
size: 16,
fill: reward.claimed ? '#888888' : '#00ff00'
});
statusText.anchor.set(0.5, 0.5);
statusText.y = 30;
rewardItem.addChild(statusText);
rewardItem.x = -450 + i * 130;
rewardItem.y = -200;
rewardItem.rewardIndex = i;
if (!reward.claimed) {
rewardItem.down = function () {
claimDailyReward(this.rewardIndex);
};
}
dailyRewardContainer.addChild(rewardItem);
rewardItems.push(rewardItem);
}
}
function claimDailyReward(index) {
var reward = dailyRewards[index];
if (!reward.claimed) {
reward.claimed = true;
claimedRewards.push(index);
storage.claimedRewards = claimedRewards;
if (reward.type === 'gold') {
playerGold += reward.amount;
goldText.setText('Gold: ' + playerGold);
} else if (reward.type === 'skillPoints') {
skillPoints += reward.amount;
skillPointsText.setText('Skill Points: ' + skillPoints);
} else if (reward.type === 'mana') {
maxMana += reward.amount;
playerMana = Math.min(maxMana, playerMana + reward.amount);
}
LK.getSound('pickup').play();
createDailyRewardUI();
}
}
function updateAchievements() {
// Update achievement progress
achievements.wave10.current = Math.max(achievements.wave10.current, waveNumber);
achievements.kills500.current = totalEnemyKills;
achievements.equipment100.current = totalEquipmentCollected;
achievements.gold5000.current = totalGoldCollected;
achievements.relics10.current = totalRelicsCollected;
// Check for newly completed achievements
for (var key in achievements) {
var achievement = achievements[key];
if (!achievement.completed && achievement.current >= achievement.target) {
achievement.completed = true;
completedAchievements.push(key);
storage.completedAchievements = completedAchievements;
// Give reward
if (achievement.reward.type === 'gold') {
playerGold += achievement.reward.amount;
goldText.setText('Gold: ' + playerGold);
} else if (achievement.reward.type === 'skillPoints') {
skillPoints += achievement.reward.amount;
skillPointsText.setText('Skill Points: ' + skillPoints);
} else if (achievement.reward.type === 'mana') {
maxMana += achievement.reward.amount;
playerMana = Math.min(maxMana, playerMana + achievement.reward.amount);
}
LK.getSound('upgrade').play();
LK.effects.flashScreen(0x00ff00, 500);
}
}
}
function createAchievementUI() {
var yOffset = -400;
for (var key in achievements) {
var achievement = achievements[key];
var achievementItem = new Container();
var bg = LK.getAsset('rangeCircle', {
width: 1600,
height: 120,
anchorX: 0.5,
anchorY: 0.5,
color: achievement.completed ? 0x00ff00 : 0x4a90e2
});
bg.alpha = 0.6;
achievementItem.addChild(bg);
var nameText = new Text2(achievement.name, {
size: 32,
fill: '#ffffff'
});
nameText.anchor.set(0, 0.5);
nameText.x = -750;
nameText.y = -15;
achievementItem.addChild(nameText);
var descText = new Text2(achievement.desc, {
size: 24,
fill: '#cccccc'
});
descText.anchor.set(0, 0.5);
descText.x = -750;
descText.y = 15;
achievementItem.addChild(descText);
var progressText = new Text2(achievement.current + '/' + achievement.target, {
size: 28,
fill: '#ffff00'
});
progressText.anchor.set(1, 0.5);
progressText.x = 600;
progressText.y = -15;
achievementItem.addChild(progressText);
var rewardText = new Text2('Reward: ' + (achievement.reward.type === 'gold' ? achievement.reward.amount + ' Gold' : achievement.reward.type === 'skillPoints' ? achievement.reward.amount + ' SP' : achievement.reward.amount + ' Mana'), {
size: 20,
fill: achievement.completed ? '#888888' : '#00ff00'
});
rewardText.anchor.set(1, 0.5);
rewardText.x = 600;
rewardText.y = 15;
achievementItem.addChild(rewardText);
var statusText = new Text2(achievement.completed ? 'COMPLETED' : 'IN PROGRESS', {
size: 24,
fill: achievement.completed ? '#00ff00' : '#ffff00'
});
statusText.anchor.set(1, 0.5);
statusText.x = 750;
statusText.y = 0;
achievementItem.addChild(statusText);
achievementItem.x = 0;
achievementItem.y = yOffset;
yOffset += 140;
achievementContainer.addChild(achievementItem);
}
}
function createPrestigeUI() {
// Clear existing prestige items
for (var i = prestigeContainer.children.length - 1; i >= 0; i--) {
var child = prestigeContainer.children[i];
if (child !== prestigeBg && child !== prestigeTitle && child !== prestigeCloseBtn) {
prestigeContainer.removeChild(child);
}
}
// Current prestige level info
var currentLevelText = new Text2('Current Prestige Level: ' + prestigeLevel, {
size: 40,
fill: '#ffffff'
});
currentLevelText.anchor.set(0.5, 0.5);
currentLevelText.x = 0;
currentLevelText.y = -350;
prestigeContainer.addChild(currentLevelText);
// Current bonuses
var bonusesText = new Text2('Current Bonuses:', {
size: 35,
fill: '#ffd700'
});
bonusesText.anchor.set(0.5, 0.5);
bonusesText.x = 0;
bonusesText.y = -280;
prestigeContainer.addChild(bonusesText);
var goldBonusText = new Text2('+' + (prestigeBonuses.goldIncome * 100).toFixed(0) + '% Gold Income', {
size: 28,
fill: '#ffff00'
});
goldBonusText.anchor.set(0.5, 0.5);
goldBonusText.x = 0;
goldBonusText.y = -230;
prestigeContainer.addChild(goldBonusText);
var manaBonusText = new Text2('+' + prestigeBonuses.manaCapacity + ' Mana Capacity', {
size: 28,
fill: '#4a90e2'
});
manaBonusText.anchor.set(0.5, 0.5);
manaBonusText.x = 0;
manaBonusText.y = -180;
prestigeContainer.addChild(manaBonusText);
// Prestige requirements
var canPrestige = waveNumber >= prestigeUnlockWave;
var requirementText = new Text2('Requirement: Reach Wave ' + prestigeUnlockWave + ' (' + (canPrestige ? 'MET' : 'Current: ' + waveNumber) + ')', {
size: 30,
fill: canPrestige ? '#00ff00' : '#ff0000'
});
requirementText.anchor.set(0.5, 0.5);
requirementText.x = 0;
requirementText.y = -100;
prestigeContainer.addChild(requirementText);
// Next prestige rewards
var nextRewardsText = new Text2('Next Prestige Rewards:', {
size: 35,
fill: '#ffd700'
});
nextRewardsText.anchor.set(0.5, 0.5);
nextRewardsText.x = 0;
nextRewardsText.y = -30;
prestigeContainer.addChild(nextRewardsText);
var goldRewardText = new Text2('+5% Gold Income', {
size: 28,
fill: '#ffff00'
});
goldRewardText.anchor.set(0.5, 0.5);
goldRewardText.x = 0;
goldRewardText.y = 20;
prestigeContainer.addChild(goldRewardText);
var manaRewardText = new Text2('+10 Mana Capacity', {
size: 28,
fill: '#4a90e2'
});
manaRewardText.anchor.set(0.5, 0.5);
manaRewardText.x = 0;
manaRewardText.y = 70;
prestigeContainer.addChild(manaRewardText);
// Prestige button
var prestigeConfirmBtn = new Text2(canPrestige ? 'PRESTIGE NOW' : 'REQUIREMENTS NOT MET', {
size: 40,
fill: canPrestige ? '#00ff00' : '#666666'
});
prestigeConfirmBtn.anchor.set(0.5, 0.5);
prestigeConfirmBtn.x = 0;
prestigeConfirmBtn.y = 150;
prestigeContainer.addChild(prestigeConfirmBtn);
// Warning text
var warningText = new Text2('WARNING: This will reset all progress except prestige bonuses!', {
size: 24,
fill: '#ff0000'
});
warningText.anchor.set(0.5, 0.5);
warningText.x = 0;
warningText.y = 220;
prestigeContainer.addChild(warningText);
if (canPrestige) {
prestigeConfirmBtn.down = function () {
performPrestige();
};
}
}
function performPrestige() {
// Increase prestige level
prestigeLevel++;
storage.prestigeLevel = prestigeLevel;
// Calculate new bonuses (scalable)
var goldBonus = 0.05 * prestigeLevel; // 5% per prestige level
var manaBonus = 10 * prestigeLevel; // 10 mana per prestige level
prestigeBonuses.goldIncome = goldBonus;
prestigeBonuses.manaCapacity = manaBonus;
prestigeBonuses.startingGold = 50 * prestigeLevel; // Starting gold bonus
// Save bonuses to storage
storage.prestigeGoldIncome = prestigeBonuses.goldIncome;
storage.prestigeManaCapacity = prestigeBonuses.manaCapacity;
storage.prestigeStartingGold = prestigeBonuses.startingGold;
// Apply mana capacity bonus immediately
maxMana = 100 + prestigeBonuses.manaCapacity;
playerMana = maxMana;
// Flash effect
LK.effects.flashScreen(0xff6b6b, 1000);
LK.getSound('upgrade').play();
// Hide prestige UI
prestigeContainer.visible = false;
// Reset progress (this will trigger game restart)
LK.showGameOver();
}
function changeBiome() {
var biomes = ['forest', 'cave', 'volcano', 'ice'];
var biomeIndex = Math.floor(waveNumber / biomeWaveInterval) % biomes.length;
var newBiome = biomes[biomeIndex];
if (newBiome !== currentBiome) {
currentBiome = newBiome;
game.setBackgroundColor(biomeColors[currentBiome]);
// Update biome display
var biomeNames = {
forest: 'Forest',
cave: 'Cave',
volcano: 'Volcano',
ice: 'Ice'
};
biomeText.setText('Biome: ' + biomeNames[currentBiome]);
biomeText.tint = biomeColors[currentBiome];
// Biome change effect
LK.effects.flashScreen(biomeColors[currentBiome], 1000);
// Clear existing biome effects
for (var i = biomeEffects.length - 1; i >= 0; i--) {
biomeEffects[i].destroy();
biomeEffects.splice(i, 1);
}
// Create new biome effects
createBiomeEffects();
}
}
function createBiomeEffects() {
// Create atmospheric effects based on biome
if (currentBiome === 'forest') {
// Create fog particles
for (var i = 0; i < 8; i++) {
var fogParticle = LK.getAsset('rangeCircle', {
width: 400 + Math.random() * 200,
height: 400 + Math.random() * 200,
anchorX: 0.5,
anchorY: 0.5,
color: 0x90EE90
});
fogParticle.alpha = 0.1 + Math.random() * 0.1;
fogParticle.x = Math.random() * 2048;
fogParticle.y = Math.random() * 2732;
game.addChild(fogParticle);
biomeEffects.push(fogParticle);
// Animate fog movement
tween(fogParticle, {
x: fogParticle.x + (Math.random() - 0.5) * 300,
y: fogParticle.y + (Math.random() - 0.5) * 300,
alpha: fogParticle.alpha * 0.5
}, {
duration: 8000 + Math.random() * 4000,
easing: tween.linear
});
}
} else if (currentBiome === 'cave') {
// Create stalactites and shadows
for (var i = 0; i < 6; i++) {
var stalactite = LK.getAsset('rangeCircle', {
width: 80 + Math.random() * 40,
height: 200 + Math.random() * 100,
anchorX: 0.5,
anchorY: 0,
color: 0x696969
});
stalactite.alpha = 0.6;
stalactite.x = Math.random() * 2048;
stalactite.y = 0;
game.addChild(stalactite);
biomeEffects.push(stalactite);
}
} else if (currentBiome === 'volcano') {
// Create lava cracks and ember particles
for (var i = 0; i < 10; i++) {
var lavaCrack = LK.getAsset('rangeCircle', {
width: 200 + Math.random() * 150,
height: 30 + Math.random() * 20,
anchorX: 0.5,
anchorY: 0.5,
color: 0xFF4500
});
lavaCrack.alpha = 0.7;
lavaCrack.x = Math.random() * 2048;
lavaCrack.y = Math.random() * 2732;
lavaCrack.rotation = Math.random() * Math.PI * 2;
game.addChild(lavaCrack);
biomeEffects.push(lavaCrack);
// Animate lava glow
tween(lavaCrack, {
alpha: 0.3
}, {
duration: 1000 + Math.random() * 1000,
easing: tween.easeInOut
});
}
// Create ember particles
for (var i = 0; i < 15; i++) {
var ember = LK.getAsset('rangeCircle', {
width: 20 + Math.random() * 15,
height: 20 + Math.random() * 15,
anchorX: 0.5,
anchorY: 0.5,
color: 0xFFD700
});
ember.alpha = 0.8;
ember.x = Math.random() * 2048;
ember.y = 2732 + Math.random() * 200;
game.addChild(ember);
biomeEffects.push(ember);
// Animate ember rising
tween(ember, {
y: ember.y - 2932,
alpha: 0
}, {
duration: 4000 + Math.random() * 2000,
easing: tween.linear
});
}
} else if (currentBiome === 'ice') {
// Create ice crystals and snow particles
for (var i = 0; i < 12; i++) {
var iceCrystal = LK.getAsset('rangeCircle', {
width: 60 + Math.random() * 30,
height: 60 + Math.random() * 30,
anchorX: 0.5,
anchorY: 0.5,
color: 0xE0FFFF
});
iceCrystal.alpha = 0.6;
iceCrystal.x = Math.random() * 2048;
iceCrystal.y = Math.random() * 2732;
game.addChild(iceCrystal);
biomeEffects.push(iceCrystal);
// Animate ice crystal sparkle
tween(iceCrystal, {
scaleX: 1.5,
scaleY: 1.5,
alpha: 0.3
}, {
duration: 2000 + Math.random() * 1000,
easing: tween.easeInOut
});
}
// Create snowflakes
for (var i = 0; i < 20; i++) {
var snowflake = LK.getAsset('rangeCircle', {
width: 15 + Math.random() * 10,
height: 15 + Math.random() * 10,
anchorX: 0.5,
anchorY: 0.5,
color: 0xFFFFFF
});
snowflake.alpha = 0.7;
snowflake.x = Math.random() * 2048;
snowflake.y = -50 - Math.random() * 100;
game.addChild(snowflake);
biomeEffects.push(snowflake);
// Animate snowflake falling
tween(snowflake, {
y: snowflake.y + 2832,
x: snowflake.x + (Math.random() - 0.5) * 300
}, {
duration: 6000 + Math.random() * 3000,
easing: tween.linear
});
}
}
}
function getBiomeEnemyTypes() {
var baseTypes = ['enemy1', 'enemy2', 'enemy3', 'enemy5', 'enemy6', 'enemy7'];
var biomeTypes = {
forest: ['enemy1', 'enemy2', 'enemy5'],
// Nature themed
cave: ['enemy3', 'enemy6', 'enemy7'],
// Dark, heavy enemies
volcano: ['enemy4', 'enemy6', 'enemy2'],
// Fire themed, fast enemies
ice: ['enemy1', 'enemy3', 'enemy7'] // Slow, defensive enemies
};
return biomeTypes[currentBiome] || baseTypes;
}
function applyPrestigeBonuses() {
// Apply starting gold bonus
if (prestigeBonuses.startingGold > 0) {
playerGold += prestigeBonuses.startingGold;
goldText.setText('Gold: ' + playerGold);
}
// Apply mana capacity bonus
maxMana = 100 + prestigeBonuses.manaCapacity;
playerMana = maxMana;
// Update UI
prestigeLevelText.setText('Prestige: ' + prestigeLevel);
}
// Button handlers
skillTreeBtn.down = function () {
showSkillTree = !showSkillTree;
skillTreeContainer.visible = showSkillTree;
updateSkillTreeUI();
};
closeBtn.down = function () {
showSkillTree = false;
skillTreeContainer.visible = false;
};
// Daily reward button handler
dailyRewardBtn.down = function () {
dailyRewardContainer.visible = !dailyRewardContainer.visible;
if (dailyRewardContainer.visible) {
createDailyRewardUI();
}
};
// Achievement button handler
achievementBtn.down = function () {
achievementContainer.visible = !achievementContainer.visible;
if (achievementContainer.visible) {
updateAchievements();
createAchievementUI();
}
};
// Daily reward close button
dailyCloseBtn.down = function () {
dailyRewardContainer.visible = false;
};
// Achievement close button
achievementCloseBtn.down = function () {
achievementContainer.visible = false;
};
// Prestige button handler
prestigeBtn.down = function () {
prestigeContainer.visible = !prestigeContainer.visible;
if (prestigeContainer.visible) {
createPrestigeUI();
}
};
// Prestige close button
prestigeCloseBtn.down = function () {
prestigeContainer.visible = false;
};
// Active skill buttons on right side
var lightningBtn = new Text2('Lightning\n(40 mana)', {
size: 28,
fill: '#ffff00'
});
lightningBtn.anchor.set(1, 0.5);
lightningBtn.x = -20;
lightningBtn.y = -200;
LK.gui.right.addChild(lightningBtn);
var freezeBtn = new Text2('Freeze\n(30 mana)', {
size: 28,
fill: '#00ffff'
});
freezeBtn.anchor.set(1, 0.5);
freezeBtn.x = -20;
freezeBtn.y = -50;
LK.gui.right.addChild(freezeBtn);
var shieldBtn = new Text2('Shield\n(50 mana)', {
size: 28,
fill: '#00ff00'
});
shieldBtn.anchor.set(1, 0.5);
shieldBtn.x = -20;
shieldBtn.y = 100;
LK.gui.right.addChild(shieldBtn);
// Upgrade costs
var damageCost = 50;
var speedCost = 75;
var rangeCost = 100;
var healthCost = 60;
var equipmentCost = 200;
var equipmentLevel = 0;
// Mana system
var playerMana = 100;
var maxMana = 100;
var manaPotions = [];
// Active skills
var lightningCooldown = 0;
var lightningMaxCooldown = 1800; // 30 seconds at 60fps
var freezeCooldown = 0;
var freezeMaxCooldown = 1800; // 30 seconds at 60fps
var shieldCooldown = 0;
var shieldMaxCooldown = 3600; // 60 seconds at 60fps
var shieldActive = false;
var shieldDuration = 0;
var shieldMaxDuration = 600; // 10 seconds at 60fps
// Skill costs
var lightningManaCost = 40;
var freezeManaCost = 30;
var shieldManaCost = 50;
// Game speed system
var gameSpeed = 1; // 1x, 2x, 3x multiplier
var speedLevels = [1, 2, 3];
var currentSpeedIndex = 0;
// Upgrade button handlers
damageUpgradeBtn.down = function () {
if (playerGold >= damageCost) {
playerGold -= damageCost;
hero.damage += 10;
damageCost = Math.floor(damageCost * 1.5);
goldText.setText('Gold: ' + playerGold);
damageUpgradeBtn.setText('Damage +10 (Cost: ' + damageCost + ')');
LK.getSound('upgrade').play();
}
};
speedUpgradeBtn.down = function () {
if (playerGold >= speedCost) {
playerGold -= speedCost;
hero.attackSpeed = Math.max(10, hero.attackSpeed - 5);
speedCost = Math.floor(speedCost * 1.5);
goldText.setText('Gold: ' + playerGold);
speedUpgradeBtn.setText('Speed +10 (Cost: ' + speedCost + ')');
LK.getSound('upgrade').play();
}
};
rangeUpgradeBtn.down = function () {
if (playerGold >= rangeCost) {
playerGold -= rangeCost;
hero.range += 50;
rangeCost = Math.floor(rangeCost * 1.5);
goldText.setText('Gold: ' + playerGold);
rangeUpgradeBtn.setText('Range +50 (Cost: ' + rangeCost + ')');
LK.getSound('upgrade').play();
}
};
healthUpgradeBtn.down = function () {
if (playerGold >= healthCost) {
playerGold -= healthCost;
hero.maxHealth += 25;
hero.health = Math.min(hero.health + 25, hero.maxHealth);
healthCost = Math.floor(healthCost * 1.4);
goldText.setText('Gold: ' + playerGold);
healthUpgradeBtn.setText('Health +25 (Cost: ' + healthCost + ')');
LK.getSound('upgrade').play();
}
};
equipmentUpgradeBtn.down = function () {
if (playerGold >= equipmentCost && playerEquipment.length > 0) {
playerGold -= equipmentCost;
equipmentLevel++;
hero.damage += 15;
hero.attackSpeed = Math.max(8, hero.attackSpeed - 3);
equipmentCost = Math.floor(equipmentCost * 1.6);
goldText.setText('Gold: ' + playerGold);
equipmentUpgradeBtn.setText('Upgrade Equipment (Cost: ' + equipmentCost + ')');
equipmentLevelText.setText('Equipment Level: ' + equipmentLevel);
LK.getSound('upgrade').play();
}
};
// Speed button handler
speedBtn.down = function () {
currentSpeedIndex = (currentSpeedIndex + 1) % speedLevels.length;
gameSpeed = speedLevels[currentSpeedIndex];
speedBtn.setText('Speed: ' + gameSpeed + 'x');
LK.getSound('pickup').play();
};
function spawnEnemy() {
// Check if boss wave
if (waveNumber % bossWaveInterval === 0 && !bossSpawned) {
spawnBoss();
return;
}
// Determine enemy type based on biome and wave
var biomeEnemyTypes = getBiomeEnemyTypes();
var enemyType = biomeEnemyTypes[Math.floor(Math.random() * biomeEnemyTypes.length)];
var rand = Math.random();
// Special enemies based on wave progression
if (waveNumber >= 10 && rand < 0.05) {
enemyType = 'enemy4'; // Boss
} else if (waveNumber >= 8 && rand < 0.08) {
enemyType = 'enemy7'; // Healer
} else if (waveNumber >= 6 && rand < 0.12) {
enemyType = 'enemy6'; // Exploder
} else if (waveNumber >= 4 && rand < 0.15) {
enemyType = 'enemy5'; // Archer
} else if (waveNumber >= 5 && rand < 0.2) {
enemyType = 'enemy3'; // Tank
} else if (waveNumber >= 3 && rand < 0.3) {
enemyType = 'enemy2'; // Fast
}
var enemy = new Enemy(enemyType);
// Random spawn position at screen edges
var side = Math.floor(Math.random() * 4);
switch (side) {
case 0:
// Top
enemy.x = Math.random() * 2048;
enemy.y = -50;
break;
case 1:
// Right
enemy.x = 2098;
enemy.y = Math.random() * 2732;
break;
case 2:
// Bottom
enemy.x = Math.random() * 2048;
enemy.y = 2782;
break;
case 3:
// Left
enemy.x = -50;
enemy.y = Math.random() * 2732;
break;
}
// Scale enemy stats with wave number based on type
var healthMultiplier = 1 + (waveNumber - 1) * 0.3;
var speedMultiplier = 1 + (waveNumber - 1) * 0.15;
var goldMultiplier = 1 + (waveNumber - 1) * 0.4;
// Apply biome-specific stat modifications
if (currentBiome === 'forest') {
// Forest enemies are more agile
speedMultiplier *= 1.2;
healthMultiplier *= 0.9;
} else if (currentBiome === 'cave') {
// Cave enemies are tankier
healthMultiplier *= 1.3;
speedMultiplier *= 0.8;
} else if (currentBiome === 'volcano') {
// Volcano enemies are aggressive
speedMultiplier *= 1.4;
enemy.damage = Math.floor(enemy.damage * 1.2);
} else if (currentBiome === 'ice') {
// Ice enemies are slow but tough
speedMultiplier *= 0.7;
healthMultiplier *= 1.4;
}
enemy.health = Math.floor(enemy.health * healthMultiplier);
enemy.maxHealth = enemy.health;
enemy.speed = enemy.speed * speedMultiplier;
enemy.goldReward = Math.floor(enemy.goldReward * goldMultiplier);
// Apply biome visual effects to enemy
if (currentBiome === 'forest') {
enemy.tint = 0x90EE90;
} else if (currentBiome === 'cave') {
enemy.tint = 0x696969;
} else if (currentBiome === 'volcano') {
enemy.tint = 0xFF4500;
} else if (currentBiome === 'ice') {
enemy.tint = 0xE0FFFF;
}
enemies.push(enemy);
game.addChild(enemy);
}
function spawnBoss() {
bossSpawned = true;
var bossTypes = ['JumpBoss', 'PoisonBoss', 'SummonBoss', 'ChargeBoss'];
var randomBossType = bossTypes[Math.floor(Math.random() * bossTypes.length)];
var boss;
if (randomBossType === 'JumpBoss') {
boss = new JumpBoss();
} else if (randomBossType === 'PoisonBoss') {
boss = new PoisonBoss();
} else if (randomBossType === 'SummonBoss') {
boss = new SummonBoss();
} else if (randomBossType === 'ChargeBoss') {
boss = new ChargeBoss();
}
// Boss spawn position (always from top for dramatic effect)
boss.x = 1024;
boss.y = -100;
// Scale boss stats with wave number
var healthMultiplier = 1 + (waveNumber - 1) * 0.4;
var speedMultiplier = 1 + (waveNumber - 1) * 0.1;
var goldMultiplier = 1 + (waveNumber - 1) * 0.5;
boss.health = Math.floor(boss.health * healthMultiplier);
boss.maxHealth = boss.health;
boss.speed = boss.speed * speedMultiplier;
boss.goldReward = Math.floor(boss.goldReward * goldMultiplier);
enemies.push(boss);
game.addChild(boss);
// Boss warning effect
bossWarningText.setText('BOSS INCOMING!');
bossWarningText.alpha = 1;
tween(bossWarningText, {
alpha: 0
}, {
duration: 3000
});
LK.effects.flashScreen(0x8B0000, 1000);
LK.getSound('bossSpawn').play();
}
game.update = function () {
// Initialize daily rewards and achievements on first frame
if (LK.ticks === 1) {
checkDailyReward();
// Load completed achievements
for (var i = 0; i < completedAchievements.length; i++) {
var key = completedAchievements[i];
if (achievements[key]) {
achievements[key].completed = true;
}
}
// Update achievement progress from storage
updateAchievements();
// Apply prestige bonuses
applyPrestigeBonuses();
}
// Update health display
healthText.setText('Health: ' + hero.health);
// Update mana display
manaText.setText('Mana: ' + playerMana + '/' + maxMana);
// Mana regeneration
if (skillBonuses.manaRegen > 0 && LK.ticks % 60 === 0) {
var manaToRegen = Math.floor(maxMana * skillBonuses.manaRegen);
playerMana = Math.min(maxMana, playerMana + manaToRegen);
}
// Update skill cooldowns
if (lightningCooldown > 0) {
lightningCooldown -= gameSpeed;
var cooldownText = Math.ceil(lightningCooldown / 60) + 's';
lightningBtn.setText('Lightning\n(' + cooldownText + ')');
lightningBtn.tint = 0x666666;
} else {
lightningBtn.setText('Lightning\n(40 mana)');
lightningBtn.tint = 0xffff00;
}
if (freezeCooldown > 0) {
freezeCooldown -= gameSpeed;
var cooldownText = Math.ceil(freezeCooldown / 60) + 's';
freezeBtn.setText('Freeze\n(' + cooldownText + ')');
freezeBtn.tint = 0x666666;
} else {
freezeBtn.setText('Freeze\n(30 mana)');
freezeBtn.tint = 0x00ffff;
}
if (shieldCooldown > 0) {
shieldCooldown -= gameSpeed;
var cooldownText = Math.ceil(shieldCooldown / 60) + 's';
shieldBtn.setText('Shield\n(' + cooldownText + ')');
shieldBtn.tint = 0x666666;
} else {
shieldBtn.setText('Shield\n(50 mana)');
shieldBtn.tint = 0x00ff00;
}
// Update shield duration
if (shieldActive) {
shieldDuration -= gameSpeed;
if (shieldDuration <= 0) {
shieldActive = false;
hero.shieldEffect.alpha = 0;
tween(hero.shieldEffect, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
}
// Enemy spawning
enemySpawnTimer += gameSpeed;
var spawnRate = Math.max(30, 120 - waveNumber * 5);
if (enemySpawnTimer >= spawnRate) {
if (enemies.length < enemiesPerWave + Math.floor(waveNumber / 2)) {
spawnEnemy();
enemySpawnTimer = 0;
}
}
// Handle hero poison effect
if (heroPoisonDuration > 0) {
heroPoisonDuration -= gameSpeed;
poisonDamageTimer += gameSpeed;
if (poisonDamageTimer >= 60) {
// Damage every second
hero.takeDamage(5);
poisonDamageTimer = 0;
LK.effects.flashObject(hero, 0x00FF00, 200);
}
}
// Check for wave completion
if (LK.ticks % 1800 === 0) {
// Every 30 seconds
waveNumber++;
enemiesPerWave = Math.min(15, 3 + Math.floor(waveNumber / 2));
waveText.setText('Wave: ' + waveNumber);
// Reset boss spawn flag for next boss wave
if (waveNumber % bossWaveInterval === 1) {
bossSpawned = false;
}
// Check for biome change
changeBiome();
}
// Update all game objects
for (var i = bullets.length - 1; i >= 0; i--) {
if (bullets[i].update) {
bullets[i].update();
}
}
for (var i = enemyBullets.length - 1; i >= 0; i--) {
if (enemyBullets[i].update) {
enemyBullets[i].update();
}
}
for (var i = enemies.length - 1; i >= 0; i--) {
if (enemies[i].update) {
enemies[i].update();
}
}
for (var i = goldItems.length - 1; i >= 0; i--) {
if (goldItems[i].update) {
goldItems[i].update();
}
}
for (var i = equipmentItems.length - 1; i >= 0; i--) {
if (equipmentItems[i].update) {
equipmentItems[i].update();
}
}
for (var i = healthPotions.length - 1; i >= 0; i--) {
if (healthPotions[i].update) {
healthPotions[i].update();
}
}
for (var i = manaPotions.length - 1; i >= 0; i--) {
if (manaPotions[i].update) {
manaPotions[i].update();
}
}
for (var i = relicItems.length - 1; i >= 0; i--) {
if (relicItems[i].update) {
relicItems[i].update();
}
}
// Update relic count display
relicCountText.setText('Relics: ' + playerRelics.length);
// Update prestige level display
prestigeLevelText.setText('Prestige: ' + prestigeLevel);
// Update achievements every 5 seconds
if (LK.ticks % 300 === 0) {
updateAchievements();
}
// Update biome effects
biomeEffectTimer += gameSpeed;
if (biomeEffectTimer >= 300) {
// Every 5 seconds
biomeEffectTimer = 0;
// Clean up destroyed biome effects
for (var i = biomeEffects.length - 1; i >= 0; i--) {
if (!biomeEffects[i].parent) {
biomeEffects.splice(i, 1);
}
}
// Add new biome effects periodically
if (biomeEffects.length < 5) {
createBiomeEffects();
}
}
}; ===================================================================
--- original.js
+++ change.js
@@ -1288,8 +1288,19 @@
var bossSpawned = false;
var bossWaveInterval = 5; // Boss every 5 waves
var heroPoisonDuration = 0;
var poisonDamageTimer = 0;
+// Biome system variables
+var currentBiome = 'forest';
+var biomeWaveInterval = 10; // Change biome every 10 waves
+var biomeEffectTimer = 0;
+var biomeEffects = [];
+var biomeColors = {
+ forest: 0x228B22,
+ cave: 0x2F4F4F,
+ volcano: 0x8B0000,
+ ice: 0x87CEEB
+};
// Prestige system
var prestigeLevel = storage.prestigeLevel || 0;
var prestigeUnlockWave = 15; // Minimum wave to unlock prestige
var prestigeBonuses = {
@@ -1492,8 +1503,17 @@
bossWarningText.anchor.set(0.5, 0.5);
bossWarningText.x = 0;
bossWarningText.y = 0;
LK.gui.center.addChild(bossWarningText);
+// Biome display
+var biomeText = new Text2('Biome: Forest', {
+ size: 35,
+ fill: '#00FF00'
+});
+biomeText.anchor.set(0.5, 0);
+biomeText.x = 0;
+biomeText.y = 100;
+LK.gui.top.addChild(biomeText);
// Skill points display
var skillPointsText = new Text2('Skill Points: 0', {
size: 30,
fill: '#ffd700'
@@ -2203,8 +2223,188 @@
prestigeContainer.visible = false;
// Reset progress (this will trigger game restart)
LK.showGameOver();
}
+function changeBiome() {
+ var biomes = ['forest', 'cave', 'volcano', 'ice'];
+ var biomeIndex = Math.floor(waveNumber / biomeWaveInterval) % biomes.length;
+ var newBiome = biomes[biomeIndex];
+ if (newBiome !== currentBiome) {
+ currentBiome = newBiome;
+ game.setBackgroundColor(biomeColors[currentBiome]);
+ // Update biome display
+ var biomeNames = {
+ forest: 'Forest',
+ cave: 'Cave',
+ volcano: 'Volcano',
+ ice: 'Ice'
+ };
+ biomeText.setText('Biome: ' + biomeNames[currentBiome]);
+ biomeText.tint = biomeColors[currentBiome];
+ // Biome change effect
+ LK.effects.flashScreen(biomeColors[currentBiome], 1000);
+ // Clear existing biome effects
+ for (var i = biomeEffects.length - 1; i >= 0; i--) {
+ biomeEffects[i].destroy();
+ biomeEffects.splice(i, 1);
+ }
+ // Create new biome effects
+ createBiomeEffects();
+ }
+}
+function createBiomeEffects() {
+ // Create atmospheric effects based on biome
+ if (currentBiome === 'forest') {
+ // Create fog particles
+ for (var i = 0; i < 8; i++) {
+ var fogParticle = LK.getAsset('rangeCircle', {
+ width: 400 + Math.random() * 200,
+ height: 400 + Math.random() * 200,
+ anchorX: 0.5,
+ anchorY: 0.5,
+ color: 0x90EE90
+ });
+ fogParticle.alpha = 0.1 + Math.random() * 0.1;
+ fogParticle.x = Math.random() * 2048;
+ fogParticle.y = Math.random() * 2732;
+ game.addChild(fogParticle);
+ biomeEffects.push(fogParticle);
+ // Animate fog movement
+ tween(fogParticle, {
+ x: fogParticle.x + (Math.random() - 0.5) * 300,
+ y: fogParticle.y + (Math.random() - 0.5) * 300,
+ alpha: fogParticle.alpha * 0.5
+ }, {
+ duration: 8000 + Math.random() * 4000,
+ easing: tween.linear
+ });
+ }
+ } else if (currentBiome === 'cave') {
+ // Create stalactites and shadows
+ for (var i = 0; i < 6; i++) {
+ var stalactite = LK.getAsset('rangeCircle', {
+ width: 80 + Math.random() * 40,
+ height: 200 + Math.random() * 100,
+ anchorX: 0.5,
+ anchorY: 0,
+ color: 0x696969
+ });
+ stalactite.alpha = 0.6;
+ stalactite.x = Math.random() * 2048;
+ stalactite.y = 0;
+ game.addChild(stalactite);
+ biomeEffects.push(stalactite);
+ }
+ } else if (currentBiome === 'volcano') {
+ // Create lava cracks and ember particles
+ for (var i = 0; i < 10; i++) {
+ var lavaCrack = LK.getAsset('rangeCircle', {
+ width: 200 + Math.random() * 150,
+ height: 30 + Math.random() * 20,
+ anchorX: 0.5,
+ anchorY: 0.5,
+ color: 0xFF4500
+ });
+ lavaCrack.alpha = 0.7;
+ lavaCrack.x = Math.random() * 2048;
+ lavaCrack.y = Math.random() * 2732;
+ lavaCrack.rotation = Math.random() * Math.PI * 2;
+ game.addChild(lavaCrack);
+ biomeEffects.push(lavaCrack);
+ // Animate lava glow
+ tween(lavaCrack, {
+ alpha: 0.3
+ }, {
+ duration: 1000 + Math.random() * 1000,
+ easing: tween.easeInOut
+ });
+ }
+ // Create ember particles
+ for (var i = 0; i < 15; i++) {
+ var ember = LK.getAsset('rangeCircle', {
+ width: 20 + Math.random() * 15,
+ height: 20 + Math.random() * 15,
+ anchorX: 0.5,
+ anchorY: 0.5,
+ color: 0xFFD700
+ });
+ ember.alpha = 0.8;
+ ember.x = Math.random() * 2048;
+ ember.y = 2732 + Math.random() * 200;
+ game.addChild(ember);
+ biomeEffects.push(ember);
+ // Animate ember rising
+ tween(ember, {
+ y: ember.y - 2932,
+ alpha: 0
+ }, {
+ duration: 4000 + Math.random() * 2000,
+ easing: tween.linear
+ });
+ }
+ } else if (currentBiome === 'ice') {
+ // Create ice crystals and snow particles
+ for (var i = 0; i < 12; i++) {
+ var iceCrystal = LK.getAsset('rangeCircle', {
+ width: 60 + Math.random() * 30,
+ height: 60 + Math.random() * 30,
+ anchorX: 0.5,
+ anchorY: 0.5,
+ color: 0xE0FFFF
+ });
+ iceCrystal.alpha = 0.6;
+ iceCrystal.x = Math.random() * 2048;
+ iceCrystal.y = Math.random() * 2732;
+ game.addChild(iceCrystal);
+ biomeEffects.push(iceCrystal);
+ // Animate ice crystal sparkle
+ tween(iceCrystal, {
+ scaleX: 1.5,
+ scaleY: 1.5,
+ alpha: 0.3
+ }, {
+ duration: 2000 + Math.random() * 1000,
+ easing: tween.easeInOut
+ });
+ }
+ // Create snowflakes
+ for (var i = 0; i < 20; i++) {
+ var snowflake = LK.getAsset('rangeCircle', {
+ width: 15 + Math.random() * 10,
+ height: 15 + Math.random() * 10,
+ anchorX: 0.5,
+ anchorY: 0.5,
+ color: 0xFFFFFF
+ });
+ snowflake.alpha = 0.7;
+ snowflake.x = Math.random() * 2048;
+ snowflake.y = -50 - Math.random() * 100;
+ game.addChild(snowflake);
+ biomeEffects.push(snowflake);
+ // Animate snowflake falling
+ tween(snowflake, {
+ y: snowflake.y + 2832,
+ x: snowflake.x + (Math.random() - 0.5) * 300
+ }, {
+ duration: 6000 + Math.random() * 3000,
+ easing: tween.linear
+ });
+ }
+ }
+}
+function getBiomeEnemyTypes() {
+ var baseTypes = ['enemy1', 'enemy2', 'enemy3', 'enemy5', 'enemy6', 'enemy7'];
+ var biomeTypes = {
+ forest: ['enemy1', 'enemy2', 'enemy5'],
+ // Nature themed
+ cave: ['enemy3', 'enemy6', 'enemy7'],
+ // Dark, heavy enemies
+ volcano: ['enemy4', 'enemy6', 'enemy2'],
+ // Fire themed, fast enemies
+ ice: ['enemy1', 'enemy3', 'enemy7'] // Slow, defensive enemies
+ };
+ return biomeTypes[currentBiome] || baseTypes;
+}
function applyPrestigeBonuses() {
// Apply starting gold bonus
if (prestigeBonuses.startingGold > 0) {
playerGold += prestigeBonuses.startingGold;
@@ -2381,11 +2581,13 @@
if (waveNumber % bossWaveInterval === 0 && !bossSpawned) {
spawnBoss();
return;
}
- // Determine enemy type based on wave and random chance
- var enemyType = 'enemy1';
+ // Determine enemy type based on biome and wave
+ var biomeEnemyTypes = getBiomeEnemyTypes();
+ var enemyType = biomeEnemyTypes[Math.floor(Math.random() * biomeEnemyTypes.length)];
var rand = Math.random();
+ // Special enemies based on wave progression
if (waveNumber >= 10 && rand < 0.05) {
enemyType = 'enemy4'; // Boss
} else if (waveNumber >= 8 && rand < 0.08) {
enemyType = 'enemy7'; // Healer
@@ -2426,12 +2628,40 @@
// Scale enemy stats with wave number based on type
var healthMultiplier = 1 + (waveNumber - 1) * 0.3;
var speedMultiplier = 1 + (waveNumber - 1) * 0.15;
var goldMultiplier = 1 + (waveNumber - 1) * 0.4;
+ // Apply biome-specific stat modifications
+ if (currentBiome === 'forest') {
+ // Forest enemies are more agile
+ speedMultiplier *= 1.2;
+ healthMultiplier *= 0.9;
+ } else if (currentBiome === 'cave') {
+ // Cave enemies are tankier
+ healthMultiplier *= 1.3;
+ speedMultiplier *= 0.8;
+ } else if (currentBiome === 'volcano') {
+ // Volcano enemies are aggressive
+ speedMultiplier *= 1.4;
+ enemy.damage = Math.floor(enemy.damage * 1.2);
+ } else if (currentBiome === 'ice') {
+ // Ice enemies are slow but tough
+ speedMultiplier *= 0.7;
+ healthMultiplier *= 1.4;
+ }
enemy.health = Math.floor(enemy.health * healthMultiplier);
enemy.maxHealth = enemy.health;
enemy.speed = enemy.speed * speedMultiplier;
enemy.goldReward = Math.floor(enemy.goldReward * goldMultiplier);
+ // Apply biome visual effects to enemy
+ if (currentBiome === 'forest') {
+ enemy.tint = 0x90EE90;
+ } else if (currentBiome === 'cave') {
+ enemy.tint = 0x696969;
+ } else if (currentBiome === 'volcano') {
+ enemy.tint = 0xFF4500;
+ } else if (currentBiome === 'ice') {
+ enemy.tint = 0xE0FFFF;
+ }
enemies.push(enemy);
game.addChild(enemy);
}
function spawnBoss() {
@@ -2568,8 +2798,10 @@
// Reset boss spawn flag for next boss wave
if (waveNumber % bossWaveInterval === 1) {
bossSpawned = false;
}
+ // Check for biome change
+ changeBiome();
}
// Update all game objects
for (var i = bullets.length - 1; i >= 0; i--) {
if (bullets[i].update) {
@@ -2618,5 +2850,21 @@
// Update achievements every 5 seconds
if (LK.ticks % 300 === 0) {
updateAchievements();
}
+ // Update biome effects
+ biomeEffectTimer += gameSpeed;
+ if (biomeEffectTimer >= 300) {
+ // Every 5 seconds
+ biomeEffectTimer = 0;
+ // Clean up destroyed biome effects
+ for (var i = biomeEffects.length - 1; i >= 0; i--) {
+ if (!biomeEffects[i].parent) {
+ biomeEffects.splice(i, 1);
+ }
+ }
+ // Add new biome effects periodically
+ if (biomeEffects.length < 5) {
+ createBiomeEffects();
+ }
+ }
};
\ No newline at end of file