User prompt
Input the echoesofancestry skill tree using the circuitofascension skill tree system including the back button
User prompt
Now that we have a complete working skill node/tree system for circuitofascension, let's do the same setup for echoesofancestry popup screen. Make sure to add the same back button. Here are the 7 skills with their descriptions: Below are seven example skills for The Echoes of Ancestry skill tree, each drawing upon ancient bloodlines, ancestral wisdom, and elemental control: 1. Ancient Wisdom Description: Tap into the deep knowledge of your forebears. Increases your critical hit chance by 5%. 2. Elemental Mastery Description: Channel elemental forces passed down through the ages. Your attacks gain a small amount of elemental damage, enhancing both sword and bow strikes. 3. Warrior Spirit Description: Draw upon the martial prowess of ancestral warriors. Increases your melee attack speed by 10%, allowing swifter sword swings against foes. 4. Beast Tamer Description: Ancestral bonds with nature grant you the ability to briefly call forth a spectral beast. This ally strikes nearby enemies before fading away. 5. Herbal Remedies Description: Old herbal secrets provide gentle healing over time. Gradually restores a portion of your health while in battle. 6. Spirit Guidance Description: A guiding ancestral spirit offers insight in combat. Reduces incoming damage by 5%, helping you withstand the harshest blows. 7. Legendary Ancestor (Ultimate) Description: Invoke the essence of a mighty champion from your bloodline. For a short duration, greatly increase your overall damage and defense, turning the tide of battle in your favor.
User prompt
Please fix the bug: 'Uncaught ReferenceError: addSkillNodes is not defined' in or related to this line: 'addSkillNodes(chosenNodes);' Line Number: 1457
User prompt
Please fix the bug: 'Uncaught ReferenceError: displayFinalCrescendoPopup is not defined' in or related to this line: 'var symphonyNodes = [{' Line Number: 657
User prompt
Please fix the bug: 'Uncaught ReferenceError: displayPhantomWaltzPopup is not defined' in or related to this line: 'var symphonyNodes = [{' Line Number: 657
User prompt
Please fix the bug: 'Uncaught ReferenceError: displayEchoingLaughPopup is not defined' in or related to this line: 'var symphonyNodes = [{' Line Number: 657
User prompt
Please fix the bug: 'Uncaught ReferenceError: displayNightmareVeilPopup is not defined' in or related to this line: 'var symphonyNodes = [{' Line Number: 652
User prompt
Please fix the bug: 'Uncaught ReferenceError: displayUmbralStrikePopup is not defined' in or related to this line: 'var symphonyNodes = [{' Line Number: 652
User prompt
Please fix the bug: 'Uncaught ReferenceError: displaySilentStepPopup is not defined' in or related to this line: 'var symphonyNodes = [{' Line Number: 647
User prompt
Please fix the bug: 'Uncaught ReferenceError: displayShadowBladePopup is not defined' in or related to this line: 'var symphonyNodes = [{' Line Number: 642
User prompt
Please fix the bug: 'Uncaught ReferenceError: displayCosmicCollapsePopup is not defined' in or related to this line: 'var nexusNodes = [{' Line Number: 598
User prompt
Please fix the bug: 'Uncaught ReferenceError: displayQuantumBlinkPopup is not defined' in or related to this line: 'var nexusNodes = [{' Line Number: 593
User prompt
Please fix the bug: 'Uncaught ReferenceError: displayFractalShieldPopup is not defined' in or related to this line: 'var nexusNodes = [{' Line Number: 588
User prompt
Please fix the bug: 'Uncaught ReferenceError: displayVoidPullPopup is not defined' in or related to this line: 'var nexusNodes = [{' Line Number: 583
User prompt
Please fix the bug: 'Uncaught ReferenceError: displayRandomSurgePopup is not defined' in or related to this line: 'var nexusNodes = [{' Line Number: 583
User prompt
Please fix the bug: 'Uncaught ReferenceError: displayEntropyFieldPopup is not defined' in or related to this line: 'var nexusNodes = [{' Line Number: 578
User prompt
Please fix the bug: 'Uncaught ReferenceError: displayChaoticBoltPopup is not defined' in or related to this line: 'var nexusNodes = [{' Line Number: 573
User prompt
Please fix the bug: 'Uncaught ReferenceError: displayWhiteNovaPopup is not defined' in or related to this line: 'var prismNodes = [{' Line Number: 529
User prompt
Please fix the bug: 'Uncaught ReferenceError: displayOrangeRagePopup is not defined' in or related to this line: 'var prismNodes = [{' Line Number: 524
User prompt
Please fix the bug: 'Uncaught ReferenceError: displayPurpleStealthPopup is not defined' in or related to this line: 'var prismNodes = [{' Line Number: 518
User prompt
Please fix the bug: 'Uncaught ReferenceError: displayYellowInsightPopup is not defined' in or related to this line: 'var prismNodes = [{' Line Number: 518
User prompt
Please fix the bug: 'Uncaught ReferenceError: displayGreenSpeedPopup is not defined' in or related to this line: 'var prismNodes = [{' Line Number: 518
User prompt
Please fix the bug: 'Uncaught ReferenceError: displayBlueShieldPopup is not defined' in or related to this line: 'var prismNodes = [{' Line Number: 518
User prompt
Please fix the bug: 'Uncaught ReferenceError: displayRedFuryPopup is not defined' in or related to this line: 'var prismNodes = [{' Line Number: 518
User prompt
Please fix the bug: 'Uncaught ReferenceError: displayGodforgePopup is not defined' in or related to this line: 'var forgeNodes = [{' Line Number: 474
/**** * Classes ****/ // Arrow class representing the arrows fired by the hero var Arrow = Container.expand(function () { var self = Container.call(this); self.attachAsset('arrow', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 15; self.damage = 5; self.update = function () { self.x += Math.cos(self.rotation) * self.speed; self.y += Math.sin(self.rotation) * self.speed; if (self.x < 0 || self.x > 2048 || self.y < 0 || self.y > 2732) { self.destroy(); } }; }); // BackButton class representing the back button functionality var BackButton = Container.expand(function () { var self = Container.call(this); self.attachAsset('backButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2 }); self.x = 150; self.y = 350; self.down = function () { menuContainer.removeChild(self.parent); menuContainer.addChild(skillTreePopup); }; return self; }); // Enemy class representing the enemy character var Enemy = Container.expand(function () { var self = Container.call(this); var enemyGraphics = self.attachAsset('enemy_run1', { anchorX: 0.5, anchorY: 0.5 }); var frames = [LK.getAsset('enemy_run1', { anchorX: 0.5, anchorY: 0.5 }), LK.getAsset('enemy_run2', { anchorX: 0.5, anchorY: 0.5 }), LK.getAsset('enemy_run3', { anchorX: 0.5, anchorY: 0.5 }), LK.getAsset('enemy_run4', { anchorX: 0.5, anchorY: 0.5 })]; self.speed = 2 + Math.random() * 0.5; self.damageCooldown = 0; var currentFrame = 0; var frameDelay = 30; var frameCounter = 0; self.update = function () { frameCounter++; if (frameCounter >= frameDelay) { frameCounter = 0; self.removeChild(enemyGraphics); currentFrame = (currentFrame + 1) % frames.length; enemyGraphics = self.addChild(frames[currentFrame]); } var offsetX = (Math.random() - 0.5) * 20; var offsetY = (Math.random() - 0.5) * 20; var dx = hero.x + offsetX - self.x; var dy = hero.y + offsetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); var minDistance = 70; if (distance > minDistance) { self.x += dx / distance * self.speed; self.y += dy / distance * self.speed; self.rotation = Math.atan2(dy, dx); } else { if (self.damageCooldown <= 0) { hero.health -= 5; self.damageCooldown = 60; updateRoomDisplay(); } else { self.damageCooldown--; } self.x -= dx / distance * (minDistance - distance); self.y -= dy / distance * (minDistance - distance); } if (self.x < wallThickness) { self.x = wallThickness; } if (self.x > roomWidth - wallThickness) { self.x = roomWidth - wallThickness; } if (self.y < wallThickness) { self.y = wallThickness; } if (self.y > roomHeight - wallThickness) { self.y = roomHeight - wallThickness; } }; return self; }); // Hero class representing the player character var Hero = Container.expand(function () { var self = Container.call(this); var heroGraphics = self.attachAsset('hero', { anchorX: 0.5, anchorY: 0.5 }); self.swordGraphics = heroGraphics.addChild(LK.getAsset('sword', { anchorX: 0.5, anchorY: 0.5 })); self.swordGraphics.x = heroGraphics.width / 2 + 20; self.swordGraphics.y = 0; self.bowGraphics = self.attachAsset('bow', { anchorX: 0.5, anchorY: 0.5 }); self.bowGraphics.x = heroGraphics.width / 2; self.bowGraphics.visible = false; self.attackCooldown = 0; self.isAttacking = false; self.health = 100; self.attackDuration = 20; self.weaponType = 1; self.attackRange = 60; self.attackDamage = 10; self.speed = 3; self.joystick = null; self.update = function () { var direction = this.joystick ? this.joystick.getDirection() : { x: 0, y: 0 }; var nextX = this.x + direction.x * this.speed; var nextY = this.y + direction.y * this.speed; if (nextX < wallThickness && !(nextY >= entrances.left.yStart && nextY <= entrances.left.yEnd)) { nextX = wallThickness; } else if (nextX > roomWidth - wallThickness && !(nextY >= entrances.right.yStart && nextY <= entrances.right.yEnd)) { nextX = roomWidth - wallThickness; } if (nextY < wallThickness && !(nextX >= entrances.top.xStart && nextX <= entrances.top.xEnd)) { nextY = wallThickness; } else if (nextY > roomHeight - wallThickness && !(nextX >= entrances.bottom.xStart && nextX <= entrances.bottom.xEnd)) { nextY = roomHeight - wallThickness; } this.x = nextX; this.y = nextY; if (self.isAttacking) { var swingProgress = (self.attackDuration - self.attackCooldown) / self.attackDuration; self.swordGraphics.rotation = Math.sin(swingProgress * Math.PI) * 1.2; self.swordGraphics.x = heroGraphics.width / 2 + Math.cos(swingProgress * Math.PI) * 30; self.swordGraphics.y = Math.sin(swingProgress * Math.PI) * 30; self.attackCooldown--; if (self.attackCooldown <= 0) { self.isAttacking = false; self.swordGraphics.rotation = 0; } else { for (var i = currentRoom.enemies.length - 1; i >= 0; i--) { var enemy = currentRoom.enemies[i]; var angleToEnemy = Math.atan2(enemy.y - self.y, enemy.x - self.x); var angleDifference = Math.abs(angleToEnemy - self.rotation); var swordDx = enemy.x - (self.x + Math.cos(self.rotation) * self.attackRange); var swordDy = enemy.y - (self.y + Math.sin(self.rotation) * self.attackRange); var swordDistance = Math.sqrt(swordDx * swordDx + swordDy * swordDy); if (swordDistance < self.attackRange && angleDifference < Math.PI / 4) { enemy.health -= self.attackDamage; if (enemy.health <= 0) { currentRoom.enemiesKilled++; currentRoom.enemyCounter--; enemy.destroy(); currentRoom.enemies.splice(i, 1); updateRoomDisplay(); } } } } } else { self.swordGraphics.rotation = 0; } }; }); // Joystick class representing the on-screen joystick for movement var Joystick = Container.expand(function () { var self = Container.call(this); var joystickBackground = self.attachAsset('joystickBackground', { anchorX: 0.5, anchorY: 0.5 }); var joystickHandle = self.attachAsset('joystickHandle', { anchorX: 0.5, anchorY: 0.5 }); self.x = joystickBackground.width / 2 + 100; self.y = 2732 - joystickBackground.height / 2 - 100; var maxRadius = 100; var isDragging = false; self.down = function (x, y, obj) { isDragging = true; }; self.move = function (x, y, obj) { if (isDragging && !isPopupActive) { var localPos = self.toLocal(obj.global); var dx = localPos.x; var dy = localPos.y; var distance = Math.sqrt(dx * dx + dy * dy); if (distance > maxRadius) { var angle = Math.atan2(dy, dx); dx = maxRadius * Math.cos(angle); dy = maxRadius * Math.sin(angle); } joystickHandle.x = dx; joystickHandle.y = dy; } }; self.up = function (x, y, obj) { isDragging = false; joystickHandle.x = 0; joystickHandle.y = 0; }; self.getDirection = function () { var magnitude = Math.sqrt(joystickHandle.x * joystickHandle.x + joystickHandle.y * joystickHandle.y); if (magnitude > 0) { return { x: joystickHandle.x / magnitude, y: joystickHandle.y / magnitude }; } return { x: 0, y: 0 }; }; return self; }); // StartGameButton class representing the start game button functionality var StartGameButton = Container.expand(function () { var self = Container.call(this); self.attachAsset('startGameButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 }); self.x = 2048 / 2; self.y = 2732 - 400; self.down = function () { menuContainer.removeChild(skillTreePopup); isPopupActive = false; isDataSpikePopupActive = false; initializeGame(); LK.playMusic('room1_music', { loop: true }); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 }); /**** * Game Code ****/ // Define displayLegendaryAncestorPopup function function displayLegendaryAncestorPopup() { var legendaryAncestorPopup = createSkillPopup('Legendary Ancestor', 'Invoke the power of a legendary ancestor, greatly enhancing your abilities.'); menuContainer.addChild(legendaryAncestorPopup); isDataSpikePopupActive = true; } // Define displayArcaneAlloyPopup function function displayArcaneAlloyPopup() { var arcaneAlloyPopup = createSkillPopup('Arcane Alloy', 'Combine mystical elements to create a powerful alloy, enhancing your weaponry.'); menuContainer.addChild(arcaneAlloyPopup); isDataSpikePopupActive = true; } // Define displayMetalMasteryPopup function function displayMetalMasteryPopup() { var metalMasteryPopup = createSkillPopup('Metal Mastery', 'Enhance your skills in manipulating metals, increasing crafting efficiency.'); menuContainer.addChild(metalMasteryPopup); isDataSpikePopupActive = true; } // Define displayForgeFirePopup function function displayForgeFirePopup() { var forgeFirePopup = createSkillPopup('Forge Fire', 'Ignite the forge with mystical flames, enhancing your crafting abilities.'); menuContainer.addChild(forgeFirePopup); isDataSpikePopupActive = true; } // Define displayBeastTamerPopup function function displayBeastTamerPopup() { var beastTamerPopup = createSkillPopup('Beast Tamer', 'Gain the ability to tame beasts, turning them into allies.'); menuContainer.addChild(beastTamerPopup); isDataSpikePopupActive = true; } // Define displayHerbalRemediesPopup function function displayHerbalRemediesPopup() { var herbalRemediesPopup = createSkillPopup('Herbal Remedies', 'Enhance your healing abilities with natural remedies.'); menuContainer.addChild(herbalRemediesPopup); isDataSpikePopupActive = true; } // Define displaySpiritGuidancePopup function function displaySpiritGuidancePopup() { var spiritGuidancePopup = createSkillPopup('Spirit Guidance', 'Receive guidance from the spirits, enhancing your intuition and decision-making.'); menuContainer.addChild(spiritGuidancePopup); isDataSpikePopupActive = true; } function updateSkillPointsDisplay() { if (typeof skillPointsDisplay !== 'undefined') { skillPointsDisplay.setText('Skill Points: ' + heroSkillPoints); } if (typeof skillPointsText !== 'undefined') { skillPointsText.setText('Skill Points: ' + heroSkillPoints); } } updateSkillPointsDisplay(); // call once to set initial text // Global variables var heroSkillPoints = 3; // Starting skill points var skillTreePointsText = null; // Will hold the text object once created // Define skill nodes for each skill tree var baseXPositions = [2048 / 4, 2048 / 2, 3 * 2048 / 4]; var tier1Y = 2732 / 6; var tier2Y = 2 * 2732 / 6; var tier3Y = 3 * 2732 / 6; // Circuit of Ascension skill nodes var circuitNodes = [{ id: 'data_spike_icon', x: baseXPositions[0], y: tier1Y, name: 'Data Spike', action: displayDataSpikePopup }, { id: 'reflex_accelerator_icon', x: baseXPositions[1], y: tier1Y, name: 'Reflex Accelerator', action: displayReflexAcceleratorPopup }, { id: 'overclock_core_icon', x: baseXPositions[2], y: tier1Y, name: 'Overclock Core', action: displayOverclockCorePopup }, { id: 'neural_hijack_icon', x: baseXPositions[0], y: tier2Y, name: 'Neural Hijack', action: displayNeuralHijackPopup }, { id: 'dodge_matrix_icon', x: baseXPositions[1], y: tier2Y, name: 'Dodge Matrix', action: displayDodgeMatrixPopup }, { id: 'brown_node_icon', x: baseXPositions[2], y: tier2Y, name: 'Power Surge', action: displayPowerSurgePopup }, { id: 'ultimate_skill_icon', x: 2048 / 2, y: tier3Y, name: 'Overload Blast', action: displayOverloadBlastPopup }]; // Echoes of Ancestry skill nodes var ancestryNodes = [{ id: 'data_spike_icon', x: baseXPositions[0], y: tier1Y, name: 'Ancient Wisdom', action: displayAncientWisdomPopup }, { id: 'reflex_accelerator_icon', x: baseXPositions[1], y: tier1Y, name: 'Elemental Mastery', action: displayElementalMasteryPopup }, { id: 'overclock_core_icon', x: baseXPositions[2], y: tier1Y, name: 'Warrior Spirit', action: displayWarriorSpiritPopup }, { id: 'neural_hijack_icon', x: baseXPositions[0], y: tier2Y, name: 'Beast Tamer', action: displayBeastTamerPopup }, { id: 'dodge_matrix_icon', x: baseXPositions[1], y: tier2Y, name: 'Herbal Remedies', action: displayHerbalRemediesPopup }, { id: 'brown_node_icon', x: baseXPositions[2], y: tier2Y, name: 'Spirit Guidance', action: displaySpiritGuidancePopup }, { id: 'ultimate_skill_icon', x: 2048 / 2, y: tier3Y, name: 'Legendary Ancestor', action: displayLegendaryAncestorPopup }]; // Forge of Possibilities skill nodes var forgeNodes = [{ id: 'data_spike_icon', x: baseXPositions[0], y: tier1Y, name: 'Forge Fire', action: displayForgeFirePopup }, { id: 'reflex_accelerator_icon', x: baseXPositions[1], y: tier1Y, name: 'Metal Mastery', action: displayMetalMasteryPopup }, { id: 'overclock_core_icon', x: baseXPositions[2], y: tier1Y, name: 'Arcane Alloy', action: displayArcaneAlloyPopup }, { id: 'neural_hijack_icon', x: baseXPositions[0], y: tier2Y, name: 'Runic Hammer', action: displayRunicHammerPopup }, { id: 'dodge_matrix_icon', x: baseXPositions[1], y: tier2Y, name: 'Adaptive Crafting', action: displayAdaptiveCraftingPopup }, { id: 'brown_node_icon', x: baseXPositions[2], y: tier2Y, name: 'Aether Furnace', action: displayAetherFurnacePopup }, { id: 'ultimate_skill_icon', x: 2048 / 2, y: tier3Y, name: 'Godforge', action: displayGodforgePopup }]; // Prism of Potential skill nodes var prismNodes = [{ id: 'data_spike_icon', x: baseXPositions[0], y: tier1Y, name: 'Red Fury', action: displayRedFuryPopup }, { id: 'reflex_accelerator_icon', x: baseXPositions[1], y: tier1Y, name: 'Blue Shield', action: displayBlueShieldPopup }, { id: 'overclock_core_icon', x: baseXPositions[2], y: tier1Y, name: 'Green Speed', action: displayGreenSpeedPopup }, { id: 'neural_hijack_icon', x: baseXPositions[0], y: tier2Y, name: 'Yellow Insight', action: displayYellowInsightPopup }, { id: 'dodge_matrix_icon', x: baseXPositions[1], y: tier2Y, name: 'Purple Stealth', action: displayPurpleStealthPopup }, { id: 'brown_node_icon', x: baseXPositions[2], y: tier2Y, name: 'Orange Rage', action: displayOrangeRagePopup }, { id: 'ultimate_skill_icon', x: 2048 / 2, y: tier3Y, name: 'White Nova', action: displayWhiteNovaPopup }]; // Nexus of Chaos skill nodes var nexusNodes = [{ id: 'data_spike_icon', x: baseXPositions[0], y: tier1Y, name: 'Chaotic Bolt', action: displayChaoticBoltPopup }, { id: 'reflex_accelerator_icon', x: baseXPositions[1], y: tier1Y, name: 'Entropy Field', action: displayEntropyFieldPopup }, { id: 'overclock_core_icon', x: baseXPositions[2], y: tier1Y, name: 'Random Surge', action: displayRandomSurgePopup }, { id: 'neural_hijack_icon', x: baseXPositions[0], y: tier2Y, name: 'Void Pull', action: displayVoidPullPopup }, { id: 'dodge_matrix_icon', x: baseXPositions[1], y: tier2Y, name: 'Fractal Shield', action: displayFractalShieldPopup }, { id: 'brown_node_icon', x: baseXPositions[2], y: tier2Y, name: 'Quantum Blink', action: displayQuantumBlinkPopup }, { id: 'ultimate_skill_icon', x: 2048 / 2, y: tier3Y, name: 'Cosmic Collapse', action: displayCosmicCollapsePopup }]; // Symphony of Shadows skill nodes var symphonyNodes = [{ id: 'data_spike_icon', x: baseXPositions[0], y: tier1Y, name: 'Shadow Blade', action: displayShadowBladePopup }, { id: 'reflex_accelerator_icon', x: baseXPositions[1], y: tier1Y, name: 'Silent Step', action: displaySilentStepPopup }, { id: 'overclock_core_icon', x: baseXPositions[2], y: tier1Y, name: 'Umbral Strike', action: displayUmbralStrikePopup }, { id: 'neural_hijack_icon', x: baseXPositions[0], y: tier2Y, name: 'Nightmare Veil', action: displayNightmareVeilPopup }, { id: 'dodge_matrix_icon', x: baseXPositions[1], y: tier2Y, name: 'Echoing Laugh', action: displayEchoingLaughPopup }, { id: 'brown_node_icon', x: baseXPositions[2], y: tier2Y, name: 'Phantom Waltz', action: displayPhantomWaltzPopup }, { id: 'ultimate_skill_icon', x: 2048 / 2, y: tier3Y, name: 'Final Crescendo', action: displayFinalCrescendoPopup }]; // Define refreshTreePointsText globally so it's accessible everywhere function refreshTreePointsText() { if (skillTreePointsText) { skillTreePointsText.setText('Skill Points: ' + heroSkillPoints); } } // Define displayRunicHammerPopup function function displayRunicHammerPopup() { var runicHammerPopup = createSkillPopup('Runic Hammer', 'Harness the power of runes to enhance your crafting abilities.'); menuContainer.addChild(runicHammerPopup); isDataSpikePopupActive = true; } // Define displayGodforgePopup function function displayGodforgePopup() { var godforgePopup = createSkillPopup('Godforge', 'Unlock the ultimate crafting potential, allowing for the creation of legendary items.'); menuContainer.addChild(godforgePopup); isDataSpikePopupActive = true; } // Define displayAetherFurnacePopup function function displayAetherFurnacePopup() { var aetherFurnacePopup = createSkillPopup('Aether Furnace', 'Channel the power of the aether to enhance your crafting capabilities.'); menuContainer.addChild(aetherFurnacePopup); isDataSpikePopupActive = true; } // Define displayAdaptiveCraftingPopup function function displayAdaptiveCraftingPopup() { var adaptiveCraftingPopup = createSkillPopup('Adaptive Crafting', 'Adapt your crafting techniques to improve efficiency and versatility.'); menuContainer.addChild(adaptiveCraftingPopup); isDataSpikePopupActive = true; } // Define displayAncientWisdomPopup function function displayAncientWisdomPopup() { var ancientWisdomPopup = createSkillPopup('Ancient Wisdom', 'Unlocks the secrets of the ancients, enhancing your abilities.'); menuContainer.addChild(ancientWisdomPopup); isDataSpikePopupActive = true; } // Define displayElementalMasteryPopup function function displayElementalMasteryPopup() { var elementalMasteryPopup = createSkillPopup('Elemental Mastery', 'Harness the power of the elements to enhance your skills.'); menuContainer.addChild(elementalMasteryPopup); isDataSpikePopupActive = true; } // Define displayWarriorSpiritPopup function function displayWarriorSpiritPopup() { var warriorSpiritPopup = createSkillPopup('Warrior Spirit', 'Unleash the inner warrior, boosting your combat abilities.'); menuContainer.addChild(warriorSpiritPopup); isDataSpikePopupActive = true; } var roomBackgroundImages = ['backgroundImage1', 'backgroundImage2', 'backgroundImage3', 'backgroundImage4', 'backgroundImage5']; var arrows = []; var currentRoom; var currentRoomMusic; var hero; var isPopupActive = false; var isDataSpikePopupActive = false; var roomWidth = 2048; var roomHeight = 2732; var wallThickness = 400; var entranceWidth = 200; var entrances = { top: { xStart: (roomWidth - entranceWidth) / 2, xEnd: (roomWidth + entranceWidth) / 2, y: wallThickness }, bottom: { xStart: (roomWidth - entranceWidth) / 2, xEnd: (roomWidth + entranceWidth) / 2, y: roomHeight - wallThickness }, left: { yStart: (roomHeight - entranceWidth) / 2, yEnd: (roomHeight + entranceWidth) / 2, x: wallThickness }, right: { yStart: (roomHeight - entranceWidth) / 2, yEnd: (roomHeight + entranceWidth) / 2, x: roomWidth - wallThickness } }; var spawnPoints = { topLeft: { x: wallThickness, y: wallThickness }, topRight: { x: roomWidth - wallThickness, y: wallThickness }, bottomLeft: { x: wallThickness, y: roomHeight - wallThickness }, bottomRight: { x: roomWidth - wallThickness, y: roomHeight - wallThickness } }; var gameContainer = new Container(); var uiContainer = new Container(); var menuContainer = new Container(); game.addChild(gameContainer); game.addChild(uiContainer); game.addChild(menuContainer); var skillTreePopup = new Container(); skillTreePopup.width = 2048; skillTreePopup.height = 2732; skillTreePopup.x = 0; skillTreePopup.y = 0; var skillTreeBackground = LK.getAsset('skillTree_Background', { anchorX: 0.5, anchorY: 0.5 }); skillTreeBackground.x = 2048 / 2; skillTreeBackground.y = 2732 / 2; skillTreePopup.addChild(skillTreeBackground); // Add skill points display var skillPointsDisplay = new Text2('Skill Points: ' + heroSkillPoints, { size: 70, fill: "#ffffff", fontWeight: "bold" }); skillPointsDisplay.x = 2048 / 2; // center horizontally skillPointsDisplay.y = 2732 - 100; // near bottom skillPointsDisplay.anchor.set(0.5, 0); skillTreePopup.addChild(skillPointsDisplay); var skillTrees = [{ title: 'The Circuit of Ascension', theme: 'Futuristic, cybernetic evolution' }, { title: 'The Echoes of Ancestry', theme: 'Mystical and historical' }, { title: 'The Forge of Possibilities', theme: 'Creative and modular' }, { title: 'The Prism of Potential', theme: 'Magical and elemental' }, { title: 'The Nexus of Chaos', theme: 'Unpredictable and chaotic' }, { title: 'The Symphony of Shadows', theme: 'Dark and stealth-focused' }]; var positions = [{ x: 1024 - 300, y: 1266 - 400 }, { x: 1024 + 300, y: 1266 - 400 }, { x: 1024 - 300, y: 1266 - 50 }, { x: 1024 + 300, y: 1266 - 50 }, { x: 1024 - 300, y: 1266 + 300 }, { x: 1024 + 300, y: 1266 + 300 }]; var skillTreeAssetMap = { 'The Circuit of Ascension': 'circuitofascension', 'The Echoes of Ancestry': 'echoesofancestry', 'The Forge of Possibilities': 'forgeofpossibilities', 'The Prism of Potential': 'prismofpotential', 'The Nexus of Chaos': 'nexusofchaos', 'The Symphony of Shadows': 'symphonyofshadows' }; positions.forEach(function (position, index) { var skillTree = skillTrees[index]; var titleText = new Text2(skillTree.title, { size: 50, fill: "#ffffff", fontWeight: "bold", fontFamily: "Techno, sans-serif", letterSpacing: 2, stroke: "#00ffcc", strokeThickness: 3 }); titleText.x = position.x; titleText.y = position.y + 100; titleText.anchor.set(0.5, 0); var skillTreeAssetId = skillTreeAssetMap[skillTree.title]; var skillTreeAsset = LK.getAsset(skillTreeAssetId, { anchorX: 0.5, anchorY: 0.5 }); if (!skillTreePopup.children.includes(skillTreeAsset)) { skillTreePopup.addChild(skillTreeAsset); } skillTreeAsset.x = position.x; skillTreeAsset.y = position.y; if (!skillTreePopup.children.includes(skillTreeAsset)) { skillTreePopup.addChild(skillTreeAsset); } titleText.down = function () { openSkillTreePopup(skillTree.title); }; skillTreePopup.addChild(titleText); }); isPopupActive = true; menuContainer.addChild(skillTreePopup); var testRectangle = LK.getAsset('box', { anchorX: 0.5, anchorY: 0.5, width: 100, height: 50, color: 0xff0000 }); testRectangle.x = 100; testRectangle.y = 100; skillTreePopup.addChild(testRectangle); var startGameButton = new StartGameButton(); skillTreePopup.addChild(startGameButton); function initializeGame() { currentRoom = new Room(1); hero.x = 2048 / 2; hero.y = 2732 / 2; updateRoomDisplay(); playRoomMusic(currentRoom.number); } // Room class representing individual rooms var Room = function Room(number) { this.number = number; this.enemies = []; this.isCleared = false; this.spawnLimit = this.number === 1 ? 24 : 12 * this.number; this.killGoal = this.spawnLimit; this.enemiesSpawned = 0; this.enemiesKilled = 0; this.enemyCounter = this.spawnLimit; this.init = function () { var self = this; var spawnInterval = LK.setInterval(function () { if (self.enemiesSpawned < self.spawnLimit && currentRoom.number === self.number && !isPopupActive) { self.spawnEnemy(); } else { LK.clearInterval(spawnInterval); } }, 500); }; this.spawnEnemy = function () { if (this.enemiesSpawned < this.spawnLimit && !isPopupActive && currentRoom.number === this.number) { var spawnKeys = Object.keys(spawnPoints); var spawnIndex = Math.floor(Math.random() * spawnKeys.length); var spawnPoint = spawnPoints[spawnKeys[spawnIndex]]; var enemy = new Enemy(); enemy.x = spawnPoint.x; enemy.y = spawnPoint.y; enemy.active = true; enemy.health = 10; enemy.visible = true; this.enemies.push(enemy); game.addChild(enemy); this.enemiesSpawned++; } }; this.init(); }; var initialBgImage = LK.getAsset('backgroundImage1', { anchorX: 0.5, anchorY: 0.5 }); initialBgImage.x = 2048 / 2; initialBgImage.y = 2732 / 2; game.addChildAt(initialBgImage, 0); game.background = initialBgImage; var statsBar = LK.getAsset('box', { anchorX: 0.0, anchorY: 0.0, width: 2048, height: 100, x: 0, y: 0 }); game.addChild(statsBar); var roomDisplay = new Text2('Room: 1 | Enemies Left: 0', { size: 70, fill: "#ffffff", fontWeight: "bold" }); roomDisplay.x = 1000; roomDisplay.y = 20; game.addChild(roomDisplay); function updateRoomDisplay() { var enemiesLeft = currentRoom.spawnLimit - currentRoom.enemiesKilled; roomDisplay.setText('Room: ' + currentRoom.number + ' | Enemies Left: ' + Math.max(enemiesLeft, 0)); healthText.setText('Health: ' + hero.health); } function stopRoomMusic() { if (currentRoomMusic) { currentRoomMusic.stop(); } } function playRoomMusic(roomNumber) { if (currentRoomMusic) { currentRoomMusic.stop(); } switch (roomNumber) { case 1: currentRoomMusic = LK.getSound('room1_music'); currentRoomMusic.play({ loop: true }); break; case 2: LK.playMusic('room2_music', { loop: true }); break; case 3: LK.playMusic('room3_music', { loop: true }); break; case 4: currentRoomMusic = LK.getSound('room4_music'); currentRoomMusic.play({ loop: true }); break; case 5: LK.playMusic('room5_music', { loop: true }); break; default: currentRoomMusic = null; } } function checkRoomCleared() { if (currentRoom.enemiesKilled >= currentRoom.killGoal && !currentRoom.isCleared) { var roomClearedSound = LK.getSound('room' + currentRoom.number + '_cleared'); if (roomClearedSound) { roomClearedSound.play(); } if (currentRoom.number === 1) { LK.getSound('room1_music').stop(); } else if (currentRoom.number === 2) { LK.getSound('room2_music').stop(); } else if (currentRoom.number === 3) { LK.getSound('room3_music').stop(); } else if (currentRoom.number === 4) { currentRoomMusic.stop(); } else if (currentRoom.number === 5) { currentRoomMusic.stop(); } stopRoomMusic(); currentRoom.isCleared = true; hero.canExitRoom = true; updateRoomDisplay(); } } function transitionToNextRoom() { playRoomMusic(currentRoom.number); if (game.background) { game.removeChild(game.background); } currentRoom.enemies.forEach(function (enemy) { enemy.destroy(); }); currentRoom.enemies = []; currentRoom.enemiesSpawned = 0; currentRoom.enemyCounter = currentRoom.spawnLimit; currentRoom.enemiesKilled = 0; currentRoom = new Room(currentRoom.number + 1); currentRoom.enemiesKilled = 0; var bgImageIndex = (currentRoom.number - 1) % roomBackgroundImages.length; var bgImage = LK.getAsset(roomBackgroundImages[bgImageIndex], { anchorX: 0.5, anchorY: 0.5 }); bgImage.x = 2048 / 2; bgImage.y = 2732 / 2; game.addChildAt(bgImage, 0); game.background = bgImage; currentRoom.isCleared = false; hero.canExitRoom = false; updateRoomDisplay(); } function transitionToNewRoom(entrySide) { if (entrySide === 'top') { hero.y = 2732 - 10; } else if (entrySide === 'bottom') { hero.y = 10; } else if (entrySide === 'left') { hero.x = 2048 - 10; } else if (entrySide === 'right') { hero.x = 10; } stopRoomMusic(); transitionToNextRoom(); playRoomMusic(currentRoom.number); hero.canExitRoom = false; } var hero = gameContainer.addChild(new Hero()); hero.x = 2048 / 2; hero.y = 2732 / 2; var healthText = new Text2('Health: ' + hero.health, { size: 70, fill: "#ffffff", fontWeight: "bold" }); healthText.x = 300; healthText.y = 20; game.addChild(healthText); var joystick = uiContainer.addChild(new Joystick()); hero.joystick = joystick; var killAllButton = LK.getAsset('killAllButton', { anchorX: 0.5, anchorY: 0.5 }); killAllButton.x = 100; killAllButton.y = 2732 - 350; uiContainer.addChild(killAllButton); killAllButton.down = function (x, y, obj) { if (isPopupActive || isDataSpikePopupActive) { return; } for (var i = currentRoom.enemies.length - 1; i >= 0; i--) { var enemy = currentRoom.enemies[i]; enemy.destroy(); currentRoom.enemies.splice(i, 1); currentRoom.enemiesKilled++; } updateRoomDisplay(); checkRoomCleared(); updateRoomDisplay(); checkRoomCleared(); }; var attackButton = LK.getAsset('attackIcon', { anchorX: 0.5, anchorY: 0.5 }); attackButton.x = 2048 - 150; attackButton.y = 2732 - 300; uiContainer.addChild(attackButton); attackButton.down = function (x, y, obj) { if (isPopupActive) { return; } if (hero.weaponType === 1) { hero.isAttacking = true; hero.attackCooldown = hero.attackDuration; LK.setTimeout(function () { hero.swordGraphics.rotation = 0.5; }, hero.attackDuration * 10); } else if (hero.weaponType === 2) { var arrow = new Arrow(); arrow.x = hero.x; arrow.y = hero.y; arrow.rotation = hero.rotation; arrows.push(arrow); game.addChild(arrow); } }; var switchWeaponZone = LK.getAsset('switchWeaponZone', { anchorX: 0.5, anchorY: 0.5 }); switchWeaponZone.x = 2048 - switchWeaponZone.width / 2; switchWeaponZone.y = 2732 / 2; uiContainer.addChild(switchWeaponZone); game.down = function (x, y, obj) { if (isPopupActive) { return; } if (x >= switchWeaponZone.x - switchWeaponZone.width / 2 && x <= switchWeaponZone.x + switchWeaponZone.width / 2 && y >= switchWeaponZone.y - switchWeaponZone.height / 2 && y <= switchWeaponZone.y + switchWeaponZone.height / 2) { hero.weaponType = hero.weaponType === 1 ? 2 : 1; hero.swordGraphics.visible = hero.weaponType === 1; hero.bowGraphics.visible = hero.weaponType === 2; return; } }; game.update = function () { if (isPopupActive) { return; } if (hero.joystick && !isPopupActive) { var direction = hero.joystick.getDirection(); if (direction.x !== 0 || direction.y !== 0) { hero.x += direction.x * hero.speed; hero.y += direction.y * hero.speed; hero.rotation = Math.atan2(direction.y, direction.x); } } hero.update(); if (hero.health <= 0) { hero.health = 0; LK.showGameOver(); return; } if (hero.canExitRoom) { if (hero.y < 10 || hero.y > 2732 - 10 || hero.x < 10 || hero.x > 2048 - 10) { var entrySide = hero.y < 10 ? 'bottom' : hero.y > 2732 - 10 ? 'top' : hero.x < 10 ? 'right' : 'left'; transitionToNewRoom(entrySide); } } for (var j = arrows.length - 1; j >= 0; j--) { arrows[j].update(); for (var i = currentRoom.enemies.length - 1; i >= 0; i--) { var hitDx = currentRoom.enemies[i].x - arrows[j].x; var hitDy = currentRoom.enemies[i].y - arrows[j].y; var hitDist = Math.sqrt(hitDx * hitDx + hitDy * hitDy); if (hitDist < 60) { currentRoom.enemies[i].health -= arrows[j].damage; if (currentRoom.enemies[i].health <= 0) { currentRoom.enemiesKilled++; currentRoom.enemyCounter--; if (currentRoom.enemies[i].parent) { currentRoom.enemies[i].parent.removeChild(currentRoom.enemies[i]); } currentRoom.enemies[i].destroy(); currentRoom.enemies.splice(i, 1); updateRoomDisplay(); } if (arrows[j]) { arrows[j].destroy(); arrows.splice(j, 1); } break; } } } if (!isPopupActive) { for (var k = 0; k < currentRoom.enemies.length; k++) { currentRoom.enemies[k].update(); } } checkRoomCleared(); }; function createSkillPopup(skillTitle, skillDescription) { var skillPopup = new Container(); skillPopup.width = 2048; skillPopup.height = 2732; skillPopup.x = 0; skillPopup.y = 0; var translucentBackground = LK.getAsset('box', { anchorX: 0.5, anchorY: 0.5, width: 2048, height: 2732, color: 0x000000, alpha: 0.5 }); translucentBackground.x = 2048 / 2; translucentBackground.y = 2732 / 2; skillPopup.addChild(translucentBackground); var skillTitleText = new Text2(skillTitle, { size: 120, fill: "#ffffff", fontWeight: "bold", fontFamily: "Techno, sans-serif", letterSpacing: 2, stroke: "#00ffcc", strokeThickness: 3 }); skillTitleText.x = 2048 / 2; skillTitleText.y = 2732 / 2 + 150; skillTitleText.anchor.set(0.5, 0.5); skillPopup.addChild(skillTitleText); var skillDescriptionText = new Text2(skillDescription, { size: 80, fill: "#ffffff", fontFamily: "Arial, sans-serif", letterSpacing: 1, stroke: "#00ffcc", strokeThickness: 2, wordWrap: true, wordWrapWidth: 1800 }); skillDescriptionText.x = 2048 / 2; skillDescriptionText.y = skillTitleText.y + 150; skillDescriptionText.anchor.set(0.5, 0.5); skillPopup.addChild(skillDescriptionText); var exitButton = LK.getAsset('cancelButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 }); exitButton.x = 2048 / 2 - 600; exitButton.y = 2732 / 2 + 850; exitButton.down = function () { menuContainer.removeChild(skillPopup); isDataSpikePopupActive = false; }; skillPopup.addChild(exitButton); var spendButton = LK.getAsset('spendButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 }); spendButton.x = 2048 / 2 + 600; spendButton.y = 2732 / 2 + 850; function refreshSkillPointsText() { if (typeof skillPointsDisplay !== 'undefined') { skillPointsDisplay.setText('Skill Points: ' + heroSkillPoints); } if (typeof skillPointsText !== 'undefined') { skillPointsText.setText('Skill Points: ' + heroSkillPoints); } } spendButton.down = function () { if (heroSkillPoints > 0) { heroSkillPoints--; refreshSkillPointsText(); // Update text after spending refreshTreePointsText(); // Update tree points text if visible // You can add any skill unlocking logic here if needed } else { // No skill points left, optionally do nothing } }; skillPopup.addChild(spendButton); var skillPointsText = new Text2('Skill Points: ' + heroSkillPoints, { size: 70, fill: "#ffffff", fontWeight: "bold" }); skillPointsText.x = 2048 / 2; skillPointsText.y = 2732 - 100; // bottom area of popup skillPointsText.anchor.set(0.5, 0); skillPopup.addChild(skillPointsText); return skillPopup; } function displayOverloadBlastPopup() { var overloadBlastPopup = createSkillPopup('Overload Blast', 'Unleashes a massive explosion that damages all enemies in the room.'); menuContainer.addChild(overloadBlastPopup); isDataSpikePopupActive = true; } function displayPowerSurgePopup() { var powerSurgePopup = createSkillPopup('Power Surge', 'Releases an energy burst that damages all nearby enemies.'); menuContainer.addChild(powerSurgePopup); isDataSpikePopupActive = true; } function displayDodgeMatrixPopup() { var dodgeMatrixPopup = createSkillPopup('Dodge Matrix', 'Grants a 10% chance to evade enemy attacks.'); menuContainer.addChild(dodgeMatrixPopup); isDataSpikePopupActive = true; } function displayNeuralHijackPopup() { var neuralHijackPopup = createSkillPopup('Neural Hijack', 'Temporarily converts an enemy to fight for you.'); menuContainer.addChild(neuralHijackPopup); isDataSpikePopupActive = true; } function displayOverclockCorePopup() { var overclockCorePopup = createSkillPopup('Overclock Core', 'Increases attack speed (2.5%) and energy regeneration by 2%.'); menuContainer.addChild(overclockCorePopup); isDataSpikePopupActive = true; } function displayReflexAcceleratorPopup() { var reflexAcceleratorPopup = createSkillPopup('Reflex Accelerator', 'Boosts movement speed by 10%.'); menuContainer.addChild(reflexAcceleratorPopup); isDataSpikePopupActive = true; } function displayDataSpikePopup() { var dataSpikePopup = createSkillPopup('Data Spike', 'Increases critical hit chance by 5%.'); menuContainer.addChild(dataSpikePopup); isDataSpikePopupActive = true; } function openSkillTreePopup(skillTreeName) { menuContainer.removeChild(skillTreePopup); var newPopup = new Container(); newPopup.width = 2048; newPopup.height = 2732; newPopup.x = 0; newPopup.y = 0; var newPopupBackground = LK.getAsset('skillTree_Background', { anchorX: 0.5, anchorY: 0.5 }); newPopupBackground.x = 2048 / 2; newPopupBackground.y = 2732 / 2; newPopup.addChild(newPopupBackground); var chosenNodes; if (skillTreeName === 'The Circuit of Ascension') { chosenNodes = circuitNodes; } else if (skillTreeName === 'The Echoes of Ancestry') { chosenNodes = ancestryNodes; } else if (skillTreeName === 'The Forge of Possibilities') { chosenNodes = forgeNodes; } else if (skillTreeName === 'The Prism of Potential') { chosenNodes = prismNodes; } else if (skillTreeName === 'The Nexus of Chaos') { chosenNodes = nexusNodes; } else if (skillTreeName === 'The Symphony of Shadows') { chosenNodes = symphonyNodes; } // Add the chosen skill nodes to the popup addSkillNodes(chosenNodes); var skillTreeTitle = new Text2(skillTreeName, { size: 150, fill: "#ffffff", fontWeight: "bold", fontFamily: "Techno, sans-serif", letterSpacing: 2, stroke: "#00ffcc", strokeThickness: 3 }); skillTreeTitle.x = 2048 / 2; skillTreeTitle.y = 100; skillTreeTitle.anchor.set(0.5, 0); newPopup.addChild(skillTreeTitle); // Create the skillTreePointsText at the bottom of the skill tree popup skillTreePointsText = new Text2('Skill Points: ' + heroSkillPoints, { size: 70, fill: "#ffffff", fontWeight: "bold" }); skillTreePointsText.x = 2048 / 2; skillTreePointsText.y = 2732 - 100; // bottom of the screen skillTreePointsText.anchor.set(0.5, 0); newPopup.addChild(skillTreePointsText); // Now that skillTreePointsText is defined, we can safely call refreshTreePointsText refreshTreePointsText(); menuContainer.addChild(newPopup); }
/****
* Classes
****/
// Arrow class representing the arrows fired by the hero
var Arrow = Container.expand(function () {
var self = Container.call(this);
self.attachAsset('arrow', {
anchorX: 0.5,
anchorY: 0.5
});
self.speed = 15;
self.damage = 5;
self.update = function () {
self.x += Math.cos(self.rotation) * self.speed;
self.y += Math.sin(self.rotation) * self.speed;
if (self.x < 0 || self.x > 2048 || self.y < 0 || self.y > 2732) {
self.destroy();
}
};
});
// BackButton class representing the back button functionality
var BackButton = Container.expand(function () {
var self = Container.call(this);
self.attachAsset('backButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 2,
scaleY: 2
});
self.x = 150;
self.y = 350;
self.down = function () {
menuContainer.removeChild(self.parent);
menuContainer.addChild(skillTreePopup);
};
return self;
});
// Enemy class representing the enemy character
var Enemy = Container.expand(function () {
var self = Container.call(this);
var enemyGraphics = self.attachAsset('enemy_run1', {
anchorX: 0.5,
anchorY: 0.5
});
var frames = [LK.getAsset('enemy_run1', {
anchorX: 0.5,
anchorY: 0.5
}), LK.getAsset('enemy_run2', {
anchorX: 0.5,
anchorY: 0.5
}), LK.getAsset('enemy_run3', {
anchorX: 0.5,
anchorY: 0.5
}), LK.getAsset('enemy_run4', {
anchorX: 0.5,
anchorY: 0.5
})];
self.speed = 2 + Math.random() * 0.5;
self.damageCooldown = 0;
var currentFrame = 0;
var frameDelay = 30;
var frameCounter = 0;
self.update = function () {
frameCounter++;
if (frameCounter >= frameDelay) {
frameCounter = 0;
self.removeChild(enemyGraphics);
currentFrame = (currentFrame + 1) % frames.length;
enemyGraphics = self.addChild(frames[currentFrame]);
}
var offsetX = (Math.random() - 0.5) * 20;
var offsetY = (Math.random() - 0.5) * 20;
var dx = hero.x + offsetX - self.x;
var dy = hero.y + offsetY - self.y;
var distance = Math.sqrt(dx * dx + dy * dy);
var minDistance = 70;
if (distance > minDistance) {
self.x += dx / distance * self.speed;
self.y += dy / distance * self.speed;
self.rotation = Math.atan2(dy, dx);
} else {
if (self.damageCooldown <= 0) {
hero.health -= 5;
self.damageCooldown = 60;
updateRoomDisplay();
} else {
self.damageCooldown--;
}
self.x -= dx / distance * (minDistance - distance);
self.y -= dy / distance * (minDistance - distance);
}
if (self.x < wallThickness) {
self.x = wallThickness;
}
if (self.x > roomWidth - wallThickness) {
self.x = roomWidth - wallThickness;
}
if (self.y < wallThickness) {
self.y = wallThickness;
}
if (self.y > roomHeight - wallThickness) {
self.y = roomHeight - wallThickness;
}
};
return self;
});
// Hero class representing the player character
var Hero = Container.expand(function () {
var self = Container.call(this);
var heroGraphics = self.attachAsset('hero', {
anchorX: 0.5,
anchorY: 0.5
});
self.swordGraphics = heroGraphics.addChild(LK.getAsset('sword', {
anchorX: 0.5,
anchorY: 0.5
}));
self.swordGraphics.x = heroGraphics.width / 2 + 20;
self.swordGraphics.y = 0;
self.bowGraphics = self.attachAsset('bow', {
anchorX: 0.5,
anchorY: 0.5
});
self.bowGraphics.x = heroGraphics.width / 2;
self.bowGraphics.visible = false;
self.attackCooldown = 0;
self.isAttacking = false;
self.health = 100;
self.attackDuration = 20;
self.weaponType = 1;
self.attackRange = 60;
self.attackDamage = 10;
self.speed = 3;
self.joystick = null;
self.update = function () {
var direction = this.joystick ? this.joystick.getDirection() : {
x: 0,
y: 0
};
var nextX = this.x + direction.x * this.speed;
var nextY = this.y + direction.y * this.speed;
if (nextX < wallThickness && !(nextY >= entrances.left.yStart && nextY <= entrances.left.yEnd)) {
nextX = wallThickness;
} else if (nextX > roomWidth - wallThickness && !(nextY >= entrances.right.yStart && nextY <= entrances.right.yEnd)) {
nextX = roomWidth - wallThickness;
}
if (nextY < wallThickness && !(nextX >= entrances.top.xStart && nextX <= entrances.top.xEnd)) {
nextY = wallThickness;
} else if (nextY > roomHeight - wallThickness && !(nextX >= entrances.bottom.xStart && nextX <= entrances.bottom.xEnd)) {
nextY = roomHeight - wallThickness;
}
this.x = nextX;
this.y = nextY;
if (self.isAttacking) {
var swingProgress = (self.attackDuration - self.attackCooldown) / self.attackDuration;
self.swordGraphics.rotation = Math.sin(swingProgress * Math.PI) * 1.2;
self.swordGraphics.x = heroGraphics.width / 2 + Math.cos(swingProgress * Math.PI) * 30;
self.swordGraphics.y = Math.sin(swingProgress * Math.PI) * 30;
self.attackCooldown--;
if (self.attackCooldown <= 0) {
self.isAttacking = false;
self.swordGraphics.rotation = 0;
} else {
for (var i = currentRoom.enemies.length - 1; i >= 0; i--) {
var enemy = currentRoom.enemies[i];
var angleToEnemy = Math.atan2(enemy.y - self.y, enemy.x - self.x);
var angleDifference = Math.abs(angleToEnemy - self.rotation);
var swordDx = enemy.x - (self.x + Math.cos(self.rotation) * self.attackRange);
var swordDy = enemy.y - (self.y + Math.sin(self.rotation) * self.attackRange);
var swordDistance = Math.sqrt(swordDx * swordDx + swordDy * swordDy);
if (swordDistance < self.attackRange && angleDifference < Math.PI / 4) {
enemy.health -= self.attackDamage;
if (enemy.health <= 0) {
currentRoom.enemiesKilled++;
currentRoom.enemyCounter--;
enemy.destroy();
currentRoom.enemies.splice(i, 1);
updateRoomDisplay();
}
}
}
}
} else {
self.swordGraphics.rotation = 0;
}
};
});
// Joystick class representing the on-screen joystick for movement
var Joystick = Container.expand(function () {
var self = Container.call(this);
var joystickBackground = self.attachAsset('joystickBackground', {
anchorX: 0.5,
anchorY: 0.5
});
var joystickHandle = self.attachAsset('joystickHandle', {
anchorX: 0.5,
anchorY: 0.5
});
self.x = joystickBackground.width / 2 + 100;
self.y = 2732 - joystickBackground.height / 2 - 100;
var maxRadius = 100;
var isDragging = false;
self.down = function (x, y, obj) {
isDragging = true;
};
self.move = function (x, y, obj) {
if (isDragging && !isPopupActive) {
var localPos = self.toLocal(obj.global);
var dx = localPos.x;
var dy = localPos.y;
var distance = Math.sqrt(dx * dx + dy * dy);
if (distance > maxRadius) {
var angle = Math.atan2(dy, dx);
dx = maxRadius * Math.cos(angle);
dy = maxRadius * Math.sin(angle);
}
joystickHandle.x = dx;
joystickHandle.y = dy;
}
};
self.up = function (x, y, obj) {
isDragging = false;
joystickHandle.x = 0;
joystickHandle.y = 0;
};
self.getDirection = function () {
var magnitude = Math.sqrt(joystickHandle.x * joystickHandle.x + joystickHandle.y * joystickHandle.y);
if (magnitude > 0) {
return {
x: joystickHandle.x / magnitude,
y: joystickHandle.y / magnitude
};
}
return {
x: 0,
y: 0
};
};
return self;
});
// StartGameButton class representing the start game button functionality
var StartGameButton = Container.expand(function () {
var self = Container.call(this);
self.attachAsset('startGameButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 3
});
self.x = 2048 / 2;
self.y = 2732 - 400;
self.down = function () {
menuContainer.removeChild(skillTreePopup);
isPopupActive = false;
isDataSpikePopupActive = false;
initializeGame();
LK.playMusic('room1_music', {
loop: true
});
};
return self;
});
/****
* Initialize Game
****/
var game = new LK.Game({
backgroundColor: 0x000000
});
/****
* Game Code
****/
// Define displayLegendaryAncestorPopup function
function displayLegendaryAncestorPopup() {
var legendaryAncestorPopup = createSkillPopup('Legendary Ancestor', 'Invoke the power of a legendary ancestor, greatly enhancing your abilities.');
menuContainer.addChild(legendaryAncestorPopup);
isDataSpikePopupActive = true;
}
// Define displayArcaneAlloyPopup function
function displayArcaneAlloyPopup() {
var arcaneAlloyPopup = createSkillPopup('Arcane Alloy', 'Combine mystical elements to create a powerful alloy, enhancing your weaponry.');
menuContainer.addChild(arcaneAlloyPopup);
isDataSpikePopupActive = true;
}
// Define displayMetalMasteryPopup function
function displayMetalMasteryPopup() {
var metalMasteryPopup = createSkillPopup('Metal Mastery', 'Enhance your skills in manipulating metals, increasing crafting efficiency.');
menuContainer.addChild(metalMasteryPopup);
isDataSpikePopupActive = true;
}
// Define displayForgeFirePopup function
function displayForgeFirePopup() {
var forgeFirePopup = createSkillPopup('Forge Fire', 'Ignite the forge with mystical flames, enhancing your crafting abilities.');
menuContainer.addChild(forgeFirePopup);
isDataSpikePopupActive = true;
}
// Define displayBeastTamerPopup function
function displayBeastTamerPopup() {
var beastTamerPopup = createSkillPopup('Beast Tamer', 'Gain the ability to tame beasts, turning them into allies.');
menuContainer.addChild(beastTamerPopup);
isDataSpikePopupActive = true;
}
// Define displayHerbalRemediesPopup function
function displayHerbalRemediesPopup() {
var herbalRemediesPopup = createSkillPopup('Herbal Remedies', 'Enhance your healing abilities with natural remedies.');
menuContainer.addChild(herbalRemediesPopup);
isDataSpikePopupActive = true;
}
// Define displaySpiritGuidancePopup function
function displaySpiritGuidancePopup() {
var spiritGuidancePopup = createSkillPopup('Spirit Guidance', 'Receive guidance from the spirits, enhancing your intuition and decision-making.');
menuContainer.addChild(spiritGuidancePopup);
isDataSpikePopupActive = true;
}
function updateSkillPointsDisplay() {
if (typeof skillPointsDisplay !== 'undefined') {
skillPointsDisplay.setText('Skill Points: ' + heroSkillPoints);
}
if (typeof skillPointsText !== 'undefined') {
skillPointsText.setText('Skill Points: ' + heroSkillPoints);
}
}
updateSkillPointsDisplay(); // call once to set initial text
// Global variables
var heroSkillPoints = 3; // Starting skill points
var skillTreePointsText = null; // Will hold the text object once created
// Define skill nodes for each skill tree
var baseXPositions = [2048 / 4, 2048 / 2, 3 * 2048 / 4];
var tier1Y = 2732 / 6;
var tier2Y = 2 * 2732 / 6;
var tier3Y = 3 * 2732 / 6;
// Circuit of Ascension skill nodes
var circuitNodes = [{
id: 'data_spike_icon',
x: baseXPositions[0],
y: tier1Y,
name: 'Data Spike',
action: displayDataSpikePopup
}, {
id: 'reflex_accelerator_icon',
x: baseXPositions[1],
y: tier1Y,
name: 'Reflex Accelerator',
action: displayReflexAcceleratorPopup
}, {
id: 'overclock_core_icon',
x: baseXPositions[2],
y: tier1Y,
name: 'Overclock Core',
action: displayOverclockCorePopup
}, {
id: 'neural_hijack_icon',
x: baseXPositions[0],
y: tier2Y,
name: 'Neural Hijack',
action: displayNeuralHijackPopup
}, {
id: 'dodge_matrix_icon',
x: baseXPositions[1],
y: tier2Y,
name: 'Dodge Matrix',
action: displayDodgeMatrixPopup
}, {
id: 'brown_node_icon',
x: baseXPositions[2],
y: tier2Y,
name: 'Power Surge',
action: displayPowerSurgePopup
}, {
id: 'ultimate_skill_icon',
x: 2048 / 2,
y: tier3Y,
name: 'Overload Blast',
action: displayOverloadBlastPopup
}];
// Echoes of Ancestry skill nodes
var ancestryNodes = [{
id: 'data_spike_icon',
x: baseXPositions[0],
y: tier1Y,
name: 'Ancient Wisdom',
action: displayAncientWisdomPopup
}, {
id: 'reflex_accelerator_icon',
x: baseXPositions[1],
y: tier1Y,
name: 'Elemental Mastery',
action: displayElementalMasteryPopup
}, {
id: 'overclock_core_icon',
x: baseXPositions[2],
y: tier1Y,
name: 'Warrior Spirit',
action: displayWarriorSpiritPopup
}, {
id: 'neural_hijack_icon',
x: baseXPositions[0],
y: tier2Y,
name: 'Beast Tamer',
action: displayBeastTamerPopup
}, {
id: 'dodge_matrix_icon',
x: baseXPositions[1],
y: tier2Y,
name: 'Herbal Remedies',
action: displayHerbalRemediesPopup
}, {
id: 'brown_node_icon',
x: baseXPositions[2],
y: tier2Y,
name: 'Spirit Guidance',
action: displaySpiritGuidancePopup
}, {
id: 'ultimate_skill_icon',
x: 2048 / 2,
y: tier3Y,
name: 'Legendary Ancestor',
action: displayLegendaryAncestorPopup
}];
// Forge of Possibilities skill nodes
var forgeNodes = [{
id: 'data_spike_icon',
x: baseXPositions[0],
y: tier1Y,
name: 'Forge Fire',
action: displayForgeFirePopup
}, {
id: 'reflex_accelerator_icon',
x: baseXPositions[1],
y: tier1Y,
name: 'Metal Mastery',
action: displayMetalMasteryPopup
}, {
id: 'overclock_core_icon',
x: baseXPositions[2],
y: tier1Y,
name: 'Arcane Alloy',
action: displayArcaneAlloyPopup
}, {
id: 'neural_hijack_icon',
x: baseXPositions[0],
y: tier2Y,
name: 'Runic Hammer',
action: displayRunicHammerPopup
}, {
id: 'dodge_matrix_icon',
x: baseXPositions[1],
y: tier2Y,
name: 'Adaptive Crafting',
action: displayAdaptiveCraftingPopup
}, {
id: 'brown_node_icon',
x: baseXPositions[2],
y: tier2Y,
name: 'Aether Furnace',
action: displayAetherFurnacePopup
}, {
id: 'ultimate_skill_icon',
x: 2048 / 2,
y: tier3Y,
name: 'Godforge',
action: displayGodforgePopup
}];
// Prism of Potential skill nodes
var prismNodes = [{
id: 'data_spike_icon',
x: baseXPositions[0],
y: tier1Y,
name: 'Red Fury',
action: displayRedFuryPopup
}, {
id: 'reflex_accelerator_icon',
x: baseXPositions[1],
y: tier1Y,
name: 'Blue Shield',
action: displayBlueShieldPopup
}, {
id: 'overclock_core_icon',
x: baseXPositions[2],
y: tier1Y,
name: 'Green Speed',
action: displayGreenSpeedPopup
}, {
id: 'neural_hijack_icon',
x: baseXPositions[0],
y: tier2Y,
name: 'Yellow Insight',
action: displayYellowInsightPopup
}, {
id: 'dodge_matrix_icon',
x: baseXPositions[1],
y: tier2Y,
name: 'Purple Stealth',
action: displayPurpleStealthPopup
}, {
id: 'brown_node_icon',
x: baseXPositions[2],
y: tier2Y,
name: 'Orange Rage',
action: displayOrangeRagePopup
}, {
id: 'ultimate_skill_icon',
x: 2048 / 2,
y: tier3Y,
name: 'White Nova',
action: displayWhiteNovaPopup
}];
// Nexus of Chaos skill nodes
var nexusNodes = [{
id: 'data_spike_icon',
x: baseXPositions[0],
y: tier1Y,
name: 'Chaotic Bolt',
action: displayChaoticBoltPopup
}, {
id: 'reflex_accelerator_icon',
x: baseXPositions[1],
y: tier1Y,
name: 'Entropy Field',
action: displayEntropyFieldPopup
}, {
id: 'overclock_core_icon',
x: baseXPositions[2],
y: tier1Y,
name: 'Random Surge',
action: displayRandomSurgePopup
}, {
id: 'neural_hijack_icon',
x: baseXPositions[0],
y: tier2Y,
name: 'Void Pull',
action: displayVoidPullPopup
}, {
id: 'dodge_matrix_icon',
x: baseXPositions[1],
y: tier2Y,
name: 'Fractal Shield',
action: displayFractalShieldPopup
}, {
id: 'brown_node_icon',
x: baseXPositions[2],
y: tier2Y,
name: 'Quantum Blink',
action: displayQuantumBlinkPopup
}, {
id: 'ultimate_skill_icon',
x: 2048 / 2,
y: tier3Y,
name: 'Cosmic Collapse',
action: displayCosmicCollapsePopup
}];
// Symphony of Shadows skill nodes
var symphonyNodes = [{
id: 'data_spike_icon',
x: baseXPositions[0],
y: tier1Y,
name: 'Shadow Blade',
action: displayShadowBladePopup
}, {
id: 'reflex_accelerator_icon',
x: baseXPositions[1],
y: tier1Y,
name: 'Silent Step',
action: displaySilentStepPopup
}, {
id: 'overclock_core_icon',
x: baseXPositions[2],
y: tier1Y,
name: 'Umbral Strike',
action: displayUmbralStrikePopup
}, {
id: 'neural_hijack_icon',
x: baseXPositions[0],
y: tier2Y,
name: 'Nightmare Veil',
action: displayNightmareVeilPopup
}, {
id: 'dodge_matrix_icon',
x: baseXPositions[1],
y: tier2Y,
name: 'Echoing Laugh',
action: displayEchoingLaughPopup
}, {
id: 'brown_node_icon',
x: baseXPositions[2],
y: tier2Y,
name: 'Phantom Waltz',
action: displayPhantomWaltzPopup
}, {
id: 'ultimate_skill_icon',
x: 2048 / 2,
y: tier3Y,
name: 'Final Crescendo',
action: displayFinalCrescendoPopup
}];
// Define refreshTreePointsText globally so it's accessible everywhere
function refreshTreePointsText() {
if (skillTreePointsText) {
skillTreePointsText.setText('Skill Points: ' + heroSkillPoints);
}
}
// Define displayRunicHammerPopup function
function displayRunicHammerPopup() {
var runicHammerPopup = createSkillPopup('Runic Hammer', 'Harness the power of runes to enhance your crafting abilities.');
menuContainer.addChild(runicHammerPopup);
isDataSpikePopupActive = true;
}
// Define displayGodforgePopup function
function displayGodforgePopup() {
var godforgePopup = createSkillPopup('Godforge', 'Unlock the ultimate crafting potential, allowing for the creation of legendary items.');
menuContainer.addChild(godforgePopup);
isDataSpikePopupActive = true;
}
// Define displayAetherFurnacePopup function
function displayAetherFurnacePopup() {
var aetherFurnacePopup = createSkillPopup('Aether Furnace', 'Channel the power of the aether to enhance your crafting capabilities.');
menuContainer.addChild(aetherFurnacePopup);
isDataSpikePopupActive = true;
}
// Define displayAdaptiveCraftingPopup function
function displayAdaptiveCraftingPopup() {
var adaptiveCraftingPopup = createSkillPopup('Adaptive Crafting', 'Adapt your crafting techniques to improve efficiency and versatility.');
menuContainer.addChild(adaptiveCraftingPopup);
isDataSpikePopupActive = true;
}
// Define displayAncientWisdomPopup function
function displayAncientWisdomPopup() {
var ancientWisdomPopup = createSkillPopup('Ancient Wisdom', 'Unlocks the secrets of the ancients, enhancing your abilities.');
menuContainer.addChild(ancientWisdomPopup);
isDataSpikePopupActive = true;
}
// Define displayElementalMasteryPopup function
function displayElementalMasteryPopup() {
var elementalMasteryPopup = createSkillPopup('Elemental Mastery', 'Harness the power of the elements to enhance your skills.');
menuContainer.addChild(elementalMasteryPopup);
isDataSpikePopupActive = true;
}
// Define displayWarriorSpiritPopup function
function displayWarriorSpiritPopup() {
var warriorSpiritPopup = createSkillPopup('Warrior Spirit', 'Unleash the inner warrior, boosting your combat abilities.');
menuContainer.addChild(warriorSpiritPopup);
isDataSpikePopupActive = true;
}
var roomBackgroundImages = ['backgroundImage1', 'backgroundImage2', 'backgroundImage3', 'backgroundImage4', 'backgroundImage5'];
var arrows = [];
var currentRoom;
var currentRoomMusic;
var hero;
var isPopupActive = false;
var isDataSpikePopupActive = false;
var roomWidth = 2048;
var roomHeight = 2732;
var wallThickness = 400;
var entranceWidth = 200;
var entrances = {
top: {
xStart: (roomWidth - entranceWidth) / 2,
xEnd: (roomWidth + entranceWidth) / 2,
y: wallThickness
},
bottom: {
xStart: (roomWidth - entranceWidth) / 2,
xEnd: (roomWidth + entranceWidth) / 2,
y: roomHeight - wallThickness
},
left: {
yStart: (roomHeight - entranceWidth) / 2,
yEnd: (roomHeight + entranceWidth) / 2,
x: wallThickness
},
right: {
yStart: (roomHeight - entranceWidth) / 2,
yEnd: (roomHeight + entranceWidth) / 2,
x: roomWidth - wallThickness
}
};
var spawnPoints = {
topLeft: {
x: wallThickness,
y: wallThickness
},
topRight: {
x: roomWidth - wallThickness,
y: wallThickness
},
bottomLeft: {
x: wallThickness,
y: roomHeight - wallThickness
},
bottomRight: {
x: roomWidth - wallThickness,
y: roomHeight - wallThickness
}
};
var gameContainer = new Container();
var uiContainer = new Container();
var menuContainer = new Container();
game.addChild(gameContainer);
game.addChild(uiContainer);
game.addChild(menuContainer);
var skillTreePopup = new Container();
skillTreePopup.width = 2048;
skillTreePopup.height = 2732;
skillTreePopup.x = 0;
skillTreePopup.y = 0;
var skillTreeBackground = LK.getAsset('skillTree_Background', {
anchorX: 0.5,
anchorY: 0.5
});
skillTreeBackground.x = 2048 / 2;
skillTreeBackground.y = 2732 / 2;
skillTreePopup.addChild(skillTreeBackground);
// Add skill points display
var skillPointsDisplay = new Text2('Skill Points: ' + heroSkillPoints, {
size: 70,
fill: "#ffffff",
fontWeight: "bold"
});
skillPointsDisplay.x = 2048 / 2; // center horizontally
skillPointsDisplay.y = 2732 - 100; // near bottom
skillPointsDisplay.anchor.set(0.5, 0);
skillTreePopup.addChild(skillPointsDisplay);
var skillTrees = [{
title: 'The Circuit of Ascension',
theme: 'Futuristic, cybernetic evolution'
}, {
title: 'The Echoes of Ancestry',
theme: 'Mystical and historical'
}, {
title: 'The Forge of Possibilities',
theme: 'Creative and modular'
}, {
title: 'The Prism of Potential',
theme: 'Magical and elemental'
}, {
title: 'The Nexus of Chaos',
theme: 'Unpredictable and chaotic'
}, {
title: 'The Symphony of Shadows',
theme: 'Dark and stealth-focused'
}];
var positions = [{
x: 1024 - 300,
y: 1266 - 400
}, {
x: 1024 + 300,
y: 1266 - 400
}, {
x: 1024 - 300,
y: 1266 - 50
}, {
x: 1024 + 300,
y: 1266 - 50
}, {
x: 1024 - 300,
y: 1266 + 300
}, {
x: 1024 + 300,
y: 1266 + 300
}];
var skillTreeAssetMap = {
'The Circuit of Ascension': 'circuitofascension',
'The Echoes of Ancestry': 'echoesofancestry',
'The Forge of Possibilities': 'forgeofpossibilities',
'The Prism of Potential': 'prismofpotential',
'The Nexus of Chaos': 'nexusofchaos',
'The Symphony of Shadows': 'symphonyofshadows'
};
positions.forEach(function (position, index) {
var skillTree = skillTrees[index];
var titleText = new Text2(skillTree.title, {
size: 50,
fill: "#ffffff",
fontWeight: "bold",
fontFamily: "Techno, sans-serif",
letterSpacing: 2,
stroke: "#00ffcc",
strokeThickness: 3
});
titleText.x = position.x;
titleText.y = position.y + 100;
titleText.anchor.set(0.5, 0);
var skillTreeAssetId = skillTreeAssetMap[skillTree.title];
var skillTreeAsset = LK.getAsset(skillTreeAssetId, {
anchorX: 0.5,
anchorY: 0.5
});
if (!skillTreePopup.children.includes(skillTreeAsset)) {
skillTreePopup.addChild(skillTreeAsset);
}
skillTreeAsset.x = position.x;
skillTreeAsset.y = position.y;
if (!skillTreePopup.children.includes(skillTreeAsset)) {
skillTreePopup.addChild(skillTreeAsset);
}
titleText.down = function () {
openSkillTreePopup(skillTree.title);
};
skillTreePopup.addChild(titleText);
});
isPopupActive = true;
menuContainer.addChild(skillTreePopup);
var testRectangle = LK.getAsset('box', {
anchorX: 0.5,
anchorY: 0.5,
width: 100,
height: 50,
color: 0xff0000
});
testRectangle.x = 100;
testRectangle.y = 100;
skillTreePopup.addChild(testRectangle);
var startGameButton = new StartGameButton();
skillTreePopup.addChild(startGameButton);
function initializeGame() {
currentRoom = new Room(1);
hero.x = 2048 / 2;
hero.y = 2732 / 2;
updateRoomDisplay();
playRoomMusic(currentRoom.number);
}
// Room class representing individual rooms
var Room = function Room(number) {
this.number = number;
this.enemies = [];
this.isCleared = false;
this.spawnLimit = this.number === 1 ? 24 : 12 * this.number;
this.killGoal = this.spawnLimit;
this.enemiesSpawned = 0;
this.enemiesKilled = 0;
this.enemyCounter = this.spawnLimit;
this.init = function () {
var self = this;
var spawnInterval = LK.setInterval(function () {
if (self.enemiesSpawned < self.spawnLimit && currentRoom.number === self.number && !isPopupActive) {
self.spawnEnemy();
} else {
LK.clearInterval(spawnInterval);
}
}, 500);
};
this.spawnEnemy = function () {
if (this.enemiesSpawned < this.spawnLimit && !isPopupActive && currentRoom.number === this.number) {
var spawnKeys = Object.keys(spawnPoints);
var spawnIndex = Math.floor(Math.random() * spawnKeys.length);
var spawnPoint = spawnPoints[spawnKeys[spawnIndex]];
var enemy = new Enemy();
enemy.x = spawnPoint.x;
enemy.y = spawnPoint.y;
enemy.active = true;
enemy.health = 10;
enemy.visible = true;
this.enemies.push(enemy);
game.addChild(enemy);
this.enemiesSpawned++;
}
};
this.init();
};
var initialBgImage = LK.getAsset('backgroundImage1', {
anchorX: 0.5,
anchorY: 0.5
});
initialBgImage.x = 2048 / 2;
initialBgImage.y = 2732 / 2;
game.addChildAt(initialBgImage, 0);
game.background = initialBgImage;
var statsBar = LK.getAsset('box', {
anchorX: 0.0,
anchorY: 0.0,
width: 2048,
height: 100,
x: 0,
y: 0
});
game.addChild(statsBar);
var roomDisplay = new Text2('Room: 1 | Enemies Left: 0', {
size: 70,
fill: "#ffffff",
fontWeight: "bold"
});
roomDisplay.x = 1000;
roomDisplay.y = 20;
game.addChild(roomDisplay);
function updateRoomDisplay() {
var enemiesLeft = currentRoom.spawnLimit - currentRoom.enemiesKilled;
roomDisplay.setText('Room: ' + currentRoom.number + ' | Enemies Left: ' + Math.max(enemiesLeft, 0));
healthText.setText('Health: ' + hero.health);
}
function stopRoomMusic() {
if (currentRoomMusic) {
currentRoomMusic.stop();
}
}
function playRoomMusic(roomNumber) {
if (currentRoomMusic) {
currentRoomMusic.stop();
}
switch (roomNumber) {
case 1:
currentRoomMusic = LK.getSound('room1_music');
currentRoomMusic.play({
loop: true
});
break;
case 2:
LK.playMusic('room2_music', {
loop: true
});
break;
case 3:
LK.playMusic('room3_music', {
loop: true
});
break;
case 4:
currentRoomMusic = LK.getSound('room4_music');
currentRoomMusic.play({
loop: true
});
break;
case 5:
LK.playMusic('room5_music', {
loop: true
});
break;
default:
currentRoomMusic = null;
}
}
function checkRoomCleared() {
if (currentRoom.enemiesKilled >= currentRoom.killGoal && !currentRoom.isCleared) {
var roomClearedSound = LK.getSound('room' + currentRoom.number + '_cleared');
if (roomClearedSound) {
roomClearedSound.play();
}
if (currentRoom.number === 1) {
LK.getSound('room1_music').stop();
} else if (currentRoom.number === 2) {
LK.getSound('room2_music').stop();
} else if (currentRoom.number === 3) {
LK.getSound('room3_music').stop();
} else if (currentRoom.number === 4) {
currentRoomMusic.stop();
} else if (currentRoom.number === 5) {
currentRoomMusic.stop();
}
stopRoomMusic();
currentRoom.isCleared = true;
hero.canExitRoom = true;
updateRoomDisplay();
}
}
function transitionToNextRoom() {
playRoomMusic(currentRoom.number);
if (game.background) {
game.removeChild(game.background);
}
currentRoom.enemies.forEach(function (enemy) {
enemy.destroy();
});
currentRoom.enemies = [];
currentRoom.enemiesSpawned = 0;
currentRoom.enemyCounter = currentRoom.spawnLimit;
currentRoom.enemiesKilled = 0;
currentRoom = new Room(currentRoom.number + 1);
currentRoom.enemiesKilled = 0;
var bgImageIndex = (currentRoom.number - 1) % roomBackgroundImages.length;
var bgImage = LK.getAsset(roomBackgroundImages[bgImageIndex], {
anchorX: 0.5,
anchorY: 0.5
});
bgImage.x = 2048 / 2;
bgImage.y = 2732 / 2;
game.addChildAt(bgImage, 0);
game.background = bgImage;
currentRoom.isCleared = false;
hero.canExitRoom = false;
updateRoomDisplay();
}
function transitionToNewRoom(entrySide) {
if (entrySide === 'top') {
hero.y = 2732 - 10;
} else if (entrySide === 'bottom') {
hero.y = 10;
} else if (entrySide === 'left') {
hero.x = 2048 - 10;
} else if (entrySide === 'right') {
hero.x = 10;
}
stopRoomMusic();
transitionToNextRoom();
playRoomMusic(currentRoom.number);
hero.canExitRoom = false;
}
var hero = gameContainer.addChild(new Hero());
hero.x = 2048 / 2;
hero.y = 2732 / 2;
var healthText = new Text2('Health: ' + hero.health, {
size: 70,
fill: "#ffffff",
fontWeight: "bold"
});
healthText.x = 300;
healthText.y = 20;
game.addChild(healthText);
var joystick = uiContainer.addChild(new Joystick());
hero.joystick = joystick;
var killAllButton = LK.getAsset('killAllButton', {
anchorX: 0.5,
anchorY: 0.5
});
killAllButton.x = 100;
killAllButton.y = 2732 - 350;
uiContainer.addChild(killAllButton);
killAllButton.down = function (x, y, obj) {
if (isPopupActive || isDataSpikePopupActive) {
return;
}
for (var i = currentRoom.enemies.length - 1; i >= 0; i--) {
var enemy = currentRoom.enemies[i];
enemy.destroy();
currentRoom.enemies.splice(i, 1);
currentRoom.enemiesKilled++;
}
updateRoomDisplay();
checkRoomCleared();
updateRoomDisplay();
checkRoomCleared();
};
var attackButton = LK.getAsset('attackIcon', {
anchorX: 0.5,
anchorY: 0.5
});
attackButton.x = 2048 - 150;
attackButton.y = 2732 - 300;
uiContainer.addChild(attackButton);
attackButton.down = function (x, y, obj) {
if (isPopupActive) {
return;
}
if (hero.weaponType === 1) {
hero.isAttacking = true;
hero.attackCooldown = hero.attackDuration;
LK.setTimeout(function () {
hero.swordGraphics.rotation = 0.5;
}, hero.attackDuration * 10);
} else if (hero.weaponType === 2) {
var arrow = new Arrow();
arrow.x = hero.x;
arrow.y = hero.y;
arrow.rotation = hero.rotation;
arrows.push(arrow);
game.addChild(arrow);
}
};
var switchWeaponZone = LK.getAsset('switchWeaponZone', {
anchorX: 0.5,
anchorY: 0.5
});
switchWeaponZone.x = 2048 - switchWeaponZone.width / 2;
switchWeaponZone.y = 2732 / 2;
uiContainer.addChild(switchWeaponZone);
game.down = function (x, y, obj) {
if (isPopupActive) {
return;
}
if (x >= switchWeaponZone.x - switchWeaponZone.width / 2 && x <= switchWeaponZone.x + switchWeaponZone.width / 2 && y >= switchWeaponZone.y - switchWeaponZone.height / 2 && y <= switchWeaponZone.y + switchWeaponZone.height / 2) {
hero.weaponType = hero.weaponType === 1 ? 2 : 1;
hero.swordGraphics.visible = hero.weaponType === 1;
hero.bowGraphics.visible = hero.weaponType === 2;
return;
}
};
game.update = function () {
if (isPopupActive) {
return;
}
if (hero.joystick && !isPopupActive) {
var direction = hero.joystick.getDirection();
if (direction.x !== 0 || direction.y !== 0) {
hero.x += direction.x * hero.speed;
hero.y += direction.y * hero.speed;
hero.rotation = Math.atan2(direction.y, direction.x);
}
}
hero.update();
if (hero.health <= 0) {
hero.health = 0;
LK.showGameOver();
return;
}
if (hero.canExitRoom) {
if (hero.y < 10 || hero.y > 2732 - 10 || hero.x < 10 || hero.x > 2048 - 10) {
var entrySide = hero.y < 10 ? 'bottom' : hero.y > 2732 - 10 ? 'top' : hero.x < 10 ? 'right' : 'left';
transitionToNewRoom(entrySide);
}
}
for (var j = arrows.length - 1; j >= 0; j--) {
arrows[j].update();
for (var i = currentRoom.enemies.length - 1; i >= 0; i--) {
var hitDx = currentRoom.enemies[i].x - arrows[j].x;
var hitDy = currentRoom.enemies[i].y - arrows[j].y;
var hitDist = Math.sqrt(hitDx * hitDx + hitDy * hitDy);
if (hitDist < 60) {
currentRoom.enemies[i].health -= arrows[j].damage;
if (currentRoom.enemies[i].health <= 0) {
currentRoom.enemiesKilled++;
currentRoom.enemyCounter--;
if (currentRoom.enemies[i].parent) {
currentRoom.enemies[i].parent.removeChild(currentRoom.enemies[i]);
}
currentRoom.enemies[i].destroy();
currentRoom.enemies.splice(i, 1);
updateRoomDisplay();
}
if (arrows[j]) {
arrows[j].destroy();
arrows.splice(j, 1);
}
break;
}
}
}
if (!isPopupActive) {
for (var k = 0; k < currentRoom.enemies.length; k++) {
currentRoom.enemies[k].update();
}
}
checkRoomCleared();
};
function createSkillPopup(skillTitle, skillDescription) {
var skillPopup = new Container();
skillPopup.width = 2048;
skillPopup.height = 2732;
skillPopup.x = 0;
skillPopup.y = 0;
var translucentBackground = LK.getAsset('box', {
anchorX: 0.5,
anchorY: 0.5,
width: 2048,
height: 2732,
color: 0x000000,
alpha: 0.5
});
translucentBackground.x = 2048 / 2;
translucentBackground.y = 2732 / 2;
skillPopup.addChild(translucentBackground);
var skillTitleText = new Text2(skillTitle, {
size: 120,
fill: "#ffffff",
fontWeight: "bold",
fontFamily: "Techno, sans-serif",
letterSpacing: 2,
stroke: "#00ffcc",
strokeThickness: 3
});
skillTitleText.x = 2048 / 2;
skillTitleText.y = 2732 / 2 + 150;
skillTitleText.anchor.set(0.5, 0.5);
skillPopup.addChild(skillTitleText);
var skillDescriptionText = new Text2(skillDescription, {
size: 80,
fill: "#ffffff",
fontFamily: "Arial, sans-serif",
letterSpacing: 1,
stroke: "#00ffcc",
strokeThickness: 2,
wordWrap: true,
wordWrapWidth: 1800
});
skillDescriptionText.x = 2048 / 2;
skillDescriptionText.y = skillTitleText.y + 150;
skillDescriptionText.anchor.set(0.5, 0.5);
skillPopup.addChild(skillDescriptionText);
var exitButton = LK.getAsset('cancelButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 3
});
exitButton.x = 2048 / 2 - 600;
exitButton.y = 2732 / 2 + 850;
exitButton.down = function () {
menuContainer.removeChild(skillPopup);
isDataSpikePopupActive = false;
};
skillPopup.addChild(exitButton);
var spendButton = LK.getAsset('spendButton', {
anchorX: 0.5,
anchorY: 0.5,
scaleX: 3,
scaleY: 3
});
spendButton.x = 2048 / 2 + 600;
spendButton.y = 2732 / 2 + 850;
function refreshSkillPointsText() {
if (typeof skillPointsDisplay !== 'undefined') {
skillPointsDisplay.setText('Skill Points: ' + heroSkillPoints);
}
if (typeof skillPointsText !== 'undefined') {
skillPointsText.setText('Skill Points: ' + heroSkillPoints);
}
}
spendButton.down = function () {
if (heroSkillPoints > 0) {
heroSkillPoints--;
refreshSkillPointsText(); // Update text after spending
refreshTreePointsText(); // Update tree points text if visible
// You can add any skill unlocking logic here if needed
} else {
// No skill points left, optionally do nothing
}
};
skillPopup.addChild(spendButton);
var skillPointsText = new Text2('Skill Points: ' + heroSkillPoints, {
size: 70,
fill: "#ffffff",
fontWeight: "bold"
});
skillPointsText.x = 2048 / 2;
skillPointsText.y = 2732 - 100; // bottom area of popup
skillPointsText.anchor.set(0.5, 0);
skillPopup.addChild(skillPointsText);
return skillPopup;
}
function displayOverloadBlastPopup() {
var overloadBlastPopup = createSkillPopup('Overload Blast', 'Unleashes a massive explosion that damages all enemies in the room.');
menuContainer.addChild(overloadBlastPopup);
isDataSpikePopupActive = true;
}
function displayPowerSurgePopup() {
var powerSurgePopup = createSkillPopup('Power Surge', 'Releases an energy burst that damages all nearby enemies.');
menuContainer.addChild(powerSurgePopup);
isDataSpikePopupActive = true;
}
function displayDodgeMatrixPopup() {
var dodgeMatrixPopup = createSkillPopup('Dodge Matrix', 'Grants a 10% chance to evade enemy attacks.');
menuContainer.addChild(dodgeMatrixPopup);
isDataSpikePopupActive = true;
}
function displayNeuralHijackPopup() {
var neuralHijackPopup = createSkillPopup('Neural Hijack', 'Temporarily converts an enemy to fight for you.');
menuContainer.addChild(neuralHijackPopup);
isDataSpikePopupActive = true;
}
function displayOverclockCorePopup() {
var overclockCorePopup = createSkillPopup('Overclock Core', 'Increases attack speed (2.5%) and energy regeneration by 2%.');
menuContainer.addChild(overclockCorePopup);
isDataSpikePopupActive = true;
}
function displayReflexAcceleratorPopup() {
var reflexAcceleratorPopup = createSkillPopup('Reflex Accelerator', 'Boosts movement speed by 10%.');
menuContainer.addChild(reflexAcceleratorPopup);
isDataSpikePopupActive = true;
}
function displayDataSpikePopup() {
var dataSpikePopup = createSkillPopup('Data Spike', 'Increases critical hit chance by 5%.');
menuContainer.addChild(dataSpikePopup);
isDataSpikePopupActive = true;
}
function openSkillTreePopup(skillTreeName) {
menuContainer.removeChild(skillTreePopup);
var newPopup = new Container();
newPopup.width = 2048;
newPopup.height = 2732;
newPopup.x = 0;
newPopup.y = 0;
var newPopupBackground = LK.getAsset('skillTree_Background', {
anchorX: 0.5,
anchorY: 0.5
});
newPopupBackground.x = 2048 / 2;
newPopupBackground.y = 2732 / 2;
newPopup.addChild(newPopupBackground);
var chosenNodes;
if (skillTreeName === 'The Circuit of Ascension') {
chosenNodes = circuitNodes;
} else if (skillTreeName === 'The Echoes of Ancestry') {
chosenNodes = ancestryNodes;
} else if (skillTreeName === 'The Forge of Possibilities') {
chosenNodes = forgeNodes;
} else if (skillTreeName === 'The Prism of Potential') {
chosenNodes = prismNodes;
} else if (skillTreeName === 'The Nexus of Chaos') {
chosenNodes = nexusNodes;
} else if (skillTreeName === 'The Symphony of Shadows') {
chosenNodes = symphonyNodes;
}
// Add the chosen skill nodes to the popup
addSkillNodes(chosenNodes);
var skillTreeTitle = new Text2(skillTreeName, {
size: 150,
fill: "#ffffff",
fontWeight: "bold",
fontFamily: "Techno, sans-serif",
letterSpacing: 2,
stroke: "#00ffcc",
strokeThickness: 3
});
skillTreeTitle.x = 2048 / 2;
skillTreeTitle.y = 100;
skillTreeTitle.anchor.set(0.5, 0);
newPopup.addChild(skillTreeTitle);
// Create the skillTreePointsText at the bottom of the skill tree popup
skillTreePointsText = new Text2('Skill Points: ' + heroSkillPoints, {
size: 70,
fill: "#ffffff",
fontWeight: "bold"
});
skillTreePointsText.x = 2048 / 2;
skillTreePointsText.y = 2732 - 100; // bottom of the screen
skillTreePointsText.anchor.set(0.5, 0);
newPopup.addChild(skillTreePointsText);
// Now that skillTreePointsText is defined, we can safely call refreshTreePointsText
refreshTreePointsText();
menuContainer.addChild(newPopup);
}
A round button with icons of a sword and bow crossed over a shield, hinting at weapon switching.. Game interface icon. Medieval theme with crossed weapons on a shield. High contrast and intuitive design.
A rugged medieval bow with a wooden frame and slightly frayed string, perfect for a fantasy setting.. Game asset. Rustic and worn. Medieval fantasy style. High detail with visible wood grain.
Remove the joystick stick
A dark, stone-walled dungeon chamber viewed directly from above. The floor is uneven with scattered bones and chains. Each wall has an entrance centered in the middle, like arched doorways, positioned on the top, bottom, left, and right sides. The room fills the entire frame, with torch-lit ambiance.. Full-frame, top-down view of a stone-walled dungeon chamber. Uneven floor, bones, chains, torch lighting. Open, arched entrances centered on each wall: top, bottom, left, and right. No 3D perspective, even lighting.
A high-tech command center with a glowing grid floor and sleek metallic walls. The room is viewed from directly above and has open entrances centered in the middle of each wall (top, bottom, left, and right) for easy transitions. Neon lights and holographic screens line the walls, casting a blue glow.. Full-frame, top-down view of a futuristic command center. Glowing grid floor, metallic walls, neon lights. Open entrances centered on each wall: top, bottom, left, and right. Blue glow, no perspective distortion.
A top-down view of jungle ruins with moss-covered stone walls and floors. The floor is scattered with vines and broken pillars. Each wall has an entrance centered in the middle, resembling natural archways positioned on the top, bottom, left, and right. Sunlight filters through, illuminating the room softly.. Full-frame, top-down view of jungle ruins. Moss-covered stone walls and floors, vines, broken pillars. Open natural archways centered on each wall: top, bottom, left, and right. Soft sunlight, no perspective distortion.
A pixelated skull with green digital "code streams" dripping down, symbolizing a destructive digital attack. Neon green and dark gray.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
A circular emblem with a tree at its center, its branches intertwining with a glowing red lineage symbol.. Colors: Deep red, gold, and subtle white highlights.
Elemental Gear Icon: A gear made of multiple materials (fire, ice, lightning, and shadow) fused together, symbolizing crafting hybrid powers.. Colors: Vibrant orange, blue, yellow, and dark purple.
Shattered Prism Icon: A cracked prism emitting chaotic light beams, symbolizing untapped magical potential.. Colors: Neon purple and silver with multicolored light fragments.
Fractured Sphere Icon: A glowing orb breaking apart into jagged, floating shards, with chaotic energy swirling around it.. Colors: Neon purple, black, and electric green.
Phantom Mask Icon: A mysterious, floating mask with glowing eyes and tendrils of shadow curling around it, symbolizing illusions and deception.. Colors: White mask with glowing blue accents and black shadows.
Backdrop: An ancient, mystical forest with glowing runes etched into massive tree trunks. Colors: Earthy greens and browns with soft golden accents. Details: Misty ambiance with faint ethereal figures in the background.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Backdrop: A grand forge surrounded by molten lava and glowing hammers mid-swing. Colors: Fiery reds and oranges with metallic silver and gray. Details: Sparks flying and glowing weapon fragments scattered around.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Backdrop: A crystal cavern with refracted light beams splitting into vibrant colors. Colors: Radiant rainbow hues with a soft, dark background. Details: Floating crystals and magical glowing particles.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Backdrop: A warped reality scene with twisting, fragmented terrain and a swirling vortex in the background. Colors: Deep purples, neon pinks, and electric greens. Details: Fractured floating rocks and glitch-like patterns.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Backdrop: A dark, shadowy realm with faint glowing outlines of jagged structures and flowing mist. Colors: Black, deep purples, and faint blue highlights. Details: Shadows shifting and subtle glowing runes.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Weapon switch icon. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Start game button. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Big red kill button. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows.
Top-down view of a floating mechanical robot with a circular body. Thin, robotic arms extend outward, metallic and glowing. The head is small with glowing eyes. Strictly top-down view, no perspective or angle. Clean and detailed for 2D gameplay. Single Game Texture. In-Game asset. Top-down view. No shadows. 2D style. High contrast. Blank background.
A futuristic, top-down 2D game room featuring a minimalist industrial design. The room should have four distinct doorways at cardinal directions (up, down, left, and right). Each doorway should blend seamlessly into the room's aesthetic, with metallic frames and subtle glowing edges to indicate navigability. The room maintains its clean, tiled walls and floor, accented with industrial details like exposed pipes, vents, and panels. Lighting is ambient, with a mix of warm tones near the top and cooler tones along the walls. The overall theme is a high-tech but slightly weathered environment, ready for player navigation. No background. Transparent background. Blank background. No shadows. 2d. In-Game asset. flat
A Dagger Icon with 1's and 0's dripping off of it like blood. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A stylized, sleek cybernetic boot or leg silhouette with clear motion lines trailing behind it (like speed lines). Alternatively, three chevrons (>>>) pointing forward, glowing with blue energy, suggesting rapid advancement.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Two stylized head silhouettes (one representing the hero, one the enemy) connected by arcing lines of digital energy or circuit patterns. Color could be a mix of blue (control) and maybe red/purple (target).. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A shield shape formed from a 1's and 0's matrix pattern (like circuitry). Some lines of the grid could be missing or 'glitching' out, suggesting attacks passing through harmlessly. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Concentric circles or energy waves expanding outwards from a central point. The waves could be depicted as sharp lines of light blue or white energy. Could also incorporate small lightning-like sparks within the surge.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A more intense version of Power Surge. A fractured or exploding core shape at the center, emitting powerful, jagged energy waves (possibly in yellow or orange on top of blue). Could incorporate classic explosion symbol elements but rendered in the cybernetic style. Should look significantly more powerful than Power Surge.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
a cracked stone tablet or ancient scroll depicting elemental symbols with a subtle glow.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A hand silhouette centrally placed, with symbolic representations of different elements (fire, ice/water, lightning/wind) swirling around it or emanating from the fingertips. Could also be intersecting elemental runes.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A primal stone axe or spearhead with stylized speed lines or a spectral blue aura indicating swift movement.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A glowing paw print (wolf, bear, or cat-like) leaving a faint spectral trail.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A bundle of glowing green herbs tied together, or a single stylized leaf with potent green light radiating from its veins.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
a translucent, ghostly shield or a faint outline of a guardian spirit figure.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
An imposing, ornate tribal mask or helmet, perhaps with glowing eyes or runic carvings.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A stylized hammer striking an anvil, creating fiery sparks or engulfing the hammer head in flames.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A potion bottle or flask swirling with multiple distinct colors (red, blue, green).. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A arrow and sword splitting into a double arrow and double sword signifying a extra shot/sword.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Could also be a stylized recycling symbol combined with an upward arrow or a plus sign.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A symbol merging a sword and an arrow/bow, perhaps crossing each other with energy flowing between them.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A stylized metallic bracer or weapon hilt showing empty sockets being filled by small, glowing runes or gems.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A glowing, ornate hammer imbued with power, or a weapon silhouette undergoing a visible transformation with radiating light and complex runic patterns.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A sharp, faceted red crystal or gem shard glowing hotly.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
An angular, crystalline shield shimmering with blue light.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Could also be a green crystal pulsing with soft light.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A sharp, angular gust of wind symbol in bright yellow, or a stylized yellow feather.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A sharply focused eye symbol in deep indigo color. Could also be a fractured mirror shard reflecting light, or an indigo crystal with internal sparks/light flashes.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
Two different colored streams of energy (e.g., red and blue) flowing and swirling together in the center. Could also be a crystal icon split into two distinct colors.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A classic prism shape refracting a beam of white light into a rainbow spectrum. Could also be a figure surrounded by a swirling aura containing all the skill colors.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A crackling spark of energy rapidly shifting between multiple colors (purple, green, orange). Could also be a die symbol with elemental icons instead of pips, or a weapon impact with a question mark.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A shield shape that looks warped, dissolving at the edges, or made of static/glitches. Could show an arrow bouncing off at a weird angle or fizzling into nothing.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A jagged tear or swirling vortex in space, leaking multi-colored, chaotic energy. Could incorporate shifting, abstract symbols or question marks within the rift.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A silhouette of the hero glitching or flickering between different colors or slightly different forms. Could also be an upward arrow surrounded by swirling question marks or dice symbols.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A branching pattern like lightning or cracks, but made of chaotic, multi-colored energy. Could also be a visual of one chaotic explosion triggering others nearby.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A clock face or hourglass that is visibly cracked or shattering. Could also be a die symbol mid-roll or showing multiple faces at once.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
An imploding geometric shape or structure crumbling inwards into a chaotic void/vortex. Could be an intense version of the Unstable Rift, looking more menacing and powerful.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A boot icon dissolving into smoke or shadow at the heel. Sound wave symbol with a line striking through it, indicating silence.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A stylized cloak hood casting a deep shadow, with only faint eyes or nothing visible within. Could also be a figure splitting into a solid version and a shadowy decoy.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A sharp, wicked-looking dagger or blade edge dripping with black, shadowy substance.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A silhouette of a small, mischievous shadow creature (imp, tendril beast, raven?). Could also be a pair of glowing eyes peering out from darkness.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A dagger or fist icon striking, but with sound waves around it being cancelled or muffled (e.g., crossed out or dissolving).. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows
A central figure with several fading, translucent shadow copies trailing behind or positioned nearby. Could also be a weapon swing that leaves dark afterimages.. Single Game Texture. In-Game asset. 2d. Blank background. High contrast. No shadows