Code edit (1 edits merged)
Please save this source code
User prompt
Instead of tinting the boosted elements, just use instead of elementButton, boostedElementButton.
User prompt
Please fix the bug: 'center is not defined' in or related to this line: 'return 0x4169E1;' Line Number: 567
Code edit (11 edits merged)
Please save this source code
User prompt
weatherText please should have text inside centered horizontally
Code edit (1 edits merged)
Please save this source code
Code edit (1 edits merged)
Please save this source code
User prompt
The confirmation dialog: should be a popup with a white background and centered in the middle of the wheel
User prompt
After the user selects one element, ask if they want to select a second for a combo (for a critical success / failure) or just use that element.
User prompt
Allow the AI to use combos, but restrict frequent combos that will be critical failures. Also, clear the combo display of the AI, is not being cleared (but the user combos are cleared). Also, allow the user to only select one element and not a combo.
User prompt
Ok, remove Score and Wins and istead use Player life and AI life. Then, using a combo makes it either a critical success or a critical failure. A critical success removes twice the points from the opponents life. A critical failure removes tiwce the life from self. A critical success is a combo that is registered in the game as a combo. A critical failure is any other combo that is not registered in the game. Make the AI intelligent and not choosing very often critical combos.
User prompt
Change impact font to other one, that's horrible.
User prompt
Change the font of all the texts to something cooler from any PIXI.JS font, but keeping the black contour
User prompt
Change all the font of all the texts to Comic Sans with a black contour
User prompt
Make a special visual effect to those elements whith are boosted from the wheel, due to the current season. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
If an element is boosted due to the season, please make it bright specially. ↪💡 Consider importing and using the following plugins: @upit/tween.v1
User prompt
The season information disappears after the first spinning never to be seen again :( Please fix.
User prompt
Ok instead of background, show the asset in drought, rainy, stormy or windy in the background of the game, depending on the current season.
User prompt
Please fix the bug: 'TypeError: Cannot read properties of null (reading 'toUpperCase')' in or related to this line: 'instructionText.setText(aiElement.toUpperCase() + ' ' + actionWord + ' ' + playerElement.toUpperCase() + '!\nYOU LOSE!');' Line Number: 1294
User prompt
1. THe AI is never selecting more than 1 element. It should be able to sping a second time the wheel. 2. In the battle screen, I only see the first element of the combo(s), not the second. 3. On the bottom left, I see the text of the combo elements. What I want is the icons of thos elements. 4. On the bottom right, I need to see the combos of the AI.
User prompt
Ok, now implement this. ## **Elemental Combo Chains** Instead of just single element battles, allow players to select a sequence of 2 elements that create combo attacks. Certain element combinations could have special effects - like "Lightning + Water = Electrified Storm" that defeats additional elements or "Fire + Air = Inferno" that deals double damage. This would add a layer of strategic depth where players need to think about not just individual matchups but sequences. Please show the combos of the user in the bototm left part of the screen. For the AI - the combos will be selected by spinning 2 times the wheel in a row when it's necessary (the AI may think only 1 element and not a combo is better).
User prompt
make sure the season is always present in after wins! Sometimes is not shown!
Code edit (1 edits merged)
Please save this source code
User prompt
The seasons should be max 3 rounds.
User prompt
Current season is not shown at start. Please fix. Just start the game, calculate the season for the next rounds, and write it under Wins!
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); /**** * Classes ****/ var BattleElement = Container.expand(function (elementType, isPlayer) { var self = Container.call(this); self.elementType = elementType; self.isPlayer = isPlayer; var background = self.attachAsset('elementButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 1.5, scaleY: 1.5 }); var icon = self.attachAsset(elementType, { anchorX: 0.5, anchorY: 0.5, scaleX: 1.2, scaleY: 1.2 }); var label = new Text2(elementType.toUpperCase(), { size: 32, fill: 0xffffff }); label.anchor.set(0.5, 0.5); label.y = 220; self.addChild(label); self.playWinAnimation = function () { var effect = self.attachAsset('winEffect', { anchorX: 0.5, anchorY: 0.5, alpha: 0.7 }); tween(self, { scaleX: 1.3, scaleY: 1.3 }, { duration: 500 }); tween(effect, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: 800, onFinish: function onFinish() { self.removeChild(effect); } }); }; self.playLoseAnimation = function () { var effect = self.attachAsset('loseEffect', { anchorX: 0.5, anchorY: 0.5, alpha: 0.7 }); tween(self, { scaleX: 0.7, scaleY: 0.7, alpha: 0.5 }, { duration: 500 }); tween(effect, { scaleX: 2, scaleY: 2, alpha: 0 }, { duration: 800, onFinish: function onFinish() { self.removeChild(effect); } }); }; return self; }); var ElementButton = Container.expand(function (elementType, index) { var self = Container.call(this); self.elementType = elementType; self.index = index; self.isSelected = false; self.isDisabled = false; var button = self.attachAsset('elementButton', { anchorX: 0.5, anchorY: 0.5 }); var icon = self.attachAsset(elementType, { anchorX: 0.5, anchorY: 0.5 }); var label = new Text2(elementType.toUpperCase(), { size: 24, fill: 0xffffff }); label.anchor.set(0.5, 0.5); self.addChild(label); // Position text toward wheel center self.positionTextTowardCenter = function (centerX, centerY) { var angle = Math.atan2(self.y - centerY, self.x - centerX); var offsetX = Math.cos(angle) * textOffsetTowardCenter; var offsetY = Math.sin(angle) * textOffsetTowardCenter; label.x = -offsetX; label.y = -offsetY; }; self.setSelected = function (selected) { self.isSelected = selected; if (selected) { button.tint = 0xffd700; tween(self, { scaleX: 1.2, scaleY: 1.2 }, { duration: 200 }); } else { button.tint = 0xffffff; tween(self, { scaleX: 1.0, scaleY: 1.0 }, { duration: 200 }); } }; self.setDisabled = function (disabled) { self.isDisabled = disabled; if (disabled) { button.alpha = 0.5; icon.alpha = 0.5; label.alpha = 0.5; } else { button.alpha = 1.0; icon.alpha = 1.0; label.alpha = 1.0; } }; self.down = function (x, y, obj) { if (gameState === 'selection' && !self.isDisabled) { LK.getSound('select').play(); selectElement(self.elementType); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0xffffff }); /**** * Game Code ****/ // Add background image - will be updated based on weather var backgroundImage = null; // Function to update background based on current weather function updateBackgroundForWeather() { // Remove existing background if it exists if (backgroundImage) { backgroundImage.destroy(); backgroundImage = null; } // Determine which background asset to use var backgroundAsset = 'background'; // default if (currentWeather === 'drought') { backgroundAsset = 'drought'; } else if (currentWeather === 'rainy') { backgroundAsset = 'rainy'; } else if (currentWeather === 'storm') { backgroundAsset = 'stormy'; } else if (currentWeather === 'windy') { backgroundAsset = 'windy'; } // Create new background with weather-appropriate asset backgroundImage = game.attachAsset(backgroundAsset, { anchorX: 0.5, anchorY: 0.5, scaleX: 1.137, scaleY: 1.013 }); backgroundImage.x = 1024; backgroundImage.y = 1366; // Move background to back game.setChildIndex(backgroundImage, 0); } // Initialize with default background updateBackgroundForWeather(); // Game elements and their relationships var elements = ['rock', 'paper', 'scissors', 'water', 'fire', 'air', 'lightning', 'tree', 'gun', 'sponge', 'smoke', 'gas', 'metal', 'ice', 'sand', 'oil']; // Element defeat relationships (each element defeats 8 others) var defeats = { // Rock: Heavy and solid, crushes fragile things, breaks weapons, absorbs energy 'rock': ['scissors', 'sponge', 'gas', 'metal', 'ice', 'gun', 'tree', 'sand'], // Paper: Wraps and covers, conducts electricity, absorbs liquids, blocks air flow 'paper': ['rock', 'metal', 'water', 'gas', 'sand', 'ice', 'air', 'smoke'], // Scissors: Sharp cutting tool, cuts through soft materials and gases 'scissors': ['paper', 'sponge', 'air', 'tree', 'gas', 'oil', 'ice', 'smoke'], // Water: Extinguishes fire, erodes materials, conducts electricity, flows through spaces 'water': ['fire', 'rock', 'scissors', 'gas', 'oil', 'sand', 'tree', 'metal'], // Fire: Burns combustible materials, melts solids, heats and expands gases 'fire': ['paper', 'scissors', 'sponge', 'ice', 'tree', 'sand', 'oil', 'smoke'], // Air: Feeds fire, disperses gases, creates pressure, moves objects 'air': ['fire', 'gas', 'smoke', 'metal', 'rock', 'oil', 'tree', 'gun'], // Lightning: Electrical discharge, conducts through metals and water, ionizes gases 'lightning': ['water', 'metal', 'gun', 'air', 'paper', 'sponge', 'smoke', 'sand'], // Tree: Absorbs water and nutrients, grows through materials, provides shelter 'tree': ['water', 'paper', 'sponge', 'smoke', 'gun', 'sand', 'ice', 'gas'], // Gun: Projectile weapon, breaks through barriers, fires through gases 'gun': ['scissors', 'rock', 'tree', 'metal', 'gas', 'ice', 'oil', 'paper'], // Sponge: Absorbs liquids and gases, flexible material, filters particles 'sponge': ['water', 'metal', 'air', 'paper', 'gas', 'rock', 'sand', 'smoke'], // Smoke: Obscures vision, suffocates, corrodes metals, covers surfaces 'smoke': ['ice', 'gun', 'rock', 'paper', 'air', 'metal', 'water', 'oil'], // Gas: Expands and fills spaces, displaces air, creates pressure, volatile 'gas': ['paper', 'ice', 'gun', 'smoke', 'air', 'scissors', 'sponge', 'sand'], // Metal: Strong and durable, conducts electricity, resists cutting, heavy 'metal': ['scissors', 'tree', 'ice', 'fire', 'gun', 'oil', 'rock', 'sand'], // Ice: Freezes liquids, slippery surface, preserves, expands when frozen 'ice': ['air', 'water', 'paper', 'sponge', 'fire', 'smoke', 'gun', 'lightning'], // Sand: Abrasive particles, absorbs liquids, extinguishes fire, buries objects 'sand': ['scissors', 'ice', 'gun', 'fire', 'air', 'paper', 'rock', 'lightning'], // Oil: Slippery liquid, flammable, coats surfaces, lubricates mechanisms 'oil': ['rock', 'scissors', 'gun', 'metal', 'water', 'gas', 'lightning', 'fire'] }; // Action keywords for how elements defeat others var actionKeywords = { 'rock': { 'scissors': 'crushes', 'sponge': 'crushes', 'gas': 'disperses', 'metal': 'breaks', 'ice': 'shatters', 'gun': 'blocks', 'tree': 'crushes', 'sand': 'compacts' }, 'paper': { 'rock': 'wraps', 'metal': 'covers', 'water': 'absorbs', 'gas': 'captures', 'sand': 'covers', 'ice': 'insulates', 'air': 'blocks', 'smoke': 'filters' }, 'scissors': { 'paper': 'cuts', 'sponge': 'cuts', 'air': 'cuts', 'tree': 'cuts', 'gas': 'cuts', 'oil': 'cuts', 'ice': 'cuts', 'smoke': 'cuts' }, 'water': { 'fire': 'extinguishes', 'rock': 'erodes', 'scissors': 'rusts', 'gas': 'dissolves', 'oil': 'displaces', 'sand': 'washes', 'tree': 'nourishes', 'metal': 'rusts' }, 'fire': { 'paper': 'burns', 'scissors': 'melts', 'sponge': 'burns', 'ice': 'melts', 'tree': 'burns', 'sand': 'heats', 'oil': 'ignites', 'smoke': 'burns' }, 'air': { 'fire': 'feeds', 'gas': 'disperses', 'smoke': 'clears', 'metal': 'oxidizes', 'rock': 'erodes', 'oil': 'evaporates', 'tree': 'sways', 'gun': 'deflects' }, 'lightning': { 'water': 'electrifies', 'metal': 'conducts', 'gun': 'shorts', 'air': 'ionizes', 'paper': 'ignites', 'sponge': 'shocks', 'smoke': 'disperses', 'sand': 'vitrifies' }, 'tree': { 'water': 'absorbs', 'paper': 'grows over', 'sponge': 'outgrows', 'smoke': 'filters', 'gun': 'blocks', 'sand': 'roots in', 'ice': 'breaks', 'gas': 'absorbs' }, 'gun': { 'scissors': 'shoots', 'rock': 'shatters', 'tree': 'shoots through', 'metal': 'pierces', 'gas': 'ignites', 'ice': 'shatters', 'oil': 'ignites', 'paper': 'pierces' }, 'sponge': { 'water': 'absorbs', 'metal': 'corrodes', 'air': 'filters', 'paper': 'soaks', 'gas': 'absorbs', 'rock': 'erodes', 'sand': 'absorbs', 'smoke': 'filters' }, 'smoke': { 'ice': 'melts', 'gun': 'jams', 'rock': 'corrodes', 'paper': 'stains', 'air': 'pollutes', 'metal': 'corrodes', 'water': 'pollutes', 'oil': 'mixes with' }, 'gas': { 'paper': 'dissolves', 'ice': 'sublimates', 'gun': 'corrodes', 'smoke': 'displaces', 'air': 'displaces', 'scissors': 'corrodes', 'sponge': 'fills', 'sand': 'displaces' }, 'metal': { 'scissors': 'dulls', 'tree': 'cuts', 'ice': 'breaks', 'fire': 'conducts', 'gun': 'reinforces', 'oil': 'repels', 'rock': 'crushes', 'sand': 'compacts' }, 'ice': { 'air': 'freezes', 'water': 'freezes', 'paper': 'freezes', 'sponge': 'freezes', 'fire': 'extinguishes', 'smoke': 'condenses', 'gun': 'jams', 'lightning': 'grounds' }, 'sand': { 'scissors': 'dulls', 'ice': 'melts', 'gun': 'jams', 'fire': 'smothers', 'air': 'fills', 'paper': 'abrades', 'rock': 'erodes', 'lightning': 'grounds' }, 'oil': { 'rock': 'lubricates', 'scissors': 'lubricates', 'gun': 'lubricates', 'metal': 'lubricates', 'water': 'floats on', 'gas': 'dissolves', 'lightning': 'insulates', 'fire': 'feeds' } }; // Game state variables var gameState = 'selection'; // 'selection', 'spinning', 'battle', 'result' var elementButtons = []; var playerElement = null; var aiElement = null; var playerBattleElement = null; var aiBattleElement = null; var vsText = null; var consecutiveWins = 0; var difficultyLevel = 1; var battleTimer = 0; var hoveredButton = null; // Track which button is currently hovered var victoryArrows = []; // Array to store victory arrows var usedPlayerElements = []; // Track elements used by player var usedAIElements = []; // Track elements used by AI var wheelContainer = null; // Container for wheel elements var isWheelSpinning = false; // Track if wheel is currently spinning var wheelRotation = 0; // Current wheel rotation // Combo system variables var playerCombo = []; // Array to store player's selected combo elements var aiCombo = []; // Array to store AI's combo elements var isComboMode = false; // Track if player is building a combo var comboDisplay = null; // UI element to show current combo var aiComboSpins = 0; // Track AI combo wheel spins // Weather system variables var currentWeather = null; var weatherRoundsLeft = 0; var weatherTypes = ['rainy', 'drought', 'windy', 'storm']; var weatherEffects = { 'rainy': ['water', 'ice'], // Water-based elements get bonus 'drought': ['fire', 'sand'], // Fire-based elements get bonus 'windy': ['air', 'gas'], // Air-based elements get bonus 'storm': ['lightning', 'metal'] // Electric/conductive elements get bonus }; // Combo system definitions var comboEffects = { // Special combo combinations with enhanced effects 'lightning+water': { name: 'Electrified Storm', defeatsExtra: ['metal', 'gun', 'scissors'], // Additional defeats beyond normal rules multiplier: 1.5 }, 'fire+air': { name: 'Inferno', defeatsExtra: ['tree', 'paper', 'oil'], multiplier: 2.0 }, 'water+ice': { name: 'Frozen Flood', defeatsExtra: ['fire', 'rock', 'sand'], multiplier: 1.5 }, 'rock+metal': { name: 'Crushing Force', defeatsExtra: ['gun', 'scissors', 'lightning'], multiplier: 1.8 }, 'gas+fire': { name: 'Explosive Blast', defeatsExtra: ['rock', 'metal', 'ice'], multiplier: 2.0 }, 'lightning+metal': { name: 'Electric Conductor', defeatsExtra: ['water', 'ice', 'gun'], multiplier: 1.7 } }; // Function to get the element at the top position function getTopElement() { // At the start, rock (index 0) is at the top (-PI/2) // Calculate angle per element var anglePerElement = Math.PI * 2 / elements.length; // Normalize rotation to 0-2PI range var normalizedRotation = (wheelContainer.rotation % (Math.PI * 2) + Math.PI * 2) % (Math.PI * 2); // Calculate how many element positions we've rotated from the starting position var elementSteps = Math.round(normalizedRotation / anglePerElement); // Find which element is now at the ROCK position (top position) // Since wheel rotates clockwise, we subtract the steps from the starting rock index var topElementIndex = (0 - elementSteps + elements.length * 10) % elements.length; var topElement = elements[topElementIndex]; return topElement; } // Function to start new weather function startNewWeather() { var newWeather = weatherTypes[Math.floor(Math.random() * weatherTypes.length)]; currentWeather = newWeather; weatherRoundsLeft = 1 + Math.floor(Math.random() * 3); // 3-5 rounds updateWeatherDisplay(); } // Function to update weather display function updateWeatherDisplay() { if (currentWeather && weatherRoundsLeft > 0) { var weatherName = currentWeather.charAt(0).toUpperCase() + currentWeather.slice(1); var effectElements = weatherEffects[currentWeather].join(', ').toUpperCase(); weatherText.setText(weatherName + ' Season (' + weatherRoundsLeft + ' rounds)\n' + effectElements + ' elements boosted'); weatherText.tint = getWeatherColor(currentWeather); } else { weatherText.setText(''); } // Update background to match current weather updateBackgroundForWeather(); } // Function to get weather color function getWeatherColor(weather) { switch (weather) { case 'rainy': return 0x4169E1; // Royal blue case 'drought': return 0xFF4500; // Orange red case 'windy': return 0x87CEEB; // Sky blue case 'storm': return 0x9370DB; // Medium purple default: return 0xFFFFFF; } } // Function to check if element gets weather bonus function hasWeatherBonus(element) { if (!currentWeather || weatherRoundsLeft <= 0) { return false; } return weatherEffects[currentWeather].indexOf(element) !== -1; } // Combo helper functions function getComboKey(combo) { if (combo.length !== 2) return null; var sorted = combo.slice().sort(); return sorted[0] + '+' + sorted[1]; } function getComboEffect(combo) { var key = getComboKey(combo); return comboEffects[key] || null; } function updateComboDisplay() { // Clear existing combo elements for (var i = comboDisplay.children.length - 1; i >= 0; i--) { comboDisplay.removeChild(comboDisplay.children[i]); } comboDisplay.setText(''); if (playerCombo.length === 0) { // No combo } else if (playerCombo.length === 1) { comboDisplay.setText('Your Combo:'); var icon1 = LK.getAsset(playerCombo[0], { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3 }); icon1.x = 80; icon1.y = -50; comboDisplay.addChild(icon1); var plusText = new Text2(' + ?', { size: 20, fill: 0xFFFFFF }); plusText.x = 120; plusText.y = -50; plusText.anchor.set(0, 0.5); comboDisplay.addChild(plusText); } else if (playerCombo.length === 2) { var effect = getComboEffect(playerCombo); if (effect) { comboDisplay.setText('Your Combo:\n' + effect.name); comboDisplay.tint = 0x00FF00; // Green for special combo } else { comboDisplay.setText('Your Combo:'); comboDisplay.tint = 0xFFD700; // Gold for normal combo } var icon1 = LK.getAsset(playerCombo[0], { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3 }); icon1.x = 60; icon1.y = effect ? -80 : -50; comboDisplay.addChild(icon1); var plusText = new Text2(' + ', { size: 20, fill: 0xFFFFFF }); plusText.x = 90; plusText.y = effect ? -80 : -50; plusText.anchor.set(0.5, 0.5); comboDisplay.addChild(plusText); var icon2 = LK.getAsset(playerCombo[1], { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3 }); icon2.x = 120; icon2.y = effect ? -80 : -50; comboDisplay.addChild(icon2); } } function updateAIComboDisplay() { // Clear existing AI combo elements for (var i = aiComboDisplay.children.length - 1; i >= 0; i--) { aiComboDisplay.removeChild(aiComboDisplay.children[i]); } aiComboDisplay.setText(''); if (aiCombo.length === 0 && !aiElement) { // No combo or element yet } else if (aiCombo.length === 1) { aiComboDisplay.setText('AI Combo:'); var icon1 = LK.getAsset(aiCombo[0], { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3 }); icon1.x = -80; icon1.y = -50; aiComboDisplay.addChild(icon1); var plusText = new Text2(' + ?', { size: 20, fill: 0xFFFFFF }); plusText.x = -120; plusText.y = -50; plusText.anchor.set(1, 0.5); aiComboDisplay.addChild(plusText); } else if (aiCombo.length === 2) { var effect = getComboEffect(aiCombo); if (effect) { aiComboDisplay.setText('AI Combo:\n' + effect.name); aiComboDisplay.tint = 0xFF0000; // Red for AI special combo } else { aiComboDisplay.setText('AI Combo:'); aiComboDisplay.tint = 0xFF6B35; // Orange for AI normal combo } var icon1 = LK.getAsset(aiCombo[0], { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3 }); icon1.x = -120; icon1.y = effect ? -80 : -50; aiComboDisplay.addChild(icon1); var plusText = new Text2(' + ', { size: 20, fill: 0xFFFFFF }); plusText.x = -90; plusText.y = effect ? -80 : -50; plusText.anchor.set(0.5, 0.5); aiComboDisplay.addChild(plusText); var icon2 = LK.getAsset(aiCombo[1], { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3 }); icon2.x = -60; icon2.y = effect ? -80 : -50; aiComboDisplay.addChild(icon2); } else if (aiElement) { aiComboDisplay.setText('AI Element:'); var icon = LK.getAsset(aiElement, { anchorX: 0.5, anchorY: 0.5, scaleX: 0.3, scaleY: 0.3 }); icon.x = -80; icon.y = -50; aiComboDisplay.addChild(icon); } } // Text positioning parameter - distance to move text toward wheel center var textOffsetTowardCenter = 160; // Adjustable parameter for text positioning // UI elements var titleText = new Text2('ULTIMATE ELEMENTS SHOWDOWN', { size: 48, fill: 0xFFFFFF }); titleText.anchor.set(0.5, 0); LK.gui.top.addChild(titleText); titleText.y = 50; var instructionText = new Text2('Choose your element', { size: 32, fill: 0xCCCCCC }); instructionText.anchor.set(0.5, 0.5); game.addChild(instructionText); instructionText.x = 1024; instructionText.y = 400; var scoreText = new Text2('Score: 0', { size: 36, fill: 0xFFFFFF }); scoreText.anchor.set(1, 0); LK.gui.topRight.addChild(scoreText); scoreText.x = -20; scoreText.y = 20; var winsText = new Text2('Wins: 0', { size: 32, fill: 0xFFFFFF }); winsText.anchor.set(1, 0); LK.gui.topRight.addChild(winsText); winsText.x = -20; winsText.y = 70; var weatherText = new Text2('', { size: 28, fill: 0x87CEEB }); weatherText.anchor.set(1, 0); LK.gui.topRight.addChild(weatherText); weatherText.x = -20; weatherText.y = 120; // Position under Wins text // Combo display in bottom left comboDisplay = new Text2('', { size: 24, fill: 0xFFD700 }); comboDisplay.anchor.set(0, 1); LK.gui.bottomLeft.addChild(comboDisplay); comboDisplay.x = 20; comboDisplay.y = -20; // AI combo display in bottom right var aiComboDisplay = new Text2('', { size: 24, fill: 0xFF6B35 }); aiComboDisplay.anchor.set(1, 1); LK.gui.bottomRight.addChild(aiComboDisplay); aiComboDisplay.x = -20; aiComboDisplay.y = -20; // Create element selection grid function createElementButtons() { var centerX = 1024; var centerY = 1400; var radius = 800; // Create container for victory arrows (behind wheel elements) var arrowsContainer = new Container(); arrowsContainer.x = centerX; arrowsContainer.y = centerY; game.addChild(arrowsContainer); // Create wheel container for spinning animation wheelContainer = new Container(); wheelContainer.x = centerX; wheelContainer.y = centerY; game.addChild(wheelContainer); for (var i = 0; i < elements.length; i++) { var angle = i / elements.length * Math.PI * 2 - Math.PI / 2; var x = Math.cos(angle) * radius; var y = Math.sin(angle) * radius; var button = wheelContainer.addChild(new ElementButton(elements[i], i)); button.x = x; button.y = y; button.positionTextTowardCenter(0, 0); // Use wheel center as reference // Store original label position var label = button.children[button.children.length - 1]; if (label && label.setText) { button.originalLabelX = label.x; button.originalLabelY = label.y; } elementButtons.push(button); } } // Select element function function selectElement(elementType) { if (gameState !== 'selection') { return; } // Check if element has already been used by player if (usedPlayerElements.indexOf(elementType) !== -1) { return; // Don't allow selection of already used elements } // Handle combo selection if (playerCombo.length === 0) { // First element selection playerCombo.push(elementType); updateComboDisplay(); instructionText.setText('Choose second element for combo (or same element to use single)'); // Update button states to show first selection for (var i = 0; i < elementButtons.length; i++) { elementButtons[i].setSelected(elementButtons[i].elementType === elementType); } } else if (playerCombo.length === 1) { // Second element selection if (elementType === playerCombo[0]) { // Player chose same element twice - use single element playerElement = elementType; playerCombo = [elementType]; // Keep as single element combo } else { // Player chose different element - create combo playerCombo.push(elementType); playerElement = null; // Use combo instead of single element } updateComboDisplay(); // Reset aiElement and combo when starting new selection aiElement = null; aiCombo = []; aiComboSpins = 0; // Update button states for (var i = 0; i < elementButtons.length; i++) { elementButtons[i].setSelected(false); } // Start wheel spinning animation startWheelSpin(); } } // Start wheel spinning animation function startWheelSpin() { gameState = 'spinning'; isWheelSpinning = true; // Determine if AI should use combo var shouldUseCombo = Math.random() < 0.4; // 40% chance for AI to use combo if (shouldUseCombo && aiCombo.length === 0) { instructionText.setText('AI is choosing combo...'); aiComboSpins = 1; // AI will spin twice for combo } else if (aiComboSpins === 1) { instructionText.setText('AI choosing second element...'); } else { instructionText.setText('AI is choosing...'); } // Add triangle pointing down behind the "AI is choosing" text var triangle = LK.getAsset('marker', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); triangle.tint = 0xFFFFFF; triangle.rotation = Math.PI / 2; // Rotate 90 degrees to point down triangle.x = 1024; // Center horizontally triangle.y = 475; // Position below the instruction text triangle.alpha = 0; game.addChild(triangle); // Animate triangle in tween(triangle, { alpha: 1 }, { duration: 300 }); // Store triangle reference for cleanup instructionText.triangle = triangle; // Hide victory arrows during spinning for (var i = 0; i < victoryArrows.length; i++) { tween(victoryArrows[i], { alpha: 0 }, { duration: 300 }); } // Hide element labels during spinning for (var i = 0; i < elementButtons.length; i++) { var button = elementButtons[i]; var label = button.children[button.children.length - 1]; // Label is the last child if (label && label.setText) { label.alpha = 0; // Immediately hide labels } } // Get available elements for AI (not disabled) var availableElements = []; for (var i = 0; i < elementButtons.length; i++) { if (!elementButtons[i].isDisabled) { availableElements.push(elementButtons[i].elementType); } } // Calculate how many spins we need to ensure we land on an available element var spinAmount = 3 + Math.random() * 3; // 3-6 full rotations var baseRotation = spinAmount * Math.PI * 2; // Choose a random available element to land on var targetElement = availableElements[Math.floor(Math.random() * availableElements.length)]; var targetIndex = elements.indexOf(targetElement); // Calculate angle per element var anglePerElement = Math.PI * 2 / elements.length; // Calculate the rotation needed to put target element at top // Rock (index 0) starts at -PI/2, so target element should be at -PI/2 var targetAngleFromStart = targetIndex * anglePerElement; var rotationToTarget = -targetAngleFromStart; // Negative because wheel rotates clockwise // Final rotation combines base spins with precise positioning var finalRotation = baseRotation + rotationToTarget; // Ensure we stop at exact element positions by rounding to nearest element angle var exactElementPosition = Math.round(finalRotation / anglePerElement) * anglePerElement; finalRotation = exactElementPosition; // Reset wheel rotation for animation wheelContainer.rotation = 0; // Function to check if wheel stopped on disabled element and continue spinning function checkAndContinueSpinning() { // Get the current top element var currentTopElement = getTopElement(); // Find the button for this element var topButton = null; for (var i = 0; i < elementButtons.length; i++) { if (elementButtons[i].elementType === currentTopElement) { topButton = elementButtons[i]; break; } } // If the top element is disabled, continue spinning to next available element if (topButton && topButton.isDisabled) { // Find the next non-disabled element var nextAvailableIndex = -1; var currentIndex = elements.indexOf(currentTopElement); for (var step = 1; step < elements.length; step++) { var checkIndex = (currentIndex + step) % elements.length; var checkElement = elements[checkIndex]; var checkButton = null; for (var i = 0; i < elementButtons.length; i++) { if (elementButtons[i].elementType === checkElement) { checkButton = elementButtons[i]; break; } } if (checkButton && !checkButton.isDisabled) { nextAvailableIndex = checkIndex; break; } } if (nextAvailableIndex !== -1) { // Calculate additional rotation needed to reach next available element var additionalSteps = (nextAvailableIndex - currentIndex + elements.length) % elements.length; var additionalRotation = additionalSteps * anglePerElement; // Continue spinning to the next available element tween(wheelContainer, { rotation: wheelContainer.rotation - additionalRotation }, { duration: 1000, easing: tween.easeOut, onFinish: function onFinish() { // Check again in case we need to continue further checkAndContinueSpinning(); } }); return; } } // If we reach here, the wheel has stopped on a valid element if (aiComboSpins === 1) { // AI is building a combo - this is first element aiCombo.push(currentTopElement); aiComboSpins = 2; updateAIComboDisplay(); // Start spinning again for second element LK.setTimeout(function () { startWheelSpin(); }, 1000); } else if (aiComboSpins === 2) { // AI is completing combo - this is second element aiCombo.push(currentTopElement); aiComboSpins = 0; isWheelSpinning = false; updateAIComboDisplay(); // Start battle after wheel stops LK.setTimeout(function () { startBattle(); }, 2000); // Wait 2 seconds before VS screen } else { // AI using single element isWheelSpinning = false; aiElement = currentTopElement; updateAIComboDisplay(); // Start battle after wheel stops LK.setTimeout(function () { startBattle(); }, 2000); // Wait 2 seconds before VS screen } } // Animate wheel spinning tween(wheelContainer, { rotation: finalRotation }, { duration: 2000 + Math.random() * 1000, // 2-3 seconds easing: tween.easeOut, onFinish: function onFinish() { // Check if we need to continue spinning checkAndContinueSpinning(); } }); } // AI element selection function getAIElement() { // Get available elements (not used by AI yet) var availableElements = []; for (var i = 0; i < elements.length; i++) { if (usedAIElements.indexOf(elements[i]) === -1) { availableElements.push(elements[i]); } } // If no available elements, use all elements (shouldn't happen in normal gameplay) if (availableElements.length === 0) { availableElements = elements.slice(); } // Basic AI that becomes more strategic with difficulty if (difficultyLevel === 1) { // Random selection from available elements return availableElements[Math.floor(Math.random() * availableElements.length)]; } else if (difficultyLevel === 2) { // 30% chance to counter player's last choice if (Math.random() < 0.3 && playerElement) { var counters = []; for (var i = 0; i < availableElements.length; i++) { if (defeats[availableElements[i]] && defeats[availableElements[i]].indexOf(playerElement) !== -1) { counters.push(availableElements[i]); } } if (counters.length > 0) { return counters[Math.floor(Math.random() * counters.length)]; } } return availableElements[Math.floor(Math.random() * availableElements.length)]; } else { // 50% chance to counter player's choice if (Math.random() < 0.5 && playerElement) { var counters = []; for (var i = 0; i < availableElements.length; i++) { if (defeats[availableElements[i]] && defeats[availableElements[i]].indexOf(playerElement) !== -1) { counters.push(availableElements[i]); } } if (counters.length > 0) { return counters[Math.floor(Math.random() * counters.length)]; } } return availableElements[Math.floor(Math.random() * availableElements.length)]; } } // Start battle phase function startBattle() { gameState = 'battle'; // aiElement is already set by wheel spin, only get it if not set if (!aiElement && aiCombo.length === 0) { aiElement = getAIElement(); } // Track used elements if (playerElement && usedPlayerElements.indexOf(playerElement) === -1) { usedPlayerElements.push(playerElement); } if (playerCombo.length > 0) { for (var i = 0; i < playerCombo.length; i++) { if (usedPlayerElements.indexOf(playerCombo[i]) === -1) { usedPlayerElements.push(playerCombo[i]); } } } if (aiElement && usedAIElements.indexOf(aiElement) === -1) { usedAIElements.push(aiElement); } if (aiCombo.length > 0) { for (var i = 0; i < aiCombo.length; i++) { if (usedAIElements.indexOf(aiCombo[i]) === -1) { usedAIElements.push(aiCombo[i]); } } } // Reset hover state hoveredButton = null; // Hide victory arrows during battle for (var i = 0; i < victoryArrows.length; i++) { tween(victoryArrows[i], { alpha: 0 }, { duration: 300 }); } // Hide triangle if it exists if (instructionText.triangle) { tween(instructionText.triangle, { alpha: 0 }, { duration: 300, onFinish: function onFinish() { instructionText.triangle.destroy(); instructionText.triangle = null; } }); } // Hide selection elements and disable them for (var i = 0; i < elementButtons.length; i++) { elementButtons[i].setDisabled(true); tween(elementButtons[i], { alpha: 0 }, { duration: 300 }); } instructionText.setText('BATTLE!'); // Create battle elements var playerDisplayElement = playerElement || playerCombo[0] || 'unknown'; var aiDisplayElement = aiElement || aiCombo[0] || 'unknown'; playerBattleElement = game.addChild(new BattleElement(playerDisplayElement, true)); playerBattleElement.x = 400; playerBattleElement.y = 1100; playerBattleElement.alpha = 0; // Add second element icon for player combo if (playerCombo.length === 2) { var playerSecondIcon = LK.getAsset(playerCombo[1], { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6 }); playerSecondIcon.x = 80; playerSecondIcon.y = -100; playerBattleElement.addChild(playerSecondIcon); } aiBattleElement = game.addChild(new BattleElement(aiDisplayElement, false)); aiBattleElement.x = 1648; aiBattleElement.y = 1100; aiBattleElement.alpha = 0; // Add second element icon for AI combo if (aiCombo.length === 2) { var aiSecondIcon = LK.getAsset(aiCombo[1], { anchorX: 0.5, anchorY: 0.5, scaleX: 0.6, scaleY: 0.6 }); aiSecondIcon.x = -80; aiSecondIcon.y = -100; aiBattleElement.addChild(aiSecondIcon); } // Animate battle elements in tween(playerBattleElement, { alpha: 1, x: 512 }, { duration: 500 }); tween(aiBattleElement, { alpha: 1, x: 1536 }, { duration: 500 }); // Add VS text vsText = new Text2('VS', { size: 72, fill: 0xFF6B35 }); vsText.anchor.set(0.5, 0.5); vsText.x = 1024; vsText.y = 1100; vsText.alpha = 0; game.addChild(vsText); tween(vsText, { alpha: 1, scaleX: 1.5, scaleY: 1.5 }, { duration: 300, onFinish: function onFinish() { LK.getSound('battle').play(); // Start battle timer battleTimer = 0; } }); } // Get action keyword for how one element defeats another function getActionKeyword(winner, loser) { if (actionKeywords[winner] && actionKeywords[winner][loser]) { return actionKeywords[winner][loser]; } return 'defeats'; } // Check battle result function checkBattleResult() { // Determine what elements are actually battling var playerBattleElements = playerElement ? [playerElement] : playerCombo; var aiBattleElements = aiElement ? [aiElement] : aiCombo; // Check for combo effects var playerComboEffect = playerCombo.length === 2 ? getComboEffect(playerCombo) : null; var aiComboEffect = aiCombo.length === 2 ? getComboEffect(aiCombo) : null; // Calculate wins using combo logic var playerWins = false; var aiWins = false; // Player vs AI battle logic for (var i = 0; i < playerBattleElements.length && !playerWins; i++) { for (var j = 0; j < aiBattleElements.length && !playerWins; j++) { if (defeats[playerBattleElements[i]] && defeats[playerBattleElements[i]].indexOf(aiBattleElements[j]) !== -1) { playerWins = true; } // Check combo extra defeats if (playerComboEffect && playerComboEffect.defeatsExtra.indexOf(aiBattleElements[j]) !== -1) { playerWins = true; } } } for (var i = 0; i < aiBattleElements.length && !aiWins; i++) { for (var j = 0; j < playerBattleElements.length && !aiWins; j++) { if (defeats[aiBattleElements[i]] && defeats[aiBattleElements[i]].indexOf(playerBattleElements[j]) !== -1) { aiWins = true; } // Check combo extra defeats if (aiComboEffect && aiComboEffect.defeatsExtra.indexOf(playerBattleElements[j]) !== -1) { aiWins = true; } } } // Apply weather effects var playerHasBonus = false; var aiHasBonus = false; for (var i = 0; i < playerBattleElements.length; i++) { if (hasWeatherBonus(playerBattleElements[i])) { playerHasBonus = true; break; } } for (var i = 0; i < aiBattleElements.length; i++) { if (hasWeatherBonus(aiBattleElements[i])) { aiHasBonus = true; break; } } // Weather bonus can override normal defeat relationships if (playerHasBonus && !aiHasBonus) { // Player gets weather advantage if (!playerWins && !aiWins) { // In a tie, weather bonus wins return 'player'; } // If AI would normally win, weather bonus creates a tie instead if (aiWins && !playerWins) { return 'tie'; } } else if (aiHasBonus && !playerHasBonus) { // AI gets weather advantage if (!playerWins && !aiWins) { // In a tie, weather bonus wins return 'ai'; } // If player would normally win, weather bonus creates a tie instead if (playerWins && !aiWins) { return 'tie'; } } // Normal battle logic if no weather advantage or both have advantage if (playerWins) { return 'player'; } else if (aiWins) { return 'ai'; } else { return 'tie'; } } // Show battle result function showBattleResult() { gameState = 'result'; var result = checkBattleResult(); if (result === 'player') { LK.getSound('win').play(); playerBattleElement.playWinAnimation(); aiBattleElement.playLoseAnimation(); consecutiveWins++; var basePoints = 10 * difficultyLevel * consecutiveWins; // Apply combo multiplier var playerComboEffect = playerCombo.length === 2 ? getComboEffect(playerCombo) : null; var multiplier = playerComboEffect ? playerComboEffect.multiplier : 1.0; var points = Math.floor(basePoints * multiplier); LK.setScore(LK.getScore() + points); // Create result text var playerDesc = playerElement ? playerElement.toUpperCase() : playerComboEffect ? playerComboEffect.name : playerCombo.join(' + ').toUpperCase(); var aiDesc = aiElement ? aiElement.toUpperCase() : aiCombo.length === 2 ? aiCombo.join(' + ').toUpperCase() : 'AI COMBO'; var actionWord = 'defeats'; if (playerElement && aiElement) { actionWord = getActionKeyword(playerElement, aiElement); } var resultText = playerDesc + ' ' + actionWord + ' ' + aiDesc + '!\nYOU WIN! +' + points + ' points'; if (multiplier > 1.0) { resultText += '\nCOMBO BONUS x' + multiplier.toFixed(1) + '!'; } instructionText.setText(resultText); instructionText.tint = 0x00ff00; // Make text 3 times bigger for result display instructionText.size = 180; // Increase difficulty every 3 wins if (consecutiveWins % 3 === 0 && difficultyLevel < 3) { difficultyLevel++; } } else if (result === 'ai') { LK.getSound('lose').play(); playerBattleElement.playLoseAnimation(); aiBattleElement.playWinAnimation(); consecutiveWins = 0; var aiDesc = aiElement ? aiElement.toUpperCase() : aiCombo.length === 2 ? aiCombo.join(' + ').toUpperCase() : 'AI'; var playerDesc = playerElement ? playerElement.toUpperCase() : playerCombo.length === 2 ? playerCombo.join(' + ').toUpperCase() : 'PLAYER'; var actionWord = 'defeats'; if (aiElement && playerElement) { actionWord = getActionKeyword(aiElement, playerElement); } instructionText.setText(aiDesc + ' ' + actionWord + ' ' + playerDesc + '!\nYOU LOSE!'); instructionText.tint = 0xff0000; // Make text 3 times bigger for result display instructionText.size = 180; } else { instructionText.setText('TIE!'); instructionText.tint = 0xffff00; // Make text 3 times bigger for result display instructionText.size = 180; } // Update UI scoreText.setText('Score: ' + LK.getScore()); winsText.setText('Wins: ' + consecutiveWins); // Update weather system if (weatherRoundsLeft > 0) { weatherRoundsLeft--; updateWeatherDisplay(); if (weatherRoundsLeft === 0) { currentWeather = null; updateWeatherDisplay(); // Update display when weather ends } } else { // 30% chance to start new weather when no weather is active if (Math.random() < 0.3) { startNewWeather(); } } // Return to selection after delay LK.setTimeout(function () { resetForNextRound(); }, 2000); } // Create victory arrow function function createVictoryArrow(losingElement, winningElement) { console.log("createVictoryArrow called with:", losingElement, "->", winningElement); // Find element indices var losingIndex = elements.indexOf(losingElement); var winningIndex = elements.indexOf(winningElement); console.log("Element indices:", { losingIndex: losingIndex, winningIndex: winningIndex }); if (losingIndex === -1 || winningIndex === -1) { console.log("ERROR: One or both elements not found in elements array!"); return; } // Calculate initial static positions (same as in createElementButtons) var centerX = 1024; var centerY = 1400; var radius = 800; // Calculate losing element position var losingAngle = losingIndex / elements.length * Math.PI * 2 - Math.PI / 2; var losingX = centerX + Math.cos(losingAngle) * radius; var losingY = centerY + Math.sin(losingAngle) * radius; // Calculate winning element position var winningAngle = winningIndex / elements.length * Math.PI * 2 - Math.PI / 2; var winningX = centerX + Math.cos(winningAngle) * radius; var winningY = centerY + Math.sin(winningAngle) * radius; console.log("Static positions:", { losing: { x: losingX, y: losingY }, winning: { x: winningX, y: winningY }, center: { x: centerX, y: centerY } }); // Create bezier curve points using static positions // Adjust for arrows container offset var startX = losingX - centerX; var startY = losingY - centerY; var endX = winningX - centerX; var endY = winningY - centerY; var controlX = 0; // Center relative to arrows container var controlY = 0; console.log("Bezier points:", { start: { x: startX, y: startY }, end: { x: endX, y: endY }, control: { x: controlX, y: controlY } }); // Create container for the arrow var arrowContainer = new Container(); // Find the arrows container (first child of game that's a Container) var arrowsContainer = null; for (var i = 0; i < game.children.length; i++) { if (game.children[i].constructor === Container && game.children[i] !== wheelContainer) { arrowsContainer = game.children[i]; break; } } if (arrowsContainer) { arrowsContainer.addChild(arrowContainer); } else { game.addChild(arrowContainer); } console.log("Created arrow container, added to arrows container"); // Number of segments for the bezier curve var segments = 80; var halfSegments = segments / 2; // Create line segments for bezier curve for (var i = 0; i < segments; i++) { var t1 = i / segments; var t2 = (i + 1) / segments; // Calculate bezier points var x1 = (1 - t1) * (1 - t1) * startX + 2 * (1 - t1) * t1 * controlX + t1 * t1 * endX; var y1 = (1 - t1) * (1 - t1) * startY + 2 * (1 - t1) * t1 * controlY + t1 * t1 * endY; var x2 = (1 - t2) * (1 - t2) * startX + 2 * (1 - t2) * t2 * controlX + t2 * t2 * endX; var y2 = (1 - t2) * (1 - t2) * startY + 2 * (1 - t2) * t2 * controlY + t2 * t2 * endY; // Calculate angle and distance for this segment var dx = x2 - x1; var dy = y2 - y1; var distance = Math.sqrt(dx * dx + dy * dy); var angle = Math.atan2(dy, dx); // Create line segment var lineSegment = LK.getAsset('line', { anchorX: 0, anchorY: 0.5 }); console.log("Segment", i, "- position:", { x: x1, y: y1 }, "distance:", distance, "angle:", angle); arrowContainer.addChild(lineSegment); // Position and rotate the segment lineSegment.x = x1; lineSegment.y = y1; lineSegment.rotation = angle; lineSegment.width = distance; lineSegment.height = 8; // Line thickness // Color the segment - first half red, second half green if (i < halfSegments) { lineSegment.tint = 0xff0000; // Red for first half } else { lineSegment.tint = 0x00ff00; // Green for second half } console.log("Segment", i, "created with width:", lineSegment.width, "height:", lineSegment.height, "tint:", lineSegment.tint.toString(16)); } console.log("Total segments created:", segments, "Arrow container children count:", arrowContainer.children.length); // Store arrow for cleanup victoryArrows.push(arrowContainer); console.log("Arrow stored. Total victory arrows:", victoryArrows.length); // Animate arrow appearance arrowContainer.alpha = 0; console.log("Starting arrow animation from alpha 0 to 1"); tween(arrowContainer, { alpha: 1 }, { duration: 500, onFinish: function onFinish() { console.log("Arrow animation finished. Final alpha:", arrowContainer.alpha); } }); } // Reset for next round function resetForNextRound() { gameState = 'selection'; // Stop any ongoing wheel spinning animation if (wheelContainer) { tween.stop(wheelContainer, { rotation: true }); } // Reset spinning state isWheelSpinning = false; // Reset combo state for next round playerCombo = []; aiCombo = []; aiComboSpins = 0; updateComboDisplay(); updateAIComboDisplay(); // Don't reset aiElement to null immediately - we need it for victory arrows // aiElement will be reset when a new round actually starts // Reset wheel rotation and element rotations if (wheelContainer) { wheelContainer.rotation = 0; } // Reset all element button rotations to keep them upright for (var i = 0; i < elementButtons.length; i++) { elementButtons[i].rotation = 0; } // Clean up battle elements if (playerBattleElement) { playerBattleElement.destroy(); playerBattleElement = null; } if (aiBattleElement) { aiBattleElement.destroy(); aiBattleElement = null; } if (vsText) { vsText.destroy(); vsText = null; } // Reset instruction text instructionText.setText('Choose first element for combo'); instructionText.tint = 0xcccccc; // Restore original font size instructionText.size = 32; // Clean up triangle if it exists if (instructionText.triangle) { instructionText.triangle.destroy(); instructionText.triangle = null; } // Create victory arrow if we have a battle result and both elements are valid var battleResult = checkBattleResult(); console.log("Battle result:", battleResult, "playerElement:", playerElement, "aiElement:", aiElement); if (playerElement && aiElement && battleResult !== 'tie') { if (battleResult === 'player') { console.log("Creating victory arrow: AI loses, Player wins"); createVictoryArrow(aiElement, playerElement); } else if (battleResult === 'ai') { console.log("Creating victory arrow: Player loses, AI wins"); createVictoryArrow(playerElement, aiElement); } } else { console.log("Skipping victory arrow creation - tie result or missing elements"); } // Show victory arrows again for (var i = 0; i < victoryArrows.length; i++) { tween(victoryArrows[i], { alpha: 1 }, { duration: 300 }); } // Show selection elements and re-enable only unused ones for (var i = 0; i < elementButtons.length; i++) { elementButtons[i].setSelected(false); var elementType = elementButtons[i].elementType; var isUsed = usedPlayerElements.indexOf(elementType) !== -1 || usedAIElements.indexOf(elementType) !== -1; elementButtons[i].setDisabled(isUsed); tween(elementButtons[i], { alpha: 1 }, { duration: 300 }); // Show element labels again after returning from battle var button = elementButtons[i]; var label = button.children[button.children.length - 1]; // Label is the last child if (label && label.setText) { tween(label, { alpha: 1 }, { duration: 300 }); } } // Reset battle timer battleTimer = 0; } // Game move handler for hover effects game.move = function (x, y, obj) { if (gameState !== 'selection') { return; } var newHoveredButton = null; // Check which button is under the cursor for (var i = 0; i < elementButtons.length; i++) { var button = elementButtons[i]; // Convert game coordinates to wheel container space // Account for wheel container position (1024, 1400) var localX = x - wheelContainer.x; var localY = y - wheelContainer.y; // Calculate distance from cursor to button center var dx = localX - button.x; var dy = localY - button.y; var distance = Math.sqrt(dx * dx + dy * dy); // Use button's actual width/height to determine hit area (button is anchored at center) var hitRadius = 150; // Approximate radius for the button hit area if (distance < hitRadius) { newHoveredButton = button; break; } } // Handle hover state changes if (hoveredButton !== newHoveredButton) { // Handle leave event for previously hovered button if (hoveredButton && !hoveredButton.isSelected && !hoveredButton.isDisabled) { // Stop any existing scale tweens tween.stop(hoveredButton, { scaleX: true, scaleY: true }); // Scale back to normal tween(hoveredButton, { scaleX: 1.0, scaleY: 1.0 }, { duration: 150 }); } // Handle hover event for new button if (newHoveredButton && !newHoveredButton.isSelected && !newHoveredButton.isDisabled) { // Stop any existing scale tweens tween.stop(newHoveredButton, { scaleX: true, scaleY: true }); // Scale up on hover tween(newHoveredButton, { scaleX: 1.1, scaleY: 1.1 }, { duration: 150 }); } hoveredButton = newHoveredButton; } }; // Initialize game createElementButtons(); // Start with a random weather 50% of the time if (Math.random() < 0.5) { startNewWeather(); } else { // Start a new weather if none is active startNewWeather(); } // Game update loop game.update = function () { // Keep elements upright during wheel spinning if (isWheelSpinning && wheelContainer) { for (var i = 0; i < elementButtons.length; i++) { // Counter-rotate each element button to keep it upright elementButtons[i].rotation = -wheelContainer.rotation; // Restore original label position var button = elementButtons[i]; var label = button.children[button.children.length - 1]; if (label && label.setText && button.originalLabelX !== undefined) { label.x = button.originalLabelX; label.y = button.originalLabelY; } } } if (gameState === 'battle' && playerBattleElement && aiBattleElement) { battleTimer++; // Show result after 3 seconds if (battleTimer >= 180) { // 3 seconds at 60 FPS showBattleResult(); } } };
===================================================================
--- original.js
+++ change.js
@@ -1307,8 +1307,9 @@
weatherRoundsLeft--;
updateWeatherDisplay();
if (weatherRoundsLeft === 0) {
currentWeather = null;
+ updateWeatherDisplay(); // Update display when weather ends
}
} else {
// 30% chance to start new weather when no weather is active
if (Math.random() < 0.3) {
A hand with its fingers symbolizing gas
Make the background darker (blue)
Make the bacgkground color darker(blue)
a triangle pointing down. In-Game asset. 2d. High contrast. No shadows
This place after a draught
This place in very windy conditions
This place but it's raining
This place but there is an electric storm
a popup frame, retro pixel style, rectangular. In-Game asset. 2d. High contrast. No shadows
A version of this frame that symbolizes that this button has boosted / improved power
a minimalistic pixel button, no text on it, just the buton. White.. In-Game asset. 2d. High contrast. No shadows
A win effect that will be over a round button and that will triger for some seconds after a win happens, scaling in x and y as an effect.. In-Game asset. 2d. High contrast. No shadows
Lose
The frame should be ice related too
The frame should be earth related too
The frame should be water related too
The frame should be wind too
A hand with its fingers symbolizing ash
A hand with its fingers symbolizing sun
A hand with its fingers symbolizing moon
A hand with a piece of leather
A hand with a piece of plastic
A hand with a piece of opaque plastic
A hand with its fingers symbolizing salt
Can you make this picture slightly lighter
Can you make this image lighter please? But not a lot lighter, just a little
A frame that symbolizes that the element inside is penalized, unboosted, has a minus to its effect. It should be shown in the frame, not inside! With some VFX effect
One drop of rain. In-Game asset. 2d. High contrast. No shadows
Yellow / Orange colour
wind. In-Game asset. 2d. High contrast. No shadows
A pixel style magician from Magicka who has an arc around him of elements to be casted (fire, water, ice, rock, etc). In-Game asset. 2d. High contrast. No shadows
Tint the wizard to blue
Make the black border of the start twice thicker
A '?' (question mark) symbol inside
A white shield. In-Game asset. 2d. High contrast. No shadows
background
Music
air
Music
storm
Music
rain
Music
draught
Music
rock
Sound effect
paper
Sound effect
scissors
Sound effect
fire
Sound effect
metal
Sound effect
water
Sound effect
airy
Sound effect
lightning
Sound effect
tree
Sound effect
gun
Sound effect
sponge
Sound effect
smoke
Sound effect
gas
Sound effect
ice
Sound effect
sand
Sound effect
oil
Sound effect
plastic
Sound effect
leather
Sound effect
sun
Sound effect
glass
Sound effect
cloth
Sound effect
ash
Sound effect
fungus
Sound effect
moon
Sound effect
salt
Sound effect
select
Sound effect
spinning
Sound effect
win
Sound effect