User prompt
Please fix the bug: 'Cannot set properties of undefined (setting 'fill')' in or related to this line: 'textDisplay.style.fill = color;' Line Number: 319
User prompt
Please fix the bug: 'button.setEnabled is not a function' in or related to this line: 'button.setEnabled(skillPointsAvailable > 0);' Line Number: 506
Code edit (1 edits merged)
Please save this source code
User prompt
Monster Gauntlet: Battle RNG
Initial prompt
MG battle RNG
/**** * Plugins ****/ var tween = LK.import("@upit/tween.v1"); var storage = LK.import("@upit/storage.v1", { playerLevel: 1, victories: 0, skillPoints: 0, attackBonus: 0, defenseBonus: 0, specialBonus: 0, healthBonus: 0 }); /**** * Classes ****/ var ActionButton = Container.expand(function (text, action) { var self = Container.call(this); var buttonGraphic = self.attachAsset('actionButton', { anchorX: 0.5, anchorY: 0.5 }); var buttonText = new Text2(text, { size: 50, fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); self.addChild(buttonText); self.action = action; self.enabled = true; self.setEnabled = function (enabled) { self.enabled = enabled; buttonGraphic.alpha = enabled ? 1.0 : 0.5; }; self.down = function (x, y, obj) { if (!self.enabled) { return; } tween(buttonGraphic, { scaleX: 0.9, scaleY: 0.9 }, { duration: 100 }); }; self.up = function (x, y, obj) { if (!self.enabled) { return; } tween(buttonGraphic, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100, onFinish: function onFinish() { if (self.action) { self.action(); } } }); }; return self; }); var Dice = Container.expand(function () { var self = Container.call(this); var diceGraphic = self.attachAsset('dice', { anchorX: 0.5, anchorY: 0.5 }); var valueText = new Text2('?', { size: 60, fill: 0x000000 }); valueText.anchor.set(0.5, 0.5); self.addChild(valueText); self.value = 0; self.isRolling = false; self.roll = function (callback) { if (self.isRolling) { return; } self.isRolling = true; LK.getSound('diceRoll').play(); var rollIterations = 10; var currentIteration = 0; function doRoll() { self.value = Math.floor(Math.random() * 6) + 1; valueText.setText(self.value.toString()); currentIteration++; if (currentIteration < rollIterations) { LK.setTimeout(doRoll, 100); } else { self.isRolling = false; if (callback) { callback(self.value); } } } doRoll(); }; self.setValue = function (val) { self.value = val; valueText.setText(val.toString()); }; return self; }); var HealthBar = Container.expand(function () { var self = Container.call(this); var background = self.attachAsset('hpBarBg', { anchorX: 0, anchorY: 0 }); var foreground = self.attachAsset('hpBar', { anchorX: 0, anchorY: 0 }); self.maxHealth = 100; self.currentHealth = 100; self.setMaxHealth = function (value) { self.maxHealth = value; self.updateDisplay(); }; self.setCurrentHealth = function (value) { self.currentHealth = Math.max(0, Math.min(self.maxHealth, value)); self.updateDisplay(); }; self.updateDisplay = function () { var ratio = self.currentHealth / self.maxHealth; foreground.scale.x = ratio; }; return self; }); var Monster = Container.expand(function (isPlayer) { var self = Container.call(this); var assetId = isPlayer ? 'playerMonster' : 'enemyMonster'; var monsterGraphic = self.attachAsset(assetId, { anchorX: 0.5, anchorY: 0.5 }); var nameText = new Text2(isPlayer ? "Player" : "Enemy", { size: 40, fill: 0xFFFFFF }); nameText.anchor.set(0.5, 0); nameText.y = -monsterGraphic.height / 2 - 50; self.addChild(nameText); var healthBar = new HealthBar(); healthBar.y = monsterGraphic.height / 2 + 20; healthBar.x = -healthBar.width / 2; self.addChild(healthBar); self.isPlayer = isPlayer; self.level = 1; self.baseHealth = 100; self.baseAttack = 10; self.baseDefense = 5; self.baseSpecial = 15; self.maxHealth = self.baseHealth; self.currentHealth = self.maxHealth; self.attackPower = self.baseAttack; self.defensePower = self.baseDefense; self.specialPower = self.baseSpecial; self.setName = function (name) { nameText.setText(name); }; self.setLevel = function (level) { self.level = level; if (!self.isPlayer) { // Scale enemy stats based on level self.maxHealth = self.baseHealth + (level - 1) * 20; self.attackPower = self.baseAttack + (level - 1) * 2; self.defensePower = self.baseDefense + (level - 1); self.specialPower = self.baseSpecial + (level - 1) * 3; } else { // Apply player bonuses from storage self.maxHealth = self.baseHealth + storage.healthBonus * 10; self.attackPower = self.baseAttack + storage.attackBonus; self.defensePower = self.baseDefense + storage.defenseBonus; self.specialPower = self.baseSpecial + storage.specialBonus; } self.currentHealth = self.maxHealth; healthBar.setMaxHealth(self.maxHealth); healthBar.setCurrentHealth(self.currentHealth); }; self.takeDamage = function (amount) { self.currentHealth -= amount; if (self.currentHealth < 0) { self.currentHealth = 0; } healthBar.setCurrentHealth(self.currentHealth); // Flash red on damage LK.effects.flashObject(monsterGraphic, 0xff0000, 500); // Shake when hit self.shake(); return self.currentHealth <= 0; // Return true if defeated }; self.heal = function (amount) { self.currentHealth += amount; if (self.currentHealth > self.maxHealth) { self.currentHealth = self.maxHealth; } healthBar.setCurrentHealth(self.currentHealth); }; self.shake = function () { var originalX = self.x; var originalY = self.y; function shakeStep(magnitude) { var offsetX = (Math.random() - 0.5) * 2 * magnitude; var offsetY = (Math.random() - 0.5) * 2 * magnitude; self.x = originalX + offsetX; self.y = originalY + offsetY; } var steps = 10; var currentStep = 0; var maxMagnitude = 20; function doShake() { var magnitude = maxMagnitude * (1 - currentStep / steps); shakeStep(magnitude); currentStep++; if (currentStep < steps) { LK.setTimeout(doShake, 30); } else { self.x = originalX; self.y = originalY; } } doShake(); }; self.down = function (x, y, obj) { // Just for show - adds interactivity by shrinking slightly on press if (self.isPlayer) { tween(monsterGraphic, { scaleX: 0.95, scaleY: 0.95 }, { duration: 100 }); } }; self.up = function (x, y, obj) { if (self.isPlayer) { tween(monsterGraphic, { scaleX: 1.0, scaleY: 1.0 }, { duration: 100 }); } }; return self; }); var StatUpgradeButton = Container.expand(function (statName, upgradeAction) { var self = Container.call(this); var buttonGraphic = self.attachAsset('actionButton', { anchorX: 0.5, anchorY: 0.5, scaleX: 0.8, scaleY: 0.8 }); var buttonText = new Text2(statName + " +1", { size: 40, fill: 0xFFFFFF }); buttonText.anchor.set(0.5, 0.5); self.addChild(buttonText); self.upgradeAction = upgradeAction; self.down = function (x, y, obj) { tween(buttonGraphic, { scaleX: 0.75, scaleY: 0.75 }, { duration: 100 }); }; self.up = function (x, y, obj) { tween(buttonGraphic, { scaleX: 0.8, scaleY: 0.8 }, { duration: 100, onFinish: function onFinish() { if (self.upgradeAction) { self.upgradeAction(); } } }); }; self.setEnabled = function (enabled) { self.enabled = enabled; buttonGraphic.alpha = enabled ? 1.0 : 0.5; }; return self; }); var StatusText = Container.expand(function () { var self = Container.call(this); var textDisplay = new Text2("", { size: 60, fill: 0xFFFFFF }); textDisplay.anchor.set(0.5, 0.5); self.addChild(textDisplay); self.show = function (message, color, duration) { textDisplay.setText(message); if (color) { if (textDisplay.style) { textDisplay.style.fill = color; } else { textDisplay.style = { fill: color }; } } else { if (textDisplay.style) { textDisplay.style.fill = "#ffffff"; } else { textDisplay.style = { fill: 0xFFFFFF }; } } self.alpha = 1; if (duration) { tween(self, { alpha: 0 }, { duration: duration }); } }; return self; }); /**** * Initialize Game ****/ var game = new LK.Game({ backgroundColor: 0x2c3e50 }); /**** * Game Code ****/ // Game state var gameState = "start"; // Possible states: "start", "battle", "playerTurn", "enemyTurn", "diceRoll", "victory", "defeat", "upgrade" var currentDiceRoll = 0; var actionInProgress = false; var skillPointsAvailable = storage.skillPoints; // Game objects var playerMonster; var enemyMonster; var actionDice; var actionButtons = []; var statusText; var upgradeButtons = []; // Initialize the game function initGame() { // Play background music LK.playMusic('battleMusic'); // Create player monster playerMonster = new Monster(true); playerMonster.x = 2048 * 0.25; playerMonster.y = 2732 * 0.5; playerMonster.setName("Your Monster"); playerMonster.setLevel(storage.playerLevel); game.addChild(playerMonster); // Create enemy monster enemyMonster = new Monster(false); enemyMonster.x = 2048 * 0.75; enemyMonster.y = 2732 * 0.5; enemyMonster.setName("Enemy Lvl " + storage.playerLevel); enemyMonster.setLevel(storage.playerLevel); game.addChild(enemyMonster); // Create action dice actionDice = new Dice(); actionDice.x = 2048 * 0.5; actionDice.y = 2732 * 0.4; actionDice.visible = false; game.addChild(actionDice); // Create status text statusText = new StatusText(); statusText.x = 2048 * 0.5; statusText.y = 2732 * 0.3; game.addChild(statusText); // Create action buttons var buttonY = 2732 * 0.75; var buttonSpacing = 350; var attackButton = new ActionButton("Attack", function () { if (!actionInProgress && gameState === "playerTurn") { performPlayerAction("attack"); } }); attackButton.x = 2048 * 0.5 - buttonSpacing; attackButton.y = buttonY; game.addChild(attackButton); actionButtons.push(attackButton); var defendButton = new ActionButton("Defend", function () { if (!actionInProgress && gameState === "playerTurn") { performPlayerAction("defend"); } }); defendButton.x = 2048 * 0.5; defendButton.y = buttonY; game.addChild(defendButton); actionButtons.push(defendButton); var specialButton = new ActionButton("Special", function () { if (!actionInProgress && gameState === "playerTurn") { performPlayerAction("special"); } }); specialButton.x = 2048 * 0.5 + buttonSpacing; specialButton.y = buttonY; game.addChild(specialButton); actionButtons.push(specialButton); // Create upgrade buttons (initially hidden) createUpgradeButtons(); // Create score display var levelText = new Text2("Level: " + storage.playerLevel, { size: 50, fill: 0xFFFFFF }); levelText.anchor.set(1, 0); levelText.x = 2048 - 50; levelText.y = 50; game.addChild(levelText); var victoryText = new Text2("Victories: " + storage.victories, { size: 50, fill: 0xFFFFFF }); victoryText.anchor.set(1, 0); victoryText.x = 2048 - 50; victoryText.y = 110; game.addChild(victoryText); var skillPointsText = new Text2("Skill Points: " + storage.skillPoints, { size: 50, fill: 0xFFFFFF }); skillPointsText.anchor.set(0, 0); skillPointsText.x = 150; skillPointsText.y = 50; game.addChild(skillPointsText); // Start the battle startBattle(); } function createUpgradeButtons() { var startY = 2732 * 0.55; var spacing = 150; var attackUpgrade = new StatUpgradeButton("Attack", function () { if (skillPointsAvailable > 0) { storage.attackBonus++; storage.skillPoints--; skillPointsAvailable--; updateUpgradeButtons(); } }); attackUpgrade.x = 2048 * 0.5; attackUpgrade.y = startY; game.addChild(attackUpgrade); upgradeButtons.push(attackUpgrade); var defenseUpgrade = new StatUpgradeButton("Defense", function () { if (skillPointsAvailable > 0) { storage.defenseBonus++; storage.skillPoints--; skillPointsAvailable--; updateUpgradeButtons(); } }); defenseUpgrade.x = 2048 * 0.5; defenseUpgrade.y = startY + spacing; game.addChild(defenseUpgrade); upgradeButtons.push(defenseUpgrade); var specialUpgrade = new StatUpgradeButton("Special", function () { if (skillPointsAvailable > 0) { storage.specialBonus++; storage.skillPoints--; skillPointsAvailable--; updateUpgradeButtons(); } }); specialUpgrade.x = 2048 * 0.5; specialUpgrade.y = startY + spacing * 2; game.addChild(specialUpgrade); upgradeButtons.push(specialUpgrade); var healthUpgrade = new StatUpgradeButton("Health", function () { if (skillPointsAvailable > 0) { storage.healthBonus++; storage.skillPoints--; skillPointsAvailable--; updateUpgradeButtons(); } }); healthUpgrade.x = 2048 * 0.5; healthUpgrade.y = startY + spacing * 3; game.addChild(healthUpgrade); upgradeButtons.push(healthUpgrade); var continueButton = new ActionButton("Continue", function () { if (gameState === "upgrade") { startBattle(); } }); continueButton.x = 2048 * 0.5; continueButton.y = startY + spacing * 4.5; game.addChild(continueButton); upgradeButtons.push(continueButton); // Hidden initially updateUpgradeButtons(); setUpgradeButtonsVisible(false); } function updateUpgradeButtons() { for (var i = 0; i < upgradeButtons.length - 1; i++) { var button = upgradeButtons[i]; button.setEnabled(skillPointsAvailable > 0); } } function setUpgradeButtonsVisible(visible) { for (var i = 0; i < upgradeButtons.length; i++) { upgradeButtons[i].visible = visible; } } function setActionButtonsVisible(visible) { for (var i = 0; i < actionButtons.length; i++) { actionButtons[i].visible = visible; } } function startBattle() { gameState = "battle"; actionInProgress = false; // Reset monsters for new battle playerMonster.setLevel(storage.playerLevel); enemyMonster.setName("Enemy Lvl " + storage.playerLevel); enemyMonster.setLevel(storage.playerLevel); // Hide upgrade buttons, show action buttons setUpgradeButtonsVisible(false); setActionButtonsVisible(true); // Show battle start message statusText.show("Battle Start!", "#ffff00", 2000); // Start player turn after a delay LK.setTimeout(function () { startPlayerTurn(); }, 2000); } function startPlayerTurn() { gameState = "playerTurn"; statusText.show("Your Turn", "#3498db", 2000); } function performPlayerAction(actionType) { gameState = "diceRoll"; actionInProgress = true; // Play sound based on action LK.getSound(actionType).play(); // Show the dice for roll actionDice.visible = true; actionDice.roll(function (value) { // Process player action based on dice roll currentDiceRoll = value; var actionResult = calculateActionResult(actionType, playerMonster, enemyMonster, value); if (actionType === "attack") { statusText.show("You attacked for " + actionResult + " damage!", "#ff9900"); var defeated = enemyMonster.takeDamage(actionResult); if (defeated) { handleVictory(); return; } } else if (actionType === "defend") { var healAmount = Math.floor(actionResult / 2); statusText.show("You defended! +" + actionResult + " DEF for this turn\n+" + healAmount + " HP", "#2ecc71"); playerMonster.defensePower += actionResult; // Temporary defense boost playerMonster.heal(healAmount); } else if (actionType === "special") { statusText.show("Special attack for " + actionResult + " damage!", "#9b59b6"); var defeated = enemyMonster.takeDamage(actionResult); if (defeated) { handleVictory(); return; } } // Hide dice after action LK.setTimeout(function () { actionDice.visible = false; // Start enemy turn after a delay LK.setTimeout(function () { startEnemyTurn(); }, 1000); }, 1000); }); } function startEnemyTurn() { gameState = "enemyTurn"; statusText.show("Enemy Turn", "#e74c3c", 1000); // Reset temporary defense boost from defend action if (playerMonster.defensePower > playerMonster.baseDefense + storage.defenseBonus) { playerMonster.defensePower = playerMonster.baseDefense + storage.defenseBonus; } // Enemy AI chooses action LK.setTimeout(function () { var actions = ["attack", "special", "defend"]; var weights = [0.6, 0.3, 0.1]; // Weights for action selection if (enemyMonster.currentHealth < enemyMonster.maxHealth * 0.3) { // When low on health, more likely to defend weights = [0.4, 0.2, 0.4]; } var actionIndex = weightedRandomChoice(actions, weights); var actionType = actions[actionIndex]; // Play sound based on action LK.getSound(actionType).play(); // Show dice for enemy roll actionDice.visible = true; actionDice.roll(function (value) { currentDiceRoll = value; var actionResult = calculateActionResult(actionType, enemyMonster, playerMonster, value); if (actionType === "attack") { statusText.show("Enemy attacked for " + actionResult + " damage!", "#ff9900"); var defeated = playerMonster.takeDamage(actionResult); if (defeated) { handleDefeat(); return; } } else if (actionType === "defend") { var healAmount = Math.floor(actionResult / 2); statusText.show("Enemy defended! +" + actionResult + " DEF\n+" + healAmount + " HP", "#2ecc71"); enemyMonster.defensePower += actionResult; // Temporary defense boost enemyMonster.heal(healAmount); } else if (actionType === "special") { statusText.show("Enemy special attack for " + actionResult + " damage!", "#9b59b6"); var defeated = playerMonster.takeDamage(actionResult); if (defeated) { handleDefeat(); return; } } // Hide dice after action LK.setTimeout(function () { actionDice.visible = false; // Start player turn again after a delay LK.setTimeout(function () { actionInProgress = false; startPlayerTurn(); }, 1000); }, 1000); }); }, 1000); } function calculateActionResult(actionType, attacker, defender, diceValue) { var result = 0; if (actionType === "attack") { // Base damage is attacker's attack power + dice roll var baseDamage = attacker.attackPower + diceValue * 2; // Reduce by defender's defense result = Math.max(1, baseDamage - Math.floor(defender.defensePower / 2)); } else if (actionType === "defend") { // Defense value is based on dice roll result = diceValue * 3; } else if (actionType === "special") { // Special attack does more damage but is more dependent on dice roll var baseDamage = attacker.specialPower + diceValue * 4; // Special attacks ignore some defense result = Math.max(1, baseDamage - Math.floor(defender.defensePower / 3)); } return result; } function handleVictory() { gameState = "victory"; actionInProgress = true; LK.getSound('victory').play(); // Hide dice actionDice.visible = false; // Update stats storage.victories++; storage.playerLevel++; storage.skillPoints++; skillPointsAvailable = storage.skillPoints; // Show victory message statusText.show("Victory! +1 Skill Point", "#ffff00"); // Show upgrade screen after delay LK.setTimeout(function () { setActionButtonsVisible(false); setUpgradeButtonsVisible(true); updateUpgradeButtons(); gameState = "upgrade"; statusText.show("Upgrade Your Monster", "#2ecc71"); }, 2000); } function handleDefeat() { gameState = "defeat"; actionInProgress = true; LK.getSound('defeat').play(); // Hide dice actionDice.visible = false; // Show defeat message statusText.show("Defeat!", "#e74c3c"); // End game after delay LK.setTimeout(function () { LK.showGameOver(); }, 2000); } function weightedRandomChoice(items, weights) { var totalWeight = 0; for (var i = 0; i < weights.length; i++) { totalWeight += weights[i]; } var random = Math.random() * totalWeight; var weightSum = 0; for (var i = 0; i < items.length; i++) { weightSum += weights[i]; if (random < weightSum) { return i; } } return 0; // Fallback } // Initialize game initGame(); // Game update loop game.update = function () { // Game logic that needs to run every frame would go here // Currently, all our logic is event-driven }; // Handle mouse/touch events game.move = function (x, y, obj) { // Movement handling if needed }; game.down = function (x, y, obj) { // Handle clicks not caught by other objects }; game.up = function (x, y, obj) { // Handle releases not caught by other objects };
===================================================================
--- original.js
+++ change.js
@@ -301,11 +301,23 @@
self.addChild(textDisplay);
self.show = function (message, color, duration) {
textDisplay.setText(message);
if (color) {
- textDisplay.style.fill = color;
+ if (textDisplay.style) {
+ textDisplay.style.fill = color;
+ } else {
+ textDisplay.style = {
+ fill: color
+ };
+ }
} else {
- textDisplay.style.fill = "#ffffff";
+ if (textDisplay.style) {
+ textDisplay.style.fill = "#ffffff";
+ } else {
+ textDisplay.style = {
+ fill: 0xFFFFFF
+ };
+ }
}
self.alpha = 1;
if (duration) {
tween(self, {