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 var totalCritChance = skillBonuses.critChance + (self.critChance || 0); if (Math.random() < totalCritChance) { finalDamage *= 2; LK.effects.flashObject(enemy, 0xffff00, 200); } enemy.takeDamage(finalDamage); // Apply equipment effects if (self.burnDamage && self.burnDamage > 0) { enemy.burnDamage = self.burnDamage; enemy.burnDuration = 300; // 5 seconds LK.effects.flashObject(enemy, 0xff4400, 300); } if (self.freezeChance && Math.random() < self.freezeChance) { enemy.originalSpeed = enemy.speed; enemy.speed = 0; enemy.frozenTimer = 180; // 3 seconds tween(enemy, { tint: 0x00ffff }, { duration: 200 }); } if (self.poisonDamage && self.poisonDamage > 0) { enemy.poisonDamage = self.poisonDamage; enemy.poisonDuration = 360; // 6 seconds LK.effects.flashObject(enemy, 0x00ff00, 300); } // Vampire healing from relics and equipment var totalLifesteal = skillBonuses.vampireHealing + (self.lifesteal || 0); if (totalLifesteal > 0) { var healAmount = finalDamage * totalLifesteal; 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 += Math.floor(15 * difficultyModifiers[difficultyMode].xpMultiplier); 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 // Apply difficulty XP multiplier pointsToGive = Math.floor(pointsToGive * difficultyModifiers[difficultyMode].xpMultiplier); 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); } // Pet unlock system based on kills if (totalEnemyKills === 10 && availablePets.indexOf('fireSpirit') === -1) { unlockPet('fireSpirit'); } else if (totalEnemyKills === 25 && availablePets.indexOf('fairy') === -1) { unlockPet('fairy'); } else if (totalEnemyKills === 50 && availablePets.indexOf('goblin') === -1) { unlockPet('goblin'); } 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 }); // Generate random equipment properties self.type = equipmentTypes[Math.floor(Math.random() * equipmentTypes.length)]; self.rarity = generateRarity(); self.level = 1; self.bonusEffects = generateBonusEffects(self.rarity); self.magnetRange = 20000; self.magnetSpeed = 3; self.id = Date.now() + Math.random(); // Unique ID // Set visual based on type and rarity var rarityColors = { 'Common': 0xffffff, 'Rare': 0x00ff00, 'Epic': 0x0080ff, 'Legendary': 0xffd700 }; equipmentGraphics.tint = rarityColors[self.rarity]; // Scale based on rarity var rarityScales = { 'Common': 1.0, 'Rare': 1.2, 'Epic': 1.4, 'Legendary': 1.6 }; equipmentGraphics.scaleX = rarityScales[self.rarity]; equipmentGraphics.scaleY = rarityScales[self.rarity]; 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; // Add to inventory playerInventory.push({ id: self.id, type: self.type, rarity: self.rarity, level: self.level, bonusEffects: self.bonusEffects }); storage.playerInventory = playerInventory; self.destroy(); var index = equipmentItems.indexOf(self); if (index > -1) { equipmentItems.splice(index, 1); } LK.getSound('pickup').play(); } }; return self; }); var Fairy = Container.expand(function () { var self = Container.call(this); var petGraphics = self.attachAsset('fairy', { anchorX: 0.5, anchorY: 0.5 }); self.petType = 'fairy'; self.level = 1; self.experience = 0; self.maxExperience = 100; self.healTimer = 0; self.healCooldown = 300; // 5 seconds self.followDistance = 100; self.update = function () { // Follow player with floating motion var dx = hero.x - self.x; var dy = hero.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > self.followDistance) { self.x += dx / distance * 1.5 * gameSpeed; self.y += dy / distance * 1.5 * gameSpeed; } // Floating animation self.y += Math.sin(LK.ticks * 0.05) * 0.5; // Heal player over time self.healTimer -= gameSpeed; if (self.healTimer <= 0 && hero.health < hero.maxHealth) { var healAmount = 2 + self.level; hero.health = Math.min(hero.maxHealth, hero.health + healAmount); self.healTimer = self.healCooldown; LK.effects.flashObject(hero, 0x00ff00, 300); } // Level up glow effect if (self.level > 1) { petGraphics.alpha = 0.8 + Math.sin(LK.ticks * 0.1) * 0.2; } }; self.gainExperience = function (amount) { self.experience += amount; if (self.experience >= self.maxExperience) { self.levelUp(); } }; self.levelUp = function () { self.level++; self.experience = 0; self.maxExperience = Math.floor(self.maxExperience * 1.5); self.healCooldown = Math.max(120, self.healCooldown - 20); LK.effects.flashObject(self, 0xffd700, 500); LK.getSound('upgrade').play(); }; return self; }); var FireSpirit = Container.expand(function () { var self = Container.call(this); var petGraphics = self.attachAsset('fireSpirit', { anchorX: 0.5, anchorY: 0.5 }); self.petType = 'fireSpirit'; self.level = 1; self.experience = 0; self.maxExperience = 100; self.shootTimer = 0; self.shootCooldown = 180; // 3 seconds self.followDistance = 120; self.targetX = 0; self.targetY = 0; self.update = function () { // Follow player with some distance var dx = hero.x - self.x; var dy = hero.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > self.followDistance) { self.x += dx / distance * 2 * gameSpeed; self.y += dy / distance * 2 * gameSpeed; } // Shoot fireballs at enemies self.shootTimer -= gameSpeed; if (self.shootTimer <= 0) { var nearestEnemy = null; var nearestDistance = Infinity; for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; var enemyDx = enemy.x - self.x; var enemyDy = enemy.y - self.y; var enemyDistance = Math.sqrt(enemyDx * enemyDx + enemyDy * enemyDy); if (enemyDistance < 400 && enemyDistance < nearestDistance) { nearestDistance = enemyDistance; nearestEnemy = enemy; } } if (nearestEnemy) { var fireball = new PetBullet(); fireball.x = self.x; fireball.y = self.y; var fireballDx = nearestEnemy.x - self.x; var fireballDy = nearestEnemy.y - self.y; var fireballDistance = Math.sqrt(fireballDx * fireballDx + fireballDy * fireballDy); fireball.velocityX = fireballDx / fireballDistance * 6; fireball.velocityY = fireballDy / fireballDistance * 6; fireball.damage = 15 + self.level * 5; fireball.tint = 0xff4500; petBullets.push(fireball); game.addChild(fireball); self.shootTimer = self.shootCooldown; } } // Level up glow effect if (self.level > 1) { petGraphics.alpha = 0.8 + Math.sin(LK.ticks * 0.1) * 0.2; } }; self.gainExperience = function (amount) { self.experience += amount; if (self.experience >= self.maxExperience) { self.levelUp(); } }; self.levelUp = function () { self.level++; self.experience = 0; self.maxExperience = Math.floor(self.maxExperience * 1.5); self.shootCooldown = Math.max(60, self.shootCooldown - 10); LK.effects.flashObject(self, 0xffd700, 500); LK.getSound('upgrade').play(); }; return self; }); var Goblin = Container.expand(function () { var self = Container.call(this); var petGraphics = self.attachAsset('goblin', { anchorX: 0.5, anchorY: 0.5 }); self.petType = 'goblin'; self.level = 1; self.experience = 0; self.maxExperience = 100; self.collectRange = 150; self.followDistance = 80; self.update = function () { // Follow player closely var dx = hero.x - self.x; var dy = hero.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > self.followDistance) { self.x += dx / distance * 2.5 * gameSpeed; self.y += dy / distance * 2.5 * gameSpeed; } // Collect gold automatically var collectRangeBonus = self.collectRange + self.level * 20; for (var i = 0; i < goldItems.length; i++) { var gold = goldItems[i]; var goldDx = gold.x - self.x; var goldDy = gold.y - self.y; var goldDistance = Math.sqrt(goldDx * goldDx + goldDy * goldDy); if (goldDistance < collectRangeBonus) { gold.x += (self.x - gold.x) * 0.2 * gameSpeed; gold.y += (self.y - gold.y) * 0.2 * gameSpeed; } } // Level up glow effect if (self.level > 1) { petGraphics.alpha = 0.8 + Math.sin(LK.ticks * 0.1) * 0.2; } }; self.gainExperience = function (amount) { self.experience += amount; if (self.experience >= self.maxExperience) { self.levelUp(); } }; self.levelUp = function () { self.level++; self.experience = 0; self.maxExperience = Math.floor(self.maxExperience * 1.5); self.collectRange += 30; LK.effects.flashObject(self, 0xffd700, 500); LK.getSound('upgrade').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 + equipmentEffects.damage; // Apply equipment effects to bullet bullet.critChance = equipmentEffects.critChance / 100; bullet.burnDamage = equipmentEffects.burnDamage; bullet.freezeChance = equipmentEffects.freezeChance / 100; bullet.poisonDamage = equipmentEffects.poisonDamage; bullet.lifesteal = equipmentEffects.lifesteal / 100; bullets.push(bullet); game.addChild(bullet); var attackSpeedBonus = 1 + equipmentEffects.attackSpeed / 100; self.shootTimer = self.attackSpeed / (skillBonuses.attackSpeedMultiplier + skillBonuses.relicAttackSpeed) / attackSpeedBonus; // Update range with equipment bonus self.range = 1000 + equipmentEffects.range; 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 += Math.floor(10 * difficultyModifiers[difficultyMode].xpMultiplier); 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 PetBullet = Container.expand(function () { var self = Container.call(this); var bulletGraphics = self.attachAsset('bullet', { anchorX: 0.5, anchorY: 0.5 }); bulletGraphics.scaleX = 0.6; bulletGraphics.scaleY = 0.6; self.velocityX = 0; self.velocityY = 0; self.damage = 10; self.lifetime = 120; 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)) { enemy.takeDamage(self.damage); // Give experience to pets for (var j = 0; j < playerPets.length; j++) { playerPets[j].gainExperience(1); } self.destroy(); var index = petBullets.indexOf(self); if (index > -1) { petBullets.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 = petBullets.indexOf(self); if (index > -1) { petBullets.splice(index, 1); } } }; 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 += Math.floor(10 * difficultyModifiers[difficultyMode].xpMultiplier); 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 += Math.floor(12 * difficultyModifiers[difficultyMode].xpMultiplier); 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 petBullets = []; var playerPets = []; var availablePets = storage.availablePets || []; var waveNumber = 1; var enemySpawnTimer = 0; var enemiesPerWave = 3; // Equipment system variables var playerInventory = storage.playerInventory || []; var equippedItems = storage.equippedItems || { sword: null, wand: null, bow: null }; var equipmentRarities = ['Common', 'Rare', 'Epic', 'Legendary']; var equipmentTypes = ['Sword', 'Wand', 'Bow']; var equipmentBonuses = { critChance: 'Crit Chance', burnDamage: 'Burn Damage', freezeChance: 'Freeze Chance', poisonDamage: 'Poison Damage', lifesteal: 'Lifesteal', attackSpeed: 'Attack Speed', damage: 'Damage', range: 'Range' }; var equipmentEffects = { critChance: 0, burnDamage: 0, freezeChance: 0, poisonDamage: 0, lifesteal: 0, attackSpeed: 0, damage: 0, range: 0 }; // Boss system variables var bossSpawned = false; var bossWaveInterval = 5; // Boss every 5 waves var heroPoisonDuration = 0; var poisonDamageTimer = 0; // Difficulty system variables var difficultyMode = storage.difficultyMode || 'normal'; var difficultyModifiers = { easy: { enemyHealthMultiplier: 0.7, enemyDamageMultiplier: 0.8, goldMultiplier: 0.8, xpMultiplier: 0.8 }, normal: { enemyHealthMultiplier: 1.0, enemyDamageMultiplier: 1.0, goldMultiplier: 1.0, xpMultiplier: 1.0 }, nightmare: { enemyHealthMultiplier: 1.5, enemyDamageMultiplier: 1.5, goldMultiplier: 1.5, xpMultiplier: 1.5 } }; // 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); // Difficulty mode display var difficultyText = new Text2('Difficulty: ' + difficultyMode.charAt(0).toUpperCase() + difficultyMode.slice(1), { size: 30, fill: difficultyMode === 'easy' ? '#00FF00' : difficultyMode === 'normal' ? '#FFFF00' : '#FF0000' }); difficultyText.anchor.set(0, 0); difficultyText.x = 120; difficultyText.y = 300; LK.gui.topLeft.addChild(difficultyText); // 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); // Difficulty selection button var difficultyBtn = new Text2('Difficulty', { size: 35, fill: '#FFFFFF' }); difficultyBtn.anchor.set(0.5, 0); difficultyBtn.x = 0; difficultyBtn.y = 350; LK.gui.top.addChild(difficultyBtn); // 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); // Difficulty selection UI (initially hidden) var difficultyContainer = new Container(); difficultyContainer.visible = false; LK.gui.center.addChild(difficultyContainer); var difficultyBg = LK.getAsset('rangeCircle', { width: 1400, height: 1000, anchorX: 0.5, anchorY: 0.5, color: 0x000000 }); difficultyBg.alpha = 0.8; difficultyContainer.addChild(difficultyBg); var difficultyTitle = new Text2('SELECT DIFFICULTY', { size: 60, fill: '#FFFFFF' }); difficultyTitle.anchor.set(0.5, 0.5); difficultyTitle.x = 0; difficultyTitle.y = -400; difficultyContainer.addChild(difficultyTitle); var difficultyCloseBtn = new Text2('X', { size: 60, fill: '#ff0000' }); difficultyCloseBtn.anchor.set(0.5, 0.5); difficultyCloseBtn.x = 650; difficultyCloseBtn.y = -450; difficultyContainer.addChild(difficultyCloseBtn); 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 createDifficultyUI() { // Clear existing difficulty items for (var i = difficultyContainer.children.length - 1; i >= 0; i--) { var child = difficultyContainer.children[i]; if (child !== difficultyBg && child !== difficultyTitle && child !== difficultyCloseBtn) { difficultyContainer.removeChild(child); } } // Create difficulty option buttons var difficultyOptions = [{ mode: 'easy', name: 'Easy', desc: 'Enemies: -30% Health, -20% Damage | Rewards: -20% Gold & XP', color: 0x00FF00 }, { mode: 'normal', name: 'Normal', desc: 'Balanced gameplay experience', color: 0xFFFF00 }, { mode: 'nightmare', name: 'Nightmare', desc: 'Enemies: +50% Health, +50% Damage | Rewards: +50% Gold & XP', color: 0xFF0000 }]; for (var i = 0; i < difficultyOptions.length; i++) { var option = difficultyOptions[i]; var optionContainer = new Container(); var optionBg = LK.getAsset('rangeCircle', { width: 1200, height: 120, anchorX: 0.5, anchorY: 0.5, color: difficultyMode === option.mode ? option.color : 0x666666 }); optionBg.alpha = 0.8; optionContainer.addChild(optionBg); var nameText = new Text2(option.name, { size: 40, fill: '#FFFFFF' }); nameText.anchor.set(0.5, 0.5); nameText.x = 0; nameText.y = -20; optionContainer.addChild(nameText); var descText = new Text2(option.desc, { size: 24, fill: '#CCCCCC' }); descText.anchor.set(0.5, 0.5); descText.x = 0; descText.y = 20; optionContainer.addChild(descText); optionContainer.x = 0; optionContainer.y = -200 + i * 150; optionContainer.difficultyMode = option.mode; optionContainer.down = function () { selectDifficulty(this.difficultyMode); }; difficultyContainer.addChild(optionContainer); } } function selectDifficulty(mode) { difficultyMode = mode; storage.difficultyMode = mode; // Update difficulty display difficultyText.setText('Difficulty: ' + mode.charAt(0).toUpperCase() + mode.slice(1)); difficultyText.tint = mode === 'easy' ? 0x00FF00 : mode === 'normal' ? 0xFFFF00 : 0xFF0000; // Close difficulty UI difficultyContainer.visible = false; // Visual feedback LK.effects.flashScreen(mode === 'easy' ? 0x00FF00 : mode === 'normal' ? 0xFFFF00 : 0xFF0000, 500); LK.getSound('pickup').play(); } 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 generateRarity() { var rand = Math.random(); if (rand < 0.5) return 'Common'; if (rand < 0.8) return 'Rare'; if (rand < 0.95) return 'Epic'; return 'Legendary'; } function generateBonusEffects(rarity) { var effects = {}; var bonusKeys = Object.keys(equipmentBonuses); var effectCount = 1; if (rarity === 'Rare') effectCount = 2;else if (rarity === 'Epic') effectCount = 3;else if (rarity === 'Legendary') effectCount = 4; for (var i = 0; i < effectCount; i++) { var randomBonus = bonusKeys[Math.floor(Math.random() * bonusKeys.length)]; if (!effects[randomBonus]) { var multiplier = 1; if (rarity === 'Rare') multiplier = 1.5;else if (rarity === 'Epic') multiplier = 2;else if (rarity === 'Legendary') multiplier = 3; effects[randomBonus] = Math.floor(Math.random() * 20 + 10) * multiplier; } } return effects; } function equipItem(item) { // Unequip current item of same type var currentItem = equippedItems[item.type.toLowerCase()]; if (currentItem) { unequipItem(currentItem); } // Equip new item equippedItems[item.type.toLowerCase()] = item; storage.equippedItems = equippedItems; // Apply equipment effects applyEquipmentEffects(); // Update hero visual updateHeroVisuals(); LK.getSound('upgrade').play(); } function unequipItem(item) { if (item) { equippedItems[item.type.toLowerCase()] = null; storage.equippedItems = equippedItems; applyEquipmentEffects(); updateHeroVisuals(); } } function applyEquipmentEffects() { // Reset equipment effects for (var key in equipmentEffects) { equipmentEffects[key] = 0; } // Apply effects from equipped items for (var slot in equippedItems) { var item = equippedItems[slot]; if (item && item.bonusEffects) { for (var effect in item.bonusEffects) { equipmentEffects[effect] += item.bonusEffects[effect]; } } } // Update equipment stats display updateEquipmentStatsDisplay(); } function updateEquipmentStatsDisplay() { var statsText = 'Equipment Stats: '; var hasStats = false; for (var effect in equipmentEffects) { if (equipmentEffects[effect] > 0) { if (hasStats) statsText += ', '; statsText += equipmentBonuses[effect] + ' +' + equipmentEffects[effect]; hasStats = true; } } if (!hasStats) statsText += 'None'; equipmentStatsText.setText(statsText); } function updateHeroVisuals() { // Remove existing equipment visuals if (hero.equipmentVisuals) { for (var i = 0; i < hero.equipmentVisuals.length; i++) { hero.equipmentVisuals[i].destroy(); } } hero.equipmentVisuals = []; // Add new equipment visuals for (var slot in equippedItems) { var item = equippedItems[slot]; if (item) { var equipmentVisual = hero.attachAsset('equipment', { anchorX: 0.5, anchorY: 0.5 }); // Position based on equipment type if (item.type === 'Sword') { equipmentVisual.x = 30; equipmentVisual.y = 0; equipmentVisual.rotation = Math.PI / 4; } else if (item.type === 'Wand') { equipmentVisual.x = -30; equipmentVisual.y = -20; equipmentVisual.rotation = -Math.PI / 3; } else if (item.type === 'Bow') { equipmentVisual.x = 0; equipmentVisual.y = -40; } // Apply rarity color and effects var rarityColors = { 'Common': 0xffffff, 'Rare': 0x00ff00, 'Epic': 0x0080ff, 'Legendary': 0xffd700 }; equipmentVisual.tint = rarityColors[item.rarity]; if (item.rarity === 'Legendary') { // Glowing effect for legendary items tween(equipmentVisual, { alpha: 0.5 }, { duration: 1000, easing: tween.easeInOut, onFinish: function onFinish() { tween(equipmentVisual, { alpha: 1 }, { duration: 1000, easing: tween.easeInOut }); } }); } hero.equipmentVisuals.push(equipmentVisual); } } } function upgradeEquipment(item) { var upgradeCost = item.level * 100; if (playerGold >= upgradeCost) { playerGold -= upgradeCost; item.level++; // Increase bonus effects for (var effect in item.bonusEffects) { item.bonusEffects[effect] = Math.floor(item.bonusEffects[effect] * 1.2); } // Update storage storage.playerInventory = playerInventory; storage.equippedItems = equippedItems; goldText.setText('Gold: ' + playerGold); applyEquipmentEffects(); LK.getSound('upgrade').play(); return true; } return false; } function createInventoryUI() { // Clear existing inventory items for (var i = inventoryContainer.children.length - 1; i >= 0; i--) { var child = inventoryContainer.children[i]; if (child !== inventoryBg && child !== inventoryTitle && child !== inventoryCloseBtn) { inventoryContainer.removeChild(child); } } // Create equipped items section var equippedTitle = new Text2('EQUIPPED ITEMS', { size: 40, fill: '#ffd700' }); equippedTitle.anchor.set(0.5, 0.5); equippedTitle.x = -400; equippedTitle.y = -450; inventoryContainer.addChild(equippedTitle); // Show equipped items var yOffset = -350; for (var slot in equippedItems) { var item = equippedItems[slot]; var slotContainer = new Container(); var slotBg = LK.getAsset('rangeCircle', { width: 600, height: 80, anchorX: 0.5, anchorY: 0.5, color: item ? 0x4a90e2 : 0x666666 }); slotBg.alpha = 0.6; slotContainer.addChild(slotBg); var slotText = new Text2(slot.charAt(0).toUpperCase() + slot.slice(1) + ': ' + (item ? item.type + ' (' + item.rarity + ')' : 'Empty'), { size: 24, fill: '#ffffff' }); slotText.anchor.set(0.5, 0.5); slotContainer.addChild(slotText); slotContainer.x = -400; slotContainer.y = yOffset; if (item) { slotContainer.down = function () { unequipItem(this.item); createInventoryUI(); }; slotContainer.item = item; } inventoryContainer.addChild(slotContainer); yOffset += 100; } // Create inventory items section var inventoryTitle = new Text2('INVENTORY', { size: 40, fill: '#8a2be2' }); inventoryTitle.anchor.set(0.5, 0.5); inventoryTitle.x = 400; inventoryTitle.y = -450; inventoryContainer.addChild(inventoryTitle); // Show inventory items yOffset = -350; for (var i = 0; i < playerInventory.length; i++) { var item = playerInventory[i]; var itemContainer = new Container(); var rarityColors = { 'Common': 0xffffff, 'Rare': 0x00ff00, 'Epic': 0x0080ff, 'Legendary': 0xffd700 }; var itemBg = LK.getAsset('rangeCircle', { width: 600, height: 100, anchorX: 0.5, anchorY: 0.5, color: rarityColors[item.rarity] }); itemBg.alpha = 0.3; itemContainer.addChild(itemBg); var itemText = new Text2(item.type + ' (' + item.rarity + ') Lv.' + item.level, { size: 24, fill: '#ffffff' }); itemText.anchor.set(0.5, 0.5); itemText.y = -20; itemContainer.addChild(itemText); // Show bonus effects var bonusText = ''; for (var effect in item.bonusEffects) { if (bonusText) bonusText += ', '; bonusText += equipmentBonuses[effect] + ' +' + item.bonusEffects[effect]; } var effectsText = new Text2(bonusText, { size: 18, fill: '#ffff00' }); effectsText.anchor.set(0.5, 0.5); effectsText.y = 10; itemContainer.addChild(effectsText); // Equip and upgrade buttons var equipBtn = new Text2('Equip', { size: 20, fill: '#00ff00' }); equipBtn.anchor.set(0.5, 0.5); equipBtn.x = -150; equipBtn.y = 35; itemContainer.addChild(equipBtn); var upgradeBtn = new Text2('Upgrade (' + item.level * 100 + 'g)', { size: 20, fill: '#ffd700' }); upgradeBtn.anchor.set(0.5, 0.5); upgradeBtn.x = 150; upgradeBtn.y = 35; itemContainer.addChild(upgradeBtn); itemContainer.x = 400; itemContainer.y = yOffset; itemContainer.item = item; // Button handlers equipBtn.down = function () { equipItem(this.parent.item); createInventoryUI(); }; upgradeBtn.down = function () { if (upgradeEquipment(this.parent.item)) { createInventoryUI(); } }; inventoryContainer.addChild(itemContainer); yOffset += 120; if (yOffset > 500) break; // Limit display } } 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 unlockPet(petType) { if (availablePets.indexOf(petType) === -1) { availablePets.push(petType); storage.availablePets = availablePets; LK.effects.flashScreen(0xff69b4, 1000); LK.getSound('upgrade').play(); } } function spawnPet(petType) { var pet; if (petType === 'fireSpirit') { pet = new FireSpirit(); } else if (petType === 'fairy') { pet = new Fairy(); } else if (petType === 'goblin') { pet = new Goblin(); } else { return; } pet.x = hero.x + (Math.random() - 0.5) * 200; pet.y = hero.y + (Math.random() - 0.5) * 200; playerPets.push(pet); game.addChild(pet); updatePetUI(); } function dismissPet(petIndex) { if (petIndex >= 0 && petIndex < playerPets.length) { var pet = playerPets[petIndex]; pet.destroy(); playerPets.splice(petIndex, 1); updatePetUI(); } } function updatePetUI() { petStatusText.setText('Pets: ' + playerPets.length); } function createPetUI() { // Clear existing pet items for (var i = petContainer.children.length - 1; i >= 0; i--) { var child = petContainer.children[i]; if (child !== petBg && child !== petTitle && child !== petCloseBtn) { petContainer.removeChild(child); } } // Available pets section var availableTitle = new Text2('AVAILABLE PETS', { size: 40, fill: '#ffd700' }); availableTitle.anchor.set(0.5, 0.5); availableTitle.x = -400; availableTitle.y = -350; petContainer.addChild(availableTitle); // Pet type descriptions var petDescriptions = { fireSpirit: 'Fire Spirit: Shoots fireballs at enemies', fairy: 'Fairy: Heals player over time', goblin: 'Goblin: Collects gold automatically' }; var yOffset = -250; for (var i = 0; i < availablePets.length; i++) { var petType = availablePets[i]; var petItem = new Container(); var petItemBg = LK.getAsset('rangeCircle', { width: 600, height: 80, anchorX: 0.5, anchorY: 0.5, color: 0x4a90e2 }); petItemBg.alpha = 0.6; petItem.addChild(petItemBg); var petNameText = new Text2(petType.charAt(0).toUpperCase() + petType.slice(1), { size: 28, fill: '#ffffff' }); petNameText.anchor.set(0.5, 0.5); petNameText.y = -15; petItem.addChild(petNameText); var petDescText = new Text2(petDescriptions[petType], { size: 20, fill: '#cccccc' }); petDescText.anchor.set(0.5, 0.5); petDescText.y = 15; petItem.addChild(petDescText); petItem.x = -400; petItem.y = yOffset; petItem.petType = petType; petItem.down = function () { if (playerPets.length < 3) { spawnPet(this.petType); createPetUI(); } }; petContainer.addChild(petItem); yOffset += 100; } // Active pets section var activeTitle = new Text2('ACTIVE PETS', { size: 40, fill: '#00ff00' }); activeTitle.anchor.set(0.5, 0.5); activeTitle.x = 400; activeTitle.y = -350; petContainer.addChild(activeTitle); yOffset = -250; for (var i = 0; i < playerPets.length; i++) { var pet = playerPets[i]; var activePetItem = new Container(); var activePetBg = LK.getAsset('rangeCircle', { width: 600, height: 100, anchorX: 0.5, anchorY: 0.5, color: 0x00ff00 }); activePetBg.alpha = 0.3; activePetItem.addChild(activePetBg); var activePetNameText = new Text2(pet.petType.charAt(0).toUpperCase() + pet.petType.slice(1) + ' Lv.' + pet.level, { size: 24, fill: '#ffffff' }); activePetNameText.anchor.set(0.5, 0.5); activePetNameText.y = -25; activePetItem.addChild(activePetNameText); var expText = new Text2('EXP: ' + pet.experience + '/' + pet.maxExperience, { size: 18, fill: '#ffff00' }); expText.anchor.set(0.5, 0.5); expText.y = 0; activePetItem.addChild(expText); var dismissBtn = new Text2('Dismiss', { size: 20, fill: '#ff0000' }); dismissBtn.anchor.set(0.5, 0.5); dismissBtn.y = 25; activePetItem.addChild(dismissBtn); activePetItem.x = 400; activePetItem.y = yOffset; activePetItem.petIndex = i; dismissBtn.down = function () { dismissPet(this.parent.petIndex); createPetUI(); }; petContainer.addChild(activePetItem); yOffset += 120; } // Pet limit info var limitText = new Text2('Pet Limit: ' + playerPets.length + '/3', { size: 30, fill: '#ffffff' }); limitText.anchor.set(0.5, 0.5); limitText.x = 0; limitText.y = 400; petContainer.addChild(limitText); } 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; }; // Difficulty button handler difficultyBtn.down = function () { difficultyContainer.visible = !difficultyContainer.visible; if (difficultyContainer.visible) { createDifficultyUI(); } }; // Difficulty close button difficultyCloseBtn.down = function () { difficultyContainer.visible = false; }; // Equipment inventory button var inventoryBtn = new Text2('Inventory', { size: 35, fill: '#8a2be2' }); inventoryBtn.anchor.set(0.5, 0); inventoryBtn.x = 0; inventoryBtn.y = 400; LK.gui.top.addChild(inventoryBtn); // Pet system button var petBtn = new Text2('Pets', { size: 35, fill: '#ff69b4' }); petBtn.anchor.set(0.5, 0); petBtn.x = 0; petBtn.y = 450; LK.gui.top.addChild(petBtn); // Inventory button handler inventoryBtn.down = function () { inventoryContainer.visible = !inventoryContainer.visible; if (inventoryContainer.visible) { createInventoryUI(); } }; // Inventory close button var inventoryCloseBtn = new Text2('X', { size: 60, fill: '#ff0000' }); inventoryCloseBtn.anchor.set(0.5, 0.5); inventoryCloseBtn.x = 850; inventoryCloseBtn.y = -650; inventoryContainer.addChild(inventoryCloseBtn); inventoryCloseBtn.down = function () { inventoryContainer.visible = false; }; // Pet button handler petBtn.down = function () { petContainer.visible = !petContainer.visible; if (petContainer.visible) { createPetUI(); } }; // Pet close button petCloseBtn.down = function () { petContainer.visible = false; }; // Pet status display var petStatusText = new Text2('Pets: 0', { size: 30, fill: '#ff69b4' }); petStatusText.anchor.set(0, 0); petStatusText.x = 120; petStatusText.y = 380; LK.gui.topLeft.addChild(petStatusText); // Equipment inventory UI (initially hidden) var inventoryContainer = new Container(); inventoryContainer.visible = false; LK.gui.center.addChild(inventoryContainer); // Pet management UI (initially hidden) var petContainer = new Container(); petContainer.visible = false; LK.gui.center.addChild(petContainer); var petBg = LK.getAsset('rangeCircle', { width: 1600, height: 1200, anchorX: 0.5, anchorY: 0.5, color: 0x000000 }); petBg.alpha = 0.8; petContainer.addChild(petBg); var petTitle = new Text2('PET COMPANIONS', { size: 60, fill: '#ff69b4' }); petTitle.anchor.set(0.5, 0.5); petTitle.x = 0; petTitle.y = -500; petContainer.addChild(petTitle); var petCloseBtn = new Text2('X', { size: 60, fill: '#ff0000' }); petCloseBtn.anchor.set(0.5, 0.5); petCloseBtn.x = 750; petCloseBtn.y = -550; petContainer.addChild(petCloseBtn); var inventoryBg = LK.getAsset('rangeCircle', { width: 1800, height: 1400, anchorX: 0.5, anchorY: 0.5, color: 0x000000 }); inventoryBg.alpha = 0.8; inventoryContainer.addChild(inventoryBg); var inventoryTitle = new Text2('EQUIPMENT INVENTORY', { size: 60, fill: '#8a2be2' }); inventoryTitle.anchor.set(0.5, 0.5); inventoryTitle.x = 0; inventoryTitle.y = -600; inventoryContainer.addChild(inventoryTitle); var inventoryCloseBtn = new Text2('X', { size: 60, fill: '#ff0000' }); inventoryCloseBtn.anchor.set(0.5, 0.5); inventoryCloseBtn.x = 850; inventoryCloseBtn.y = -650; inventoryContainer.addChild(inventoryCloseBtn); // Equipment stats display var equipmentStatsText = new Text2('Equipment Stats: None', { size: 30, fill: '#8a2be2' }); equipmentStatsText.anchor.set(0, 0); equipmentStatsText.x = 120; equipmentStatsText.y = 340; LK.gui.topLeft.addChild(equipmentStatsText); // 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 difficulty modifiers var difficultyMod = difficultyModifiers[difficultyMode]; healthMultiplier *= difficultyMod.enemyHealthMultiplier; goldMultiplier *= difficultyMod.goldMultiplier; // 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 * difficultyMod.enemyDamageMultiplier); } else if (currentBiome === 'ice') { // Ice enemies are slow but tough speedMultiplier *= 0.7; healthMultiplier *= 1.4; } // Apply difficulty damage modifier to all enemies enemy.damage = Math.floor(enemy.damage * difficultyMod.enemyDamageMultiplier); 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; // Apply difficulty modifiers var difficultyMod = difficultyModifiers[difficultyMode]; healthMultiplier *= difficultyMod.enemyHealthMultiplier; goldMultiplier *= difficultyMod.goldMultiplier; boss.health = Math.floor(boss.health * healthMultiplier); boss.maxHealth = boss.health; boss.speed = boss.speed * speedMultiplier; boss.damage = Math.floor(boss.damage * difficultyMod.enemyDamageMultiplier); 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(); // Initialize equipment system applyEquipmentEffects(); updateHeroVisuals(); // Initialize pet system updatePetUI(); } // 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(); } } for (var i = petBullets.length - 1; i >= 0; i--) { if (petBullets[i].update) { petBullets[i].update(); } } for (var i = playerPets.length - 1; i >= 0; i--) { if (playerPets[i].update) { playerPets[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
@@ -3416,8 +3416,16 @@
createInventoryUI();
}
};
// Inventory close button
+var inventoryCloseBtn = new Text2('X', {
+ size: 60,
+ fill: '#ff0000'
+});
+inventoryCloseBtn.anchor.set(0.5, 0.5);
+inventoryCloseBtn.x = 850;
+inventoryCloseBtn.y = -650;
+inventoryContainer.addChild(inventoryCloseBtn);
inventoryCloseBtn.down = function () {
inventoryContainer.visible = false;
};
// Pet button handler