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, {