User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'skillPoints')' in or related to this line: 'var skillPointDisplay = new Text2('Skill Points: ' + hero.skillPoints, {' Line Number: 356
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'skillPoints')' in or related to this line: 'var skillPointDisplay = new Text2('Skill Points: ' + hero.skillPoints, {' Line Number: 356
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'skillPoints')' in or related to this line: 'var skillPointDisplay = new Text2('Skill Points: ' + hero.skillPoints, {' Line Number: 356
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'skillPoints')' in or related to this line: 'var skillPointDisplay = new Text2('Skill Points: ' + hero.skillPoints, {' Line Number: 356
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'skillPoints')' in or related to this line: 'var game = new LK.Game({' Line Number: 348
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'skillPoints')' in or related to this line: 'var skillPointDisplay = new Text2('Skill Points: ' + hero.skillPoints, {' Line Number: 355
User prompt
Please fix the bug: 'Uncaught TypeError: Cannot read properties of undefined (reading 'skillPoints')' in or related to this line: 'var skillPointDisplay = new Text2('Skill Points: ' + hero.skillPoints, {' Line Number: 355
User prompt
Add a skill point display to the skill tree screen. Position it at the top-right corner of the screen, above the 'Room' and 'Enemies Left' text. Initialize the hero with 3 skill points at the start of the game. Each time a skill is purchased by pressing the 'SPEND' button, deduct 1 point from the total. Disable the 'SPEND' button when no skill points remain. Ensure the skill point display updates dynamically whenever a point is spent.
User prompt
Make room1_music play when startbutton is pressed.
User prompt
Make it so when the startbutton is pressed, room1_music is started just like the rest of the rooms music logic
User prompt
Please fix the bug: 'Uncaught TypeError: LK.getMusic is not a function' in or related to this line: 'currentRoomMusic = LK.getMusic('room1_music');' Line Number: 338
User prompt
room1 music isn't playing
User prompt
Okay, I don't hear the room1 music when the start button is pressed.
User prompt
Great, now when I press the start game button, start room1 music logic as normal
User prompt
I still hear music when the game is initialized. This is wrong!
User prompt
No, the music should not play until the start button is pressed.
User prompt
Do not play room1 music until start game is pressed
User prompt
Revert the music back to when it worked
User prompt
All rooms are now playing nonstop after room is cleared. THIS IS NOT RIGHT! You're making it worse
User prompt
no, what you just did made the rest of the rooms act just like room1. Now all rooms music plays continuously and doesn't stop after room cleared
User prompt
Figure out why room1_music is forever looping instead of stopping like the rest of the rooms music
User prompt
After enemies in first room are killed STOP room1_music!!!!!
User prompt
Really take a deep dive into the room1_music logic throughout the entire code, Music is still continually playing after room1 is cleared. This is incorrect! Fix it please
User prompt
Music is still continually playing after room1 is cleared
User prompt
Music is still continually playing after room1 is cleared
/**** * Classes ****/ // Arrow class representing the arrows fired by the hero var Arrow = Container.expand(function () { var self = Container.call(this); var arrowGraphics = self.attachAsset('arrow', { anchorX: 0.5, anchorY: 0.5 }); self.speed = 15; self.damage = 5; self.update = function () { // Move the arrow in its current direction self.x += Math.cos(self.rotation) * self.speed; self.y += Math.sin(self.rotation) * self.speed; // Destroy arrow if it goes off screen 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); var backButtonGraphics = self.attachAsset('backButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 2, scaleY: 2 }); self.x = 150; // Move right a little self.y = 350; // Move down a little 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); // Attach the first frame of the enemy running animation var enemyGraphics = self.attachAsset('enemy_run1', { anchorX: 0.5, anchorY: 0.5 }); // Store animation frames 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 })]; // Initialize animation and movement variables self.speed = 2 + Math.random() * 0.5; // Random speed between 2 and 2.5 self.damageCooldown = 0; // Initialize damage cooldown var currentFrame = 0; var frameDelay = 30; // 500ms delay at 60FPS var frameCounter = 0; // Update function to handle animation self.update = function () { frameCounter++; if (frameCounter >= frameDelay) { frameCounter = 0; // Remove current frame and add the next frame self.removeChild(enemyGraphics); currentFrame = (currentFrame + 1) % frames.length; enemyGraphics = self.addChild(frames[currentFrame]); } // Calculate direction towards a slightly offset position around the hero var offsetX = (Math.random() - 0.5) * 20; // Further reduced random offset between -10 and 10 var offsetY = (Math.random() - 0.5) * 20; // Further reduced random offset between -10 and 10 var dx = hero.x + offsetX - self.x; var dy = hero.y + offsetY - self.y; var distance = Math.sqrt(dx * dx + dy * dy); // Normalize direction and move towards the hero var minDistance = 70; // Minimum distance to maintain from the hero if (distance > minDistance) { self.x += dx / distance * self.speed; // Use individual speed self.y += dy / distance * self.speed; // Use individual speed self.rotation = Math.atan2(dy, dx); // Face the hero } else { // Deal damage to the hero at regular intervals if (self.damageCooldown <= 0) { hero.health -= 5; // Deal 5 damage to the hero self.damageCooldown = 60; // Reset cooldown (1 second at 60FPS) updateRoomDisplay(); // Update health display } else { self.damageCooldown--; } // If too close, adjust position to maintain minimum distance self.x -= dx / distance * (minDistance - distance); self.y -= dy / distance * (minDistance - distance); } // Restrict movement within room boundaries 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; }); // Assets will be automatically created and loaded by the LK engine based on their usage in the code. // 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 }); // Add a sword asset to the hero self.swordGraphics = heroGraphics.addChild(LK.getAsset('sword', { anchorX: 0.5, anchorY: 0.5 })); // Position the sword further in front of the hero using fixed offsets self.swordGraphics.x = heroGraphics.width / 2 + 20; // Adjusted x position self.swordGraphics.y = 0; // Add a bow asset to the hero self.bowGraphics = self.attachAsset('bow', { anchorX: 0.5, anchorY: 0.5 }); // Position the bow slightly in front of the character self.bowGraphics.x = heroGraphics.width / 2; // Hide the bow initially self.bowGraphics.visible = false; // Initialize sword attack variables self.attackCooldown = 0; self.isAttacking = false; self.health = 100; // Starting health self.attackDuration = 20; // frames self.weaponType = 1; // Initialize weapon type to sword self.attackRange = 60; self.attackDamage = 10; self.speed = 3; self.joystick = null; // Reference to the Joystick object 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; // Restrict movement within boundaries unless at entrances 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; } // Update hero position this.x = nextX; this.y = nextY; // Ensure sword follows hero's rotation if (self.isAttacking) { // Zelda-style sword swing animation with a wide arc var swingProgress = (self.attackDuration - self.attackCooldown) / self.attackDuration; self.swordGraphics.rotation = Math.sin(swingProgress * Math.PI) * 1.2; // Wider arc self.swordGraphics.x = heroGraphics.width / 2 + Math.cos(swingProgress * Math.PI) * 30; // Move sword in arc self.swordGraphics.y = Math.sin(swingProgress * Math.PI) * 30; // Move sword in arc self.attackCooldown--; if (self.attackCooldown <= 0) { self.isAttacking = false; self.swordGraphics.rotation = 0; // Reset sword position } else { // Check for collision with enemies during sword attack 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); console.log("Enemy defeated by sword. Total killed: " + currentRoom.enemiesKilled); 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); // Attach joystick background and handle images with centering var joystickBackground = self.attachAsset('joystickBackground', { anchorX: 0.5, anchorY: 0.5 }); var joystickHandle = self.attachAsset('joystickHandle', { anchorX: 0.5, anchorY: 0.5 }); // Position joystick in the bottom-left corner, adjusting for touch screens self.x = joystickBackground.width / 2 + 100; self.y = 2732 - joystickBackground.height / 2 - 100; var maxRadius = 100; var isDragging = false; // Handle dragging logic 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 }; // Centered joystick means no movement }; return self; }); // StartGameButton class representing the start game button functionality var StartGameButton = Container.expand(function () { var self = Container.call(this); var startButtonGraphics = self.attachAsset('startGameButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 }); self.x = 2048 / 2; // Center horizontally self.y = 2732 - 400; // Move up a little more self.down = function () { console.log("Start Game button pressed"); menuContainer.removeChild(skillTreePopup); isPopupActive = false; // Disable all popups isDataSpikePopupActive = false; // Disable specific popups initializeGame(); }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x000000 // Init game with black background }); /**** * Game Code ****/ // Function to initialize the game function initializeGame() { console.log("Game initialized"); // Add game initialization logic here // For example, start the first room, set up the hero, etc. currentRoom = new Room(1); hero.x = 2048 / 2; hero.y = 2732 / 2; updateRoomDisplay(); playRoomMusic(currentRoom.number); } function displayOverloadBlastPopup() { // Create a new container for the popup var overloadBlastPopup = new Container(); overloadBlastPopup.width = 2048; overloadBlastPopup.height = 2732; overloadBlastPopup.x = 0; overloadBlastPopup.y = 0; // Add a translucent background for reading clarity 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; overloadBlastPopup.addChild(translucentBackground); // Add the title text for the Overload Blast var overloadBlastTitle = new Text2('Overload Blast', { size: 120, fill: "#ffffff", fontWeight: "bold", fontFamily: "Techno, sans-serif", letterSpacing: 2, stroke: "#00ffcc", strokeThickness: 3 }); overloadBlastTitle.x = 2048 / 2; overloadBlastTitle.y = 2732 / 2 + 150; // Moved down further overloadBlastTitle.anchor.set(0.5, 0.5); overloadBlastPopup.addChild(overloadBlastTitle); // Add the skill description text under the Overload Blast title var skillDescription = new Text2('Unleashes a massive explosion that damages all enemies in the room.', { size: 80, fill: "#ffffff", fontFamily: "Arial, sans-serif", letterSpacing: 1, stroke: "#00ffcc", strokeThickness: 2, wordWrap: true, wordWrapWidth: 1800 }); skillDescription.x = 2048 / 2; skillDescription.y = overloadBlastTitle.y + 150; // Move it further down below the title skillDescription.anchor.set(0.5, 0.5); overloadBlastPopup.addChild(skillDescription); // Add the popup to the menu container menuContainer.addChild(overloadBlastPopup); isDataSpikePopupActive = true; // Set Overload Blast popup active flag to true // Add an exit button to close the popup var exitButton = LK.getAsset('cancelButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 }); exitButton.x = 2048 / 2 - 600; // Move twice as far to the left exitButton.y = 2732 / 2 + 850; // Move further down exitButton.down = function () { menuContainer.removeChild(overloadBlastPopup); isDataSpikePopupActive = false; // Set Overload Blast popup active flag to false }; overloadBlastPopup.addChild(exitButton); // Add a spend button mirrored on the opposite side of the exit button var spendButton = LK.getAsset('spendButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 }); spendButton.x = 2048 / 2 + 600; // Mirror position to the right spendButton.y = 2732 / 2 + 850; // Move further down spendButton.down = function () { console.log("Spend button clicked"); // Add functionality for spend button here }; overloadBlastPopup.addChild(spendButton); } function displayPowerSurgePopup() { // Create a new container for the popup var powerSurgePopup = new Container(); powerSurgePopup.width = 2048; powerSurgePopup.height = 2732; powerSurgePopup.x = 0; powerSurgePopup.y = 0; // Add a translucent background for reading clarity 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; powerSurgePopup.addChild(translucentBackground); // Add the title text for the Power Surge var powerSurgeTitle = new Text2('Power Surge', { size: 120, fill: "#ffffff", fontWeight: "bold", fontFamily: "Techno, sans-serif", letterSpacing: 2, stroke: "#00ffcc", strokeThickness: 3 }); powerSurgeTitle.x = 2048 / 2; powerSurgeTitle.y = 2732 / 2 + 150; // Moved down further powerSurgeTitle.anchor.set(0.5, 0.5); powerSurgePopup.addChild(powerSurgeTitle); // Add the skill description text under the Power Surge title var skillDescription = new Text2('Releases an energy burst that damages all nearby enemies.', { size: 80, fill: "#ffffff", fontFamily: "Arial, sans-serif", letterSpacing: 1, stroke: "#00ffcc", strokeThickness: 2, wordWrap: true, wordWrapWidth: 1800 }); skillDescription.x = 2048 / 2; skillDescription.y = powerSurgeTitle.y + 150; // Move it further down below the title skillDescription.anchor.set(0.5, 0.5); powerSurgePopup.addChild(skillDescription); // Add the popup to the menu container menuContainer.addChild(powerSurgePopup); isDataSpikePopupActive = true; // Set Power Surge popup active flag to true // Add an exit button to close the popup var exitButton = LK.getAsset('cancelButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 }); exitButton.x = 2048 / 2 - 600; // Move twice as far to the left exitButton.y = 2732 / 2 + 850; // Move further down exitButton.down = function () { menuContainer.removeChild(powerSurgePopup); isDataSpikePopupActive = false; // Set Power Surge popup active flag to false }; powerSurgePopup.addChild(exitButton); // Add a spend button mirrored on the opposite side of the exit button var spendButton = LK.getAsset('spendButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 }); spendButton.x = 2048 / 2 + 600; // Mirror position to the right spendButton.y = 2732 / 2 + 850; // Move further down spendButton.down = function () { console.log("Spend button clicked"); // Add functionality for spend button here }; powerSurgePopup.addChild(spendButton); } function displayDodgeMatrixPopup() { // Create a new container for the popup var dodgeMatrixPopup = new Container(); dodgeMatrixPopup.width = 2048; dodgeMatrixPopup.height = 2732; dodgeMatrixPopup.x = 0; dodgeMatrixPopup.y = 0; // Add a translucent background for reading clarity 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; dodgeMatrixPopup.addChild(translucentBackground); // Add the title text for the Dodge Matrix var dodgeMatrixTitle = new Text2('Dodge Matrix', { size: 120, fill: "#ffffff", fontWeight: "bold", fontFamily: "Techno, sans-serif", letterSpacing: 2, stroke: "#00ffcc", strokeThickness: 3 }); dodgeMatrixTitle.x = 2048 / 2; dodgeMatrixTitle.y = 2732 / 2 + 150; // Moved down further dodgeMatrixTitle.anchor.set(0.5, 0.5); dodgeMatrixPopup.addChild(dodgeMatrixTitle); // Add the skill description text under the Dodge Matrix title var skillDescription = new Text2('Grants a 10% chance to evade enemy attacks.', { size: 80, fill: "#ffffff", fontFamily: "Arial, sans-serif", letterSpacing: 1, stroke: "#00ffcc", strokeThickness: 2, wordWrap: true, wordWrapWidth: 1800 }); skillDescription.x = 2048 / 2; skillDescription.y = dodgeMatrixTitle.y + 150; // Move it further down below the title skillDescription.anchor.set(0.5, 0.5); dodgeMatrixPopup.addChild(skillDescription); // Add the popup to the menu container menuContainer.addChild(dodgeMatrixPopup); isDataSpikePopupActive = true; // Set Dodge Matrix popup active flag to true // Add an exit button to close the popup var exitButton = LK.getAsset('cancelButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 }); exitButton.x = 2048 / 2 - 600; // Move twice as far to the left exitButton.y = 2732 / 2 + 850; // Move further down exitButton.down = function () { menuContainer.removeChild(dodgeMatrixPopup); isDataSpikePopupActive = false; // Set Dodge Matrix popup active flag to false }; dodgeMatrixPopup.addChild(exitButton); // Add a spend button mirrored on the opposite side of the exit button var spendButton = LK.getAsset('spendButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 }); spendButton.x = 2048 / 2 + 600; // Mirror position to the right spendButton.y = 2732 / 2 + 850; // Move further down spendButton.down = function () { console.log("Spend button clicked"); // Add functionality for spend button here }; dodgeMatrixPopup.addChild(spendButton); } function displayNeuralHijackPopup() { // Create a new container for the popup var neuralHijackPopup = new Container(); neuralHijackPopup.width = 2048; neuralHijackPopup.height = 2732; neuralHijackPopup.x = 0; neuralHijackPopup.y = 0; // Add a translucent background for reading clarity 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; neuralHijackPopup.addChild(translucentBackground); // Add the title text for the Neural Hijack var neuralHijackTitle = new Text2('Neural Hijack', { size: 120, fill: "#ffffff", fontWeight: "bold", fontFamily: "Techno, sans-serif", letterSpacing: 2, stroke: "#00ffcc", strokeThickness: 3 }); neuralHijackTitle.x = 2048 / 2; neuralHijackTitle.y = 2732 / 2 + 150; // Moved down further neuralHijackTitle.anchor.set(0.5, 0.5); neuralHijackPopup.addChild(neuralHijackTitle); // Add the skill description text under the Neural Hijack title var skillDescription = new Text2('Temporarily converts an enemy to fight for you.', { size: 80, fill: "#ffffff", fontFamily: "Arial, sans-serif", letterSpacing: 1, stroke: "#00ffcc", strokeThickness: 2, wordWrap: true, wordWrapWidth: 1800 }); skillDescription.x = 2048 / 2; skillDescription.y = neuralHijackTitle.y + 150; // Move it further down below the title skillDescription.anchor.set(0.5, 0.5); neuralHijackPopup.addChild(skillDescription); // Add the popup to the menu container menuContainer.addChild(neuralHijackPopup); isDataSpikePopupActive = true; // Set Neural Hijack popup active flag to true // Add an exit button to close the popup var exitButton = LK.getAsset('cancelButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 }); exitButton.x = 2048 / 2 - 600; // Move twice as far to the left exitButton.y = 2732 / 2 + 850; // Move further down exitButton.down = function () { menuContainer.removeChild(neuralHijackPopup); isDataSpikePopupActive = false; // Set Neural Hijack popup active flag to false }; neuralHijackPopup.addChild(exitButton); // Add a spend button mirrored on the opposite side of the exit button var spendButton = LK.getAsset('spendButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 }); spendButton.x = 2048 / 2 + 600; // Mirror position to the right spendButton.y = 2732 / 2 + 850; // Move further down spendButton.down = function () { console.log("Spend button clicked"); // Add functionality for spend button here }; neuralHijackPopup.addChild(spendButton); } function displayOverclockCorePopup() { // Create a new container for the popup var overclockCorePopup = new Container(); overclockCorePopup.width = 2048; overclockCorePopup.height = 2732; overclockCorePopup.x = 0; overclockCorePopup.y = 0; // Add a translucent background for reading clarity 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; overclockCorePopup.addChild(translucentBackground); // Add the title text for the Overclock Core var overclockCoreTitle = new Text2('Overclock Core', { size: 120, fill: "#ffffff", fontWeight: "bold", fontFamily: "Techno, sans-serif", letterSpacing: 2, stroke: "#00ffcc", strokeThickness: 3 }); overclockCoreTitle.x = 2048 / 2; overclockCoreTitle.y = 2732 / 2 + 150; // Moved down further overclockCoreTitle.anchor.set(0.5, 0.5); overclockCorePopup.addChild(overclockCoreTitle); // Add the skill description text under the Overclock Core title var skillDescription = new Text2('Increases attack speed (2.5%) and energy regeneration by 2%.', { size: 80, fill: "#ffffff", fontFamily: "Arial, sans-serif", letterSpacing: 1, stroke: "#00ffcc", strokeThickness: 2, wordWrap: true, wordWrapWidth: 1800 }); skillDescription.x = 2048 / 2; skillDescription.y = overclockCoreTitle.y + 150; // Move it further down below the title skillDescription.anchor.set(0.5, 0.5); overclockCorePopup.addChild(skillDescription); // Add the popup to the menu container menuContainer.addChild(overclockCorePopup); isDataSpikePopupActive = true; // Set Overclock Core popup active flag to true // Add an exit button to close the popup var exitButton = LK.getAsset('cancelButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 }); exitButton.x = 2048 / 2 - 600; // Move twice as far to the left exitButton.y = 2732 / 2 + 850; // Move further down exitButton.down = function () { menuContainer.removeChild(overclockCorePopup); isDataSpikePopupActive = false; // Set Overclock Core popup active flag to false }; overclockCorePopup.addChild(exitButton); // Add a spend button mirrored on the opposite side of the exit button var spendButton = LK.getAsset('spendButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 }); spendButton.x = 2048 / 2 + 600; // Mirror position to the right spendButton.y = 2732 / 2 + 850; // Move further down spendButton.down = function () { console.log("Spend button clicked"); // Add functionality for spend button here }; overclockCorePopup.addChild(spendButton); } function displayReflexAcceleratorPopup() { // Create a new container for the popup var reflexAcceleratorPopup = new Container(); reflexAcceleratorPopup.width = 2048; reflexAcceleratorPopup.height = 2732; reflexAcceleratorPopup.x = 0; reflexAcceleratorPopup.y = 0; // Add a translucent background for reading clarity 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; reflexAcceleratorPopup.addChild(translucentBackground); // Add the title text for the Reflex Accelerator var reflexAcceleratorTitle = new Text2('Reflex Accelerator', { size: 120, fill: "#ffffff", fontWeight: "bold", fontFamily: "Techno, sans-serif", letterSpacing: 2, stroke: "#00ffcc", strokeThickness: 3 }); reflexAcceleratorTitle.x = 2048 / 2; reflexAcceleratorTitle.y = 2732 / 2 + 150; // Moved down further reflexAcceleratorTitle.anchor.set(0.5, 0.5); reflexAcceleratorPopup.addChild(reflexAcceleratorTitle); // Add the skill description text under the Reflex Accelerator title var skillDescription = new Text2('Boosts movement speed by 10%.', { size: 80, fill: "#ffffff", fontFamily: "Arial, sans-serif", letterSpacing: 1, stroke: "#00ffcc", strokeThickness: 2, wordWrap: true, wordWrapWidth: 1800 }); skillDescription.x = 2048 / 2; skillDescription.y = reflexAcceleratorTitle.y + 150; // Move it further down below the title skillDescription.anchor.set(0.5, 0.5); reflexAcceleratorPopup.addChild(skillDescription); // Add the popup to the menu container menuContainer.addChild(reflexAcceleratorPopup); isDataSpikePopupActive = true; // Set Reflex Accelerator popup active flag to true // Add an exit button to close the popup var exitButton = LK.getAsset('cancelButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 }); exitButton.x = 2048 / 2 - 600; // Move twice as far to the left exitButton.y = 2732 / 2 + 850; // Move further down exitButton.down = function () { menuContainer.removeChild(reflexAcceleratorPopup); isDataSpikePopupActive = false; // Set Reflex Accelerator popup active flag to false }; reflexAcceleratorPopup.addChild(exitButton); // Add a spend button mirrored on the opposite side of the exit button var spendButton = LK.getAsset('spendButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 }); spendButton.x = 2048 / 2 + 600; // Mirror position to the right spendButton.y = 2732 / 2 + 850; // Move further down spendButton.down = function () { console.log("Spend button clicked"); // Add functionality for spend button here }; reflexAcceleratorPopup.addChild(spendButton); } function displayDataSpikePopup() { // Create a new container for the popup var dataSpikePopup = new Container(); dataSpikePopup.width = 2048; dataSpikePopup.height = 2732; dataSpikePopup.x = 0; dataSpikePopup.y = 0; // Add a translucent background for reading clarity 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; dataSpikePopup.addChild(translucentBackground); // Add the title text for the Data Spike var dataSpikeTitle = new Text2('Data Spike', { size: 120, // Increased size fill: "#ffffff", fontWeight: "bold", fontFamily: "Techno, sans-serif", letterSpacing: 2, stroke: "#00ffcc", strokeThickness: 3 }); dataSpikeTitle.x = 2048 / 2; dataSpikeTitle.y = 2732 / 2 + 150; // Moved down further dataSpikeTitle.anchor.set(0.5, 0.5); dataSpikePopup.addChild(dataSpikeTitle); // Add the skill description text under the Data Spike title var skillDescription = new Text2('Increases critical hit chance by 5%.', { size: 80, fill: "#ffffff", fontFamily: "Arial, sans-serif", letterSpacing: 1, stroke: "#00ffcc", strokeThickness: 2, wordWrap: true, wordWrapWidth: 1800 }); skillDescription.x = 2048 / 2; skillDescription.y = dataSpikeTitle.y + 150; // Move it further down below the title skillDescription.anchor.set(0.5, 0.5); dataSpikePopup.addChild(skillDescription); function displayReflexAcceleratorPopup() { // Create a new container for the popup var reflexAcceleratorPopup = new Container(); reflexAcceleratorPopup.width = 2048; reflexAcceleratorPopup.height = 2732; reflexAcceleratorPopup.x = 0; reflexAcceleratorPopup.y = 0; // Add a translucent background for reading clarity 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; reflexAcceleratorPopup.addChild(translucentBackground); // Add the title text for the Reflex Accelerator var reflexAcceleratorTitle = new Text2('Reflex Accelerator', { size: 120, fill: "#ffffff", fontWeight: "bold", fontFamily: "Techno, sans-serif", letterSpacing: 2, stroke: "#00ffcc", strokeThickness: 3 }); reflexAcceleratorTitle.x = 2048 / 2; reflexAcceleratorTitle.y = 2732 / 2 + 150; // Moved down further reflexAcceleratorTitle.anchor.set(0.5, 0.5); reflexAcceleratorPopup.addChild(reflexAcceleratorTitle); // Add the skill description text under the Reflex Accelerator title var skillDescription = new Text2('Boosts movement speed by 10%.', { size: 80, fill: "#ffffff", fontFamily: "Arial, sans-serif", letterSpacing: 1, stroke: "#00ffcc", strokeThickness: 2 }); skillDescription.x = 2048 / 2; skillDescription.y = reflexAcceleratorTitle.y + 100; // Position it below the title skillDescription.anchor.set(0.5, 0.5); reflexAcceleratorPopup.addChild(skillDescription); // Add the popup to the menu container menuContainer.addChild(reflexAcceleratorPopup); isDataSpikePopupActive = true; // Set Reflex Accelerator popup active flag to true // Add an exit button to close the popup var exitButton = LK.getAsset('cancelButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 }); exitButton.x = 2048 / 2 - 600; // Move twice as far to the left exitButton.y = 2732 / 2 + 850; // Move further down exitButton.down = function () { menuContainer.removeChild(reflexAcceleratorPopup); isDataSpikePopupActive = false; // Set Reflex Accelerator popup active flag to false }; reflexAcceleratorPopup.addChild(exitButton); // Add a spend button mirrored on the opposite side of the exit button var spendButton = LK.getAsset('spendButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, scaleY: 3 }); spendButton.x = 2048 / 2 + 600; // Mirror position to the right spendButton.y = 2732 / 2 + 850; // Move further down spendButton.down = function () { console.log("Spend button clicked"); // Add functionality for spend button here }; reflexAcceleratorPopup.addChild(spendButton); } // Add the popup to the menu container menuContainer.addChild(dataSpikePopup); isDataSpikePopupActive = true; // Set Data Spike popup active flag to true // Add an exit button to close the popup var exitButton = LK.getAsset('cancelButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, // Reduce width by 25% scaleY: 3 // Reduce height by 25% }); exitButton.x = 2048 / 2 - 600; // Move twice as far to the left exitButton.y = 2732 / 2 + 850; // Move further down exitButton.down = function () { menuContainer.removeChild(dataSpikePopup); isDataSpikePopupActive = false; // Set Data Spike popup active flag to false isDataSpikePopupActive = false; // Reset Data Spike popup active flag }; dataSpikePopup.addChild(exitButton); // Add a spend button mirrored on the opposite side of the exit button var spendButton = LK.getAsset('spendButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 3, // Reduce width by 25% scaleY: 3 // Reduce height by 25% }); spendButton.x = 2048 / 2 + 600; // Mirror position to the right spendButton.y = 2732 / 2 + 850; // Move further down spendButton.down = function () { console.log("Spend button clicked"); // Add functionality for spend button here }; dataSpikePopup.addChild(spendButton); } // Global flags to indicate when popups are active var isPopupActive = false; var isDataSpikePopupActive = false; // Create separate containers for game, UI, and Menu elements var gameContainer = new Container(); var uiContainer = new Container(); var menuContainer = new Container(); game.addChild(gameContainer); game.addChild(uiContainer); game.addChild(menuContainer); // Create a popup container to hold the skill tree buttons var skillTreePopup = new Container(); skillTreePopup.width = 2048; skillTreePopup.height = 2732; skillTreePopup.x = 0; skillTreePopup.y = 0; // Add a background asset to the skill tree popup var skillTreeBackground = LK.getAsset('skillTree_Background', { anchorX: 0.5, anchorY: 0.5 }); skillTreeBackground.x = 2048 / 2; skillTreeBackground.y = 2732 / 2; skillTreePopup.addChild(skillTreeBackground); // Define button properties var buttonWidth = 300; var buttonHeight = 100; var buttonSpacing = 50; var buttonYStart = 500; // Skill tree button titles and themes 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' }]; // Define positions for a new layout with 3 rows and 2 columns 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 }]; // Create named selections for each skill tree skillTrees.forEach(function (skillTree, index) { var position = positions[index]; // Add title text for each skill tree 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); // Attach skill tree image asset to each title using static mapping 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' }; var skillTreeAssetId = skillTreeAssetMap[skillTree.title]; var skillTreeAsset = LK.getAsset(skillTreeAssetId, { anchorX: 0.5, anchorY: 0.5 }); // Ensure skill tree asset is added only once if (!skillTreePopup.children.includes(skillTreeAsset)) { skillTreePopup.addChild(skillTreeAsset); } skillTreeAsset.x = position.x; skillTreeAsset.y = position.y; // Ensure skill tree asset is added only once if (!skillTreePopup.children.includes(skillTreeAsset)) { skillTreePopup.addChild(skillTreeAsset); } // Add click event to open skill tree popup titleText.down = function () { console.log("Skill tree opened: " + skillTree.title); openSkillTreePopup(skillTree.title); }; // Add title to the popup skillTreePopup.addChild(titleText); }); // Set isPopupActive to true when the skill tree popup is displayed isPopupActive = true; // Add the popup to the game menuContainer.addChild(skillTreePopup); // Add Start Game button to the skillTree_Background var startGameButton = new StartGameButton(); skillTreePopup.addChild(startGameButton); // Function to open a new skill tree popup function openSkillTreePopup(skillTreeName) { // Remove the current popup menuContainer.removeChild(skillTreePopup); // Create a new popup container var newPopup = new Container(); newPopup.width = 2048; newPopup.height = 2732; newPopup.x = 0; newPopup.y = 0; // Add a background to the new popup var newPopupBackground = LK.getAsset('skillTree_Background', { anchorX: 0.5, anchorY: 0.5 }); newPopupBackground.x = 2048 / 2; newPopupBackground.y = 2732 / 2; newPopup.addChild(newPopupBackground); // Attach the specific skill tree asset on top of the background if (skillTreeName === 'The Circuit of Ascension') { var circuitAsset = LK.getAsset('popup_circuitofascension', { anchorX: 0.5, anchorY: 0.5 }); circuitAsset.x = 2048 / 2; circuitAsset.y = 2732 / 2; newPopup.x = (2048 - newPopup.width) / 2; newPopup.y = (2732 - newPopup.height) / 2; newPopup.addChild(circuitAsset); // Add a back button to return to skillTree_Background var backButton = new BackButton(); newPopup.addChild(backButton); // Add skill nodes var skillNodes = [{ id: 'data_spike_icon', x: 2048 / 4, y: 2732 / 6, name: 'Data Spike' }, { id: 'reflex_accelerator_icon', x: 2048 / 2, y: 2732 / 6, name: 'Reflex Accelerator' }, { id: 'overclock_core_icon', x: 3 * 2048 / 4, y: 2732 / 6, name: 'Overclock Core' }, { id: 'neural_hijack_icon', x: 2048 / 4, y: 2 * 2732 / 6, name: 'Neural Hijack' }, { id: 'dodge_matrix_icon', x: 2048 / 2, y: 2 * 2732 / 6, name: 'Dodge Matrix' }, { id: 'brown_node_icon', x: 3 * 2048 / 4, y: 2 * 2732 / 6, name: 'Power Surge' }, { id: 'ultimate_skill_icon', x: 2048 / 2, y: 3 * 2732 / 6, name: 'Ultimate Skill' }]; skillNodes.forEach(function (node) { var skillNode = LK.getAsset(node.id, { anchorX: 0.5, anchorY: 0.5 }); skillNode.x = node.x; skillNode.y = node.y; skillNode.down = function () { if (isDataSpikePopupActive) { return; // Exit if Data Spike popup is already active } console.log('Skill node ' + node.name + ' selected'); if (node.name === 'Data Spike') { displayDataSpikePopup(); isDataSpikePopupActive = true; // Set Data Spike popup active flag to true } else if (node.name === 'Overclock Core') { displayOverclockCorePopup(); isDataSpikePopupActive = true; // Set Overclock Core popup active flag to true } else if (node.name === 'Reflex Accelerator') { displayReflexAcceleratorPopup(); isDataSpikePopupActive = true; // Set Reflex Accelerator popup active flag to true } else if (node.name === 'Neural Hijack') { displayNeuralHijackPopup(); isDataSpikePopupActive = true; // Set Neural Hijack popup active flag to true } else if (node.name === 'Dodge Matrix') { displayDodgeMatrixPopup(); isDataSpikePopupActive = true; // Set Dodge Matrix popup active flag to true } else if (node.name === 'Power Surge') { displayPowerSurgePopup(); isDataSpikePopupActive = true; // Set Power Surge popup active flag to true } else if (node.name === 'Ultimate Skill') { displayOverloadBlastPopup(); isDataSpikePopupActive = true; // Set Overload Blast popup active flag to true } // Lock all nodes (for now, just log the action) console.log('All nodes are now inactive/locked.'); // Highlight the node by changing its color or adding a glow effect var originalColor = skillNode.tint; skillNode.tint = 0xffff00; // Change color to yellow for highlight // Revert the highlight after 1 second LK.setTimeout(function () { skillNode.tint = originalColor; // Revert to original color }, 1000); }; console.log('Skill node ' + node.name + ' added to Row ' + (node.y === 2732 / 6 ? '1' : node.y === 2732 / 3 ? '2' : '3')); newPopup.addChild(skillNode); }); // Connect nodes with glowing lines var glowingLine = LK.getAsset('glowing_line_asset', { anchorX: 0.5, anchorY: 0.5 }); // Connect nodes within each branch var connectNodes = function connectNodes(node1, node2) { var line = LK.getAsset('glowing_line_asset', { anchorX: 0.5, anchorY: 0.5 }); line.x = (node1.x + node2.x) / 2; line.y = (node1.y + node2.y) / 2; newPopup.addChild(line); }; // Connect Tier 1 nodes (no Tier 2 or Tier 3 nodes to connect) } else if (skillTreeName === 'The Echoes of Ancestry') { var ancestryAsset = LK.getAsset('popup_echoesofancestry', { anchorX: 0.5, anchorY: 0.5 }); ancestryAsset.x = 2048 / 2; ancestryAsset.y = 2732 / 2; newPopup.addChild(ancestryAsset); } else if (skillTreeName === 'The Forge of Possibilities') { var forgeAsset = LK.getAsset('popup_forgeofpossibilities', { anchorX: 0.5, anchorY: 0.5 }); forgeAsset.x = 2048 / 2; forgeAsset.y = 2732 / 2; newPopup.addChild(forgeAsset); } else if (skillTreeName === 'The Prism of Potential') { var prismAsset = LK.getAsset('popup_prismofpotential', { anchorX: 0.5, anchorY: 0.5 }); prismAsset.x = 2048 / 2; prismAsset.y = 2732 / 2; newPopup.addChild(prismAsset); } else if (skillTreeName === 'The Nexus of Chaos') { var nexusAsset = LK.getAsset('popup_nexusofchaos', { anchorX: 0.5, anchorY: 0.5 }); nexusAsset.x = 2048 / 2; nexusAsset.y = 2732 / 2; newPopup.addChild(nexusAsset); } else if (skillTreeName === 'The Symphony of Shadows') { var symphonyAsset = LK.getAsset('popup_symphonyofshadows', { anchorX: 0.5, anchorY: 0.5 }); symphonyAsset.x = 2048 / 2; symphonyAsset.y = 2732 / 2; newPopup.addChild(symphonyAsset); } // Add the skill tree name at the top var skillTreeTitle = new Text2(skillTreeName, { size: 150, // Increased size 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); // Log the skill tree name console.log('Skill tree opened: ' + skillTreeName); // Add the new popup to the menu container menuContainer.addChild(newPopup); console.log('Skill tree layout updated for The Circuit of Ascension'); } function stopRoomMusic() { if (currentRoomMusic) { currentRoomMusic.stop(); } } var currentRoomMusic; function playRoomMusic(roomNumber) { if (currentRoomMusic) { currentRoomMusic.stop(); } switch (roomNumber) { case 1: currentRoomMusic = LK.getSound('room1_music'); currentRoomMusic.play({ loop: false, fade: { start: 1, end: 0, duration: 800 } }); 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; } // Removed redundant music play call } function initializeFirstRoomMusic() { currentRoomMusic = LK.getSound('room1_music'); currentRoomMusic.play({ loop: true, fade: { start: 0, end: 1, duration: 1000 } }); } initializeFirstRoomMusic(); // Add sword attack on tap/click; // Create a button to kill all enemies in the room var killAllButton = LK.getAsset('killAllButton', { anchorX: 0.5, anchorY: 0.5 }); killAllButton.x = 100; // Move further to the left killAllButton.y = 2732 - 350; // Move up uiContainer.addChild(killAllButton); // Add event listener for kill all button killAllButton.down = function (x, y, obj) { if (isPopupActive || isDataSpikePopupActive) { return; } // Kill all enemies in the current room 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(); // Update the room display text checkRoomCleared(); // Check if the room is cleared after killing all enemies updateRoomDisplay(); checkRoomCleared(); }; LK.playMusic('room1_music', { fade: { start: 0, end: 1, duration: 1000 } }); // Create an attack button asset var attackButton = LK.getAsset('attackIcon', { anchorX: 0.5, anchorY: 0.5 }); attackButton.x = 2048 - 150; // Position above the weapon switch button attackButton.y = 2732 - 300; // Adjust position uiContainer.addChild(attackButton); // Add event listener for attack button attackButton.down = function (x, y, obj) { if (isPopupActive) { return; } if (hero.weaponType === 1) { // Sword attack logic hero.isAttacking = true; hero.attackCooldown = hero.attackDuration; // Swing sword animation hero.swordGraphics.rotation = -0.5; // Start swing LK.setTimeout(function () { hero.swordGraphics.rotation = 0.5; // End swing }, hero.attackDuration * 10); // Duration of swing } else if (hero.weaponType === 2) { // Bow attack logic var arrow = new Arrow(); arrow.x = hero.x; arrow.y = hero.y; arrow.rotation = hero.rotation; // Match hero's facing direction arrows.push(arrow); game.addChild(arrow); } }; // Background images for different rooms // Array of background images for different rooms var roomBackgroundImages = ['backgroundImage1', // Replace with actual image asset IDs 'backgroundImage2', 'backgroundImage3', 'backgroundImage4', 'backgroundImage5']; // Room boundary dimensions var roomWidth = 2048; var roomHeight = 2732; var wallThickness = 400; // Wall thickness around the room var entranceWidth = 200; // Width of each entrance at middle of edges // Define spawn points for enemies var spawnPoints = { leftCenter: { x: wallThickness, y: roomHeight / 2 }, rightCenter: { x: roomWidth - wallThickness, y: roomHeight / 2 }, topCenter: { x: roomWidth / 2, y: wallThickness }, bottomCenter: { x: roomWidth / 2, y: roomHeight - wallThickness } }; // Coordinates for entrance areas (assuming entrances are centered on each wall) 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 } }; // Room class representing individual rooms // Display room number var Room = function Room(number) { this.number = number; this.enemies = []; this.isCleared = false; this.spawnLimit = this.number === 1 ? 24 : 12 * this.number; // Set spawn limit for room1 to 24, others based on room number this.killGoal = this.spawnLimit; // Align kill goal with spawn limit this.enemiesSpawned = 0; this.enemiesKilled = 0; this.enemyCounter = this.spawnLimit; // Configure room based on its number for difficulty scaling 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); // Spawn every 0.5 seconds }; this.spawnEnemy = function () { if (this.enemiesSpawned < this.spawnLimit && !isPopupActive && currentRoom.number === this.number) { // Spawn limit set to 50 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; // Ensure enemy is active enemy.health = 10; // Initialize enemy health enemy.visible = true; // Ensure enemy is visible this.enemies.push(enemy); game.addChild(enemy); // Ensure enemy is added to the game this.enemiesSpawned++; } }; this.init(); }; // Initialize the current room only once var currentRoom = new Room(1); // Set the initial background when the game starts var initialBgImage = LK.getAsset('backgroundImage1', { anchorX: 0.5, anchorY: 0.5 }); initialBgImage.x = 2048 / 2; initialBgImage.y = 2732 / 2; game.addChildAt(initialBgImage, 0); // Add at the bottom layer game.background = initialBgImage; // Store background reference for future transitions // Create a black bar (statsBar) behind the text elements var statsBar = LK.getAsset('box', { anchorX: 0.0, anchorY: 0.0, width: 2048, height: 100, x: 0, y: 0 }); game.addChild(statsBar); // Add the statsBar first to ensure it's behind the text // Room display setup var roomDisplay = new Text2('Room: ' + currentRoom.number + ' | Enemies Left: ' + (currentRoom.spawnLimit - currentRoom.enemiesKilled), { size: 70, fill: "#ffffff", fontWeight: "bold" }); roomDisplay.x = 1000; // Move further to the left roomDisplay.y = 20; game.addChild(roomDisplay); // Add directly to the game layer // Update display text function updateRoomDisplay() { var enemiesLeft = currentRoom.spawnLimit - currentRoom.enemiesKilled; roomDisplay.setText('Room: ' + currentRoom.number + ' | Enemies Left: ' + Math.max(enemiesLeft, 0)); healthText.setText('Health: ' + hero.health); // Also update health display console.log("Updating room display: Room " + currentRoom.number + ", Enemies Left: " + enemiesLeft); // Debug log } var currentRoomMusic; function transitionToNextRoom() { stopRoomMusic(); playRoomMusic(currentRoom.number); // Clear previous background if it exists if (game.background) { game.removeChild(game.background); } // Create a new room with increased difficulty 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); // Reset the enemy counter to the number of enemies that will be spawned currentRoom.enemiesKilled = 0; // Update background based on the current room number 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); // Add at the bottom layer game.background = bgImage; // Store background reference for next transition currentRoom.enemies.forEach(function (enemy) { enemy.active = true; // Reset active state enemy.health = 10; // Reset health enemy.x = Math.random() * 2048; // Reset position enemy.y = Math.random() * 2732; game.addChild(enemy); // Ensure enemy is added to the game }); hero.canExitRoom = false; // Reset exit permission for the new room currentRoom.isCleared = false; // Reset room cleared status updateRoomDisplay(); // Update the room display text } // Initialize arrows array to keep track of arrows var arrows = []; // Function to check if the room is cleared function checkRoomCleared() { if (currentRoom.enemiesKilled >= currentRoom.killGoal && !currentRoom.isCleared) { if (currentRoom.number === 1) { stopRoomMusic(); console.log('Room music stopped: room1_music'); currentRoomMusic = null; // Reset currentRoomMusic to ensure it doesn't play again } console.log('Room music stopped: room' + currentRoom.number + '_music'); console.log('checkRoomCleared called after enemy killed'); // Play room cleared sound var roomClearedSound = LK.getSound('room' + currentRoom.number + '_cleared'); if (roomClearedSound) { roomClearedSound.play(); } // Removed redundant currentRoomMusic reset currentRoom.isCleared = true; console.log("Room Cleared! Entering Room " + (currentRoom.number + 1)); // Enable room transition by allowing exits hero.canExitRoom = true; // Allow hero to exit the room updateRoomDisplay(); // Update the room display text } } function transitionToNewRoom(entrySide) { // Reset hero position based on entry side 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; } // Clear current enemies and set up the new room stopRoomMusic(); currentRoomMusic = null; // Reset currentRoomMusic to ensure it doesn't play again transitionToNextRoom(); playRoomMusic(currentRoom.number); hero.canExitRoom = false; // Disable exit until next room is cleared } // Function to transition to the next room // Initialize game variables var hero = gameContainer.addChild(new Hero()); hero.x = 2048 / 2; hero.y = 2732 / 2; // Health display var healthText = new Text2('Health: ' + hero.health, { size: 70, fill: "#ffffff", fontWeight: "bold" }); healthText.x = 300; // Move further to the left healthText.y = 20; game.addChild(healthText); // Add directly to the game layer after statsBar // Initialize hero movement variables // Removed moveTarget and moveSpeed to ensure movement is joystick-controlled only // Add Joystick to the game var joystick = uiContainer.addChild(new Joystick()); hero.joystick = joystick; // Link joystick to hero for movement control // Handle joystick events // Removed game.move event handler to ensure movement is joystick-controlled only // Removed game.down event handler to ensure movement is joystick-controlled only // Removed game.up event handler to ensure movement is joystick-controlled only // Function to handle game updates game.update = function () { // Pause game logic if a popup is active if (isPopupActive) { return; } // Continuously update hero position based on joystick input 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); // Update rotation to face movement direction } } hero.update(); // Check if hero's health is zero or less if (hero.health <= 0) { hero.health = 0; // Ensure health does not go below zero console.log("Hero has died. Game Over!"); LK.showGameOver(); // Trigger game over return; // Exit update loop } // Check if hero can exit and is near an exit edge 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); } } // Update arrows for (var j = arrows.length - 1; j >= 0; j--) { arrows[j].update(); // Check if arrow hits any enemy 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) { // Assuming enemy radius is 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); console.log("Enemy defeated. Total killed: " + currentRoom.enemiesKilled); updateRoomDisplay(); checkRoomCleared(); console.log('checkRoomCleared called after enemy killed'); } if (arrows[j]) { arrows[j].destroy(); arrows.splice(j, 1); } break; } } } // Update enemies only if popup is not active if (!isPopupActive) { for (var i = 0; i < currentRoom.enemies.length; i++) { currentRoom.enemies[i].update(); } } // Check if the room is cleared after enemies are updated console.log('checkRoomCleared called'); checkRoomCleared(); }; // Function to spawn enemies function spawnEnemy() { if (currentRoom.enemiesSpawned < currentRoom.spawnLimit) {} } // Removed interval to spawn enemies to prevent continuous spawning // Set interval to fire enemy bullets // Removed interval to prevent enemies from shooting // LK.setInterval(function () { // for (var i = 0; i < enemies.length; i++) { // fireEnemyBullet(enemies[i]); // } // }, 1000); // Handle touch/click for movement // Removed tap-to-move behavior to ensure movement is joystick-controlled only // Create an invisible button at the bottom-left corner for weapon switching var switchWeaponZone = LK.getAsset('switchWeaponZone', { anchorX: 0.5, anchorY: 0.5 }); switchWeaponZone.x = 2048 - switchWeaponZone.width / 2; // Center horizontally on the right side switchWeaponZone.y = 2732 / 2; // Center vertically uiContainer.addChild(switchWeaponZone); // Add event listener for weapon switch zone game.down = function (x, y, obj) { // Disable interactions if a popup is active if (isPopupActive) { return; } // Check if the click is within the switch weapon zone 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) { // Toggle weapon between sword (1) and bow (2) hero.weaponType = hero.weaponType === 1 ? 2 : 1; console.log("Switched to weapon type:", hero.weaponType); // Show the correct weapon asset hero.swordGraphics.visible = hero.weaponType === 1; hero.bowGraphics.visible = hero.weaponType === 2; return; // Exit the function to avoid triggering an attack } }; // Add sword attack on tap/click
===================================================================
--- original.js
+++ change.js
@@ -1524,8 +1524,9 @@
console.log("Updating room display: Room " + currentRoom.number + ", Enemies Left: " + enemiesLeft); // Debug log
}
var currentRoomMusic;
function transitionToNextRoom() {
+ stopRoomMusic();
playRoomMusic(currentRoom.number);
// Clear previous background if it exists
if (game.background) {
game.removeChild(game.background);
@@ -1569,10 +1570,10 @@
if (currentRoom.enemiesKilled >= currentRoom.killGoal && !currentRoom.isCleared) {
if (currentRoom.number === 1) {
stopRoomMusic();
console.log('Room music stopped: room1_music');
+ currentRoomMusic = null; // Reset currentRoomMusic to ensure it doesn't play again
}
- currentRoomMusic = null; // Reset currentRoomMusic to ensure it doesn't play again
console.log('Room music stopped: room' + currentRoom.number + '_music');
console.log('checkRoomCleared called after enemy killed');
// Play room cleared sound
var roomClearedSound = LK.getSound('room' + currentRoom.number + '_cleared');
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