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; self.y += self.velocityY; self.lifetime--; // Check collision with enemies for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; if (self.intersects(enemy)) { enemy.takeDamage(self.damage); 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 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--; 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--; // Keep distance and shoot if (distance > self.range) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } // 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--; 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; self.y += dy / distance * self.speed; } } 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; self.y += dy / distance * self.speed; } } else { // Normal movement for other enemy types if (distance > 0) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; } } // 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 () { // 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); // 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); } 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; self.y += self.velocityY; self.lifetime--; // Check collision with hero var dx = hero.x - self.x; var dy = hero.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < 40) { hero.takeDamage(self.damage); self.destroy(); var index = enemyBullets.indexOf(self); if (index > -1) { enemyBullets.splice(index, 1); } return; } // Remove if lifetime expired or off screen if (self.lifetime <= 0 || self.x < -100 || self.x > 2148 || self.y < -100 || self.y > 2832) { self.destroy(); var index = enemyBullets.indexOf(self); if (index > -1) { enemyBullets.splice(index, 1); } } }; return self; }); var Equipment = Container.expand(function () { var self = Container.call(this); var equipmentGraphics = self.attachAsset('equipment', { anchorX: 0.5, anchorY: 0.5 }); self.type = 'sword'; self.level = 0; self.magnetRange = 20000; self.magnetSpeed = 3; self.update = function () { // Magnetic pull towards hero var dx = hero.x - self.x; var dy = hero.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < self.magnetRange) { self.x += dx / distance * self.magnetSpeed; self.y += dy / distance * self.magnetSpeed; } // Automatic collection when close if (distance < 60) { playerEquipment.push(self.type); self.destroy(); var index = equipmentItems.indexOf(self); if (index > -1) { equipmentItems.splice(index, 1); } LK.getSound('pickup').play(); } }; return self; }); var Gold = Container.expand(function () { var self = Container.call(this); var goldGraphics = self.attachAsset('goldCoin', { anchorX: 0.5, anchorY: 0.5 }); self.value = 5; self.magnetRange = 2500; self.magnetSpeed = 4; self.update = function () { // Magnetic pull towards hero var dx = hero.x - self.x; var dy = hero.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance < self.magnetRange) { self.x += dx / distance * self.magnetSpeed; self.y += dy / distance * self.magnetSpeed; } // Automatic collection when close if (distance < 60) { playerGold += self.value; 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) { self.x += dx / distance * self.magnetSpeed; self.y += dy / distance * self.magnetSpeed; } // 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--; // Update range circle scale var scale = self.range / 1200; self.rangeCircle.scaleX = scale * 0.5; self.rangeCircle.scaleY = scale * 0.5; // Find nearest enemy in range var nearestEnemy = null; var nearestDistance = Infinity; for (var i = 0; i < enemies.length; i++) { var enemy = enemies[i]; var dx = enemy.x - self.x; var dy = enemy.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance <= self.range && distance < nearestDistance) { nearestDistance = distance; nearestEnemy = enemy; } } self.target = nearestEnemy; // Shoot at target if (self.target && self.shootTimer <= 0) { var bullet = new Bullet(); bullet.x = self.x; bullet.y = self.y; var dx = self.target.x - self.x; var dy = self.target.y - self.y; var distance = Math.sqrt(dx * dx + dy * dy); // Calculate rotation angle and smoothly rotate hero towards target var targetAngle = Math.atan2(dy, dx); tween(heroGraphics, { rotation: targetAngle }, { duration: 100, easing: tween.easeOut }); bullet.velocityX = dx / distance * 8; bullet.velocityY = dy / distance * 8; bullet.damage = self.damage; bullets.push(bullet); game.addChild(bullet); self.shootTimer = self.attackSpeed; LK.getSound('shoot').play(); } }; self.takeDamage = function (damage) { if (shieldActive) { // Shield blocks damage return; } self.health -= damage; if (self.health <= 0) { LK.showGameOver(); } }; 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 = 200; 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) { self.x += dx / distance * self.magnetSpeed; self.y += dy / distance * self.magnetSpeed; } // 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; }); /**** * 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 waveNumber = 1; var enemySpawnTimer = 0; var enemiesPerWave = 3; // 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); // 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 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); // 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; // 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(); } }; function spawnEnemy() { // Determine enemy type based on wave and random chance var enemyType = 'enemy1'; var rand = Math.random(); 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; enemy.health = Math.floor(enemy.health * healthMultiplier); enemy.maxHealth = enemy.health; enemy.speed = enemy.speed * speedMultiplier; enemy.goldReward = Math.floor(enemy.goldReward * goldMultiplier); enemies.push(enemy); game.addChild(enemy); } game.update = function () { // Update health display healthText.setText('Health: ' + hero.health); // Update mana display manaText.setText('Mana: ' + playerMana + '/' + maxMana); // Update skill cooldowns if (lightningCooldown > 0) { lightningCooldown--; 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--; 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--; 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--; if (shieldDuration <= 0) { shieldActive = false; hero.shieldEffect.alpha = 0; tween(hero.shieldEffect, { scaleX: 1, scaleY: 1 }, { duration: 200 }); } } // Enemy spawning enemySpawnTimer++; var spawnRate = Math.max(30, 120 - waveNumber * 5); if (enemySpawnTimer >= spawnRate) { if (enemies.length < enemiesPerWave + Math.floor(waveNumber / 2)) { spawnEnemy(); enemySpawnTimer = 0; } } // 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); } // 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(); } } };
/****
* 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;
self.y += self.velocityY;
self.lifetime--;
// Check collision with enemies
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
if (self.intersects(enemy)) {
enemy.takeDamage(self.damage);
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 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--;
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--;
// Keep distance and shoot
if (distance > self.range) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
// 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--;
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;
self.y += dy / distance * self.speed;
}
} 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;
self.y += dy / distance * self.speed;
}
} else {
// Normal movement for other enemy types
if (distance > 0) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
}
}
// 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 () {
// 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);
// 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);
}
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;
self.y += self.velocityY;
self.lifetime--;
// Check collision with hero
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < 40) {
hero.takeDamage(self.damage);
self.destroy();
var index = enemyBullets.indexOf(self);
if (index > -1) {
enemyBullets.splice(index, 1);
}
return;
}
// Remove if lifetime expired or off screen
if (self.lifetime <= 0 || self.x < -100 || self.x > 2148 || self.y < -100 || self.y > 2832) {
self.destroy();
var index = enemyBullets.indexOf(self);
if (index > -1) {
enemyBullets.splice(index, 1);
}
}
};
return self;
});
var Equipment = Container.expand(function () {
var self = Container.call(this);
var equipmentGraphics = self.attachAsset('equipment', {
anchorX: 0.5,
anchorY: 0.5
});
self.type = 'sword';
self.level = 0;
self.magnetRange = 20000;
self.magnetSpeed = 3;
self.update = function () {
// Magnetic pull towards hero
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < self.magnetRange) {
self.x += dx / distance * self.magnetSpeed;
self.y += dy / distance * self.magnetSpeed;
}
// Automatic collection when close
if (distance < 60) {
playerEquipment.push(self.type);
self.destroy();
var index = equipmentItems.indexOf(self);
if (index > -1) {
equipmentItems.splice(index, 1);
}
LK.getSound('pickup').play();
}
};
return self;
});
var Gold = Container.expand(function () {
var self = Container.call(this);
var goldGraphics = self.attachAsset('goldCoin', {
anchorX: 0.5,
anchorY: 0.5
});
self.value = 5;
self.magnetRange = 2500;
self.magnetSpeed = 4;
self.update = function () {
// Magnetic pull towards hero
var dx = hero.x - self.x;
var dy = hero.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance < self.magnetRange) {
self.x += dx / distance * self.magnetSpeed;
self.y += dy / distance * self.magnetSpeed;
}
// Automatic collection when close
if (distance < 60) {
playerGold += self.value;
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) {
self.x += dx / distance * self.magnetSpeed;
self.y += dy / distance * self.magnetSpeed;
}
// 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--;
// Update range circle scale
var scale = self.range / 1200;
self.rangeCircle.scaleX = scale * 0.5;
self.rangeCircle.scaleY = scale * 0.5;
// Find nearest enemy in range
var nearestEnemy = null;
var nearestDistance = Infinity;
for (var i = 0; i < enemies.length; i++) {
var enemy = enemies[i];
var dx = enemy.x - self.x;
var dy = enemy.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance <= self.range && distance < nearestDistance) {
nearestDistance = distance;
nearestEnemy = enemy;
}
}
self.target = nearestEnemy;
// Shoot at target
if (self.target && self.shootTimer <= 0) {
var bullet = new Bullet();
bullet.x = self.x;
bullet.y = self.y;
var dx = self.target.x - self.x;
var dy = self.target.y - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
// Calculate rotation angle and smoothly rotate hero towards target
var targetAngle = Math.atan2(dy, dx);
tween(heroGraphics, {
rotation: targetAngle
}, {
duration: 100,
easing: tween.easeOut
});
bullet.velocityX = dx / distance * 8;
bullet.velocityY = dy / distance * 8;
bullet.damage = self.damage;
bullets.push(bullet);
game.addChild(bullet);
self.shootTimer = self.attackSpeed;
LK.getSound('shoot').play();
}
};
self.takeDamage = function (damage) {
if (shieldActive) {
// Shield blocks damage
return;
}
self.health -= damage;
if (self.health <= 0) {
LK.showGameOver();
}
};
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 = 200;
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) {
self.x += dx / distance * self.magnetSpeed;
self.y += dy / distance * self.magnetSpeed;
}
// 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;
});
/****
* 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 waveNumber = 1;
var enemySpawnTimer = 0;
var enemiesPerWave = 3;
// 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);
// 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 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);
// 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;
// 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();
}
};
function spawnEnemy() {
// Determine enemy type based on wave and random chance
var enemyType = 'enemy1';
var rand = Math.random();
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;
enemy.health = Math.floor(enemy.health * healthMultiplier);
enemy.maxHealth = enemy.health;
enemy.speed = enemy.speed * speedMultiplier;
enemy.goldReward = Math.floor(enemy.goldReward * goldMultiplier);
enemies.push(enemy);
game.addChild(enemy);
}
game.update = function () {
// Update health display
healthText.setText('Health: ' + hero.health);
// Update mana display
manaText.setText('Mana: ' + playerMana + '/' + maxMana);
// Update skill cooldowns
if (lightningCooldown > 0) {
lightningCooldown--;
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--;
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--;
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--;
if (shieldDuration <= 0) {
shieldActive = false;
hero.shieldEffect.alpha = 0;
tween(hero.shieldEffect, {
scaleX: 1,
scaleY: 1
}, {
duration: 200
});
}
}
// Enemy spawning
enemySpawnTimer++;
var spawnRate = Math.max(30, 120 - waveNumber * 5);
if (enemySpawnTimer >= spawnRate) {
if (enemies.length < enemiesPerWave + Math.floor(waveNumber / 2)) {
spawnEnemy();
enemySpawnTimer = 0;
}
}
// 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);
}
// 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();
}
}
};