У меня, похоже, очень плохо с моим кодом. В первый раз, когда я назвал функцию битвы, она работает нормально, но во второй раз, когда я ее вызываю, он просто использует параметр, который был передан во время первого вызова. Я думаю, что функция все еще работает от первого вызова. Вот мой код, в котором я пытался только поместить существенные части:
var player = {
// Name
// Position
totalHealth: 20, // total Health
currentHealth : 20, // current Health
Level: 1, // Level
// Defense
// Attack
// Luck
Win: false,
EXP: 0,
EXPNeededCalculation: function (Level) {
return (Level * 100) - player.EXP;
},
EXPGainedCalculation: function (opponentLevel, playerCurrentHealth, playerTotalHealth) {
return player.EXP += Math.ceil(opponentLevel * 10 - ((playerTotalHealth - playerCurrentHealth) / 2));
},
// Items are in an object {Description: powers, used : false, use() : yadayadayada}
DefenseDoubled: false,
attack: function (Attack, Luck, opponentDefense) {
var possibleAttacks = [];
var possibleDefense = [999]; // arbitrary number to fill one space
for (var i = 0 ; i < Luck ; i++) {
possibleAttacks.push(Math.ceil(Math.random() * Attack));
};
possibleAttacks.sort();
var a = Math.ceil(Math.random() * 10);
if (a > 7) {
for (var x = 0 ; x < opponentDefense ; x++) {
possibleDefense.push(Math.floor(Math.random() * opponentDefense) - 1);
};
}
possibleDefense.sort();
if (possibleDefense[0] <= 0) {
var b = 0;
} else {
var b = 998; // arbitrary number
}
if (b === 0) {
player["attackDamage"] = 0;
} else {
player["attackDamage"] = possibleAttacks[possibleAttacks.length - 1];
}
},
defend: function() {
player.Defense *= 2;
player.DefenseDoubled = true;
},
undefend: function() {
player.Defense /= 2;
player.DefenseDoubled = false;
}
};
function opponent(Level, Type, Name) {
this.Name = Name;
this.Level = Level;
this.Type = Type;
this.Health = calcHealth(Level);
this.currentHealth = calcHealth(Level);
this.Defense = calcStats(Level, Type);
this.Attack = calcStats(Level, Type);
this.Luck = calcStats(Level, Type);
this.attackDamage = 0;
this.DefenseDoubled = false;
this.Poisoned = false;
this.Burned = false;
this.Frozen = false;
function calcHealth(Level) {
this.Health = Level * 5;
this.currentHealth = this.Health;
return this.Health; return this.currentHealth;
};
function calcStats(Level, Type) {
this.Defense = Level * 2;
this.Attack = Math.ceil(Level * 1.5);
this.Luck = Math.ceil(Level * 1.25);
return this.Defense ; return this.Attack ; return this.Luck;
if (Type === "snake" || Type === "Snake") {
this.Luck += 1;
}
};
this.attack = function(Attack, Luck, playerDefense) {
var possibleAttacks = [];
var possibleDefense = [999]; // arbitrary number to fill one space
for (var i = 0 ; i < Luck ; i++) {
possibleAttacks.push(Math.ceil(Math.random() * Attack));
};
possibleAttacks.sort();
var a = Math.ceil(Math.random() * 10);
if (a > 7) {
for (var x = 0 ; x < playerDefense ; x++) {
possibleDefense.push(Math.floor(Math.random() * playerDefense) - 1);
};
}
possibleDefense.sort();
if (possibleDefense[0] <= 0) {
var b = 0;
} else {
var b = 998; // arbitrary number
}
if (b === 0) {
this.attackDamage = 0;
} else {
this.attackDamage = possibleAttacks[possibleAttacks.length - 1];
}
};
this.defend = function() {
this.Defense *= 2;
this.DefenseDoubled = true;
};
this.undefend = function() {
this.Defense /= 2;
this.DefenseDoubled = false;
}
}
$yesButton.click(function() {
yPressed = true;
if (value === 4 && yPressed === true) {
addToValue(1);
yPressed = false;
$showBattleSummaryBox();
$statsBox.append("<p class='center'>Health: " + player.totalHealth + "</p>");
$battleSummaryBox.append("<p id='playersHealth' class='center'>Your Health: " + player.currentHealth + "/" + player.totalHealth + "</p>");
$outputBox.append("<p>On the right is your Battle Summary Box. Your health has also shown up. If your health reaches zero, then you will faint, but if your enemy health reaches zero, then you win.</p>");
$outputBox.append("<p>Battles are turn-based. You will make an action and then your opponent will. During your turn, you can either attack, defend, or use an item.</p>");
$outputBox.append("<p>I happen to have a level 1 python for you to practice with. </p>");
scroll($outputBox);
var e1 = new opponent(1, "snake", "Python");
$battleSummaryBox.append("<p id='opponentsHealth' class='center'>Enemy Health: " + e1.currentHealth + "/" + e1.Health + "</p>");
$showBattleCommandBox();
battle(e1);
}
});
function battle(opponent) {
$battleOutputBox.append("<p>You make the first move!</p>");
$("#opponentsHealth").text("Enemy Health: " + opponent.currentHealth + "/" + opponent.Health);
battleInProgress = true;
$attackButton.click(function () {
if (player.Win === false && battleInProgress === true) {
player.attack(player.Attack, player.Luck, opponent.Defense);
// additional Item effects
if (player.Items.hasOwnProperty("Poison Arrows")) {
var e = Math.ceil(Math.random() * 10);
if (e > 7) {
opponent.Poisoned = true;
}
} else if (player.Items.hasOwnProperty("Fire Blade")) {
var e = Math.ceil(Math.random() * 10);
if (e > 7) {
opponent.Burned = true;
player.attackDamage += 3;
}
} else if (player.Items.hasOwnProperty("Blade of Luck")) {
var e = Math.ceil(Math.random() * 10);
if (e > 7) {
player.attackDamage += 1;
}
}
opponent.currentHealth -= player.attackDamage;
$("#opponentsHealth").text("Enemy Health: " + opponent.currentHealth + "/" + opponent.Health);
if (player.attackDamage === 0) {
$battleOutputBox.append("<p>Your attack has been blocked</p>");
} else {
$battleOutputBox.append("<p>You inflicted " + player.attackDamage + " damage.</p>");
scroll($battleOutputBox);
}
if (opponent.DefenseDoubled === true) {
opponent.undefend();
}
if (opponent.Poisoned === true) {
Poison();
} else if (opponent.Burned === true) {
Burn();
} else if (opponent.Frozen === true) {
Freeze();
}
if (opponent.currentHealth <= 0) {
player.Win = true;
return postBattle(opponent);
} else {opponentTurn();}
}
});
$defendButton.click(function () {
if (player.Win === false && battleInProgress === true) {
player.defend();
$battleOutputBox.append("<p>Your defense has been doubled for one turn.</p>");
if (opponent.DefenseDoubled === true) {
opponent.undefend();
}
if (opponent.Poisoned === true) {
Poison();
} else if (opponent.Burned === true) {
Burn();
} else if (opponent.Frozen === true) {
Freeze();
}
if (opponent.currentHealth <= 0) {
player.Win = true;
return postBattle(opponent);
} else {opponentTurn();}
}
});
$useItemButton.click(function () {
if (player.Win === false && battleInProgress === true) {
if ($useItemSelection.html().length > 15) {
var itemBeingUsed = $("select[name='useItemSelection'] option:selected").text();
if (itemBeingUsed === "Book of Spells" && player.Items.bookOfSpells.used === false) {
player.Items.bookOfSpells.use();
console.log(player.Items.bookOfSpells.effect);
if (player.Items.bookOfSpells.effect === "burn" || player.Items.bookOfSpells.effect === "poison") {
$battleOutputBox.append("<p>You have " + player.Items.bookOfSpells.effect + "ed " + opponent.Name + ".</p>");
if (player.Items.bookOfSpells.effect === "burn") {
opponent.Burned = true;
} else {
opponent.Poisoned = true;
}
} else {
$battleOutputBox.append("<p>You have froze " + opponent.Name + ".</p>");
opponent.Frozen = true;
}
player.Items.bookOfSpells.used = true;
} else if (itemBeingUsed === "Shield Charm" && player.Items.shieldCharm.used === false) {
player.Items.shieldCharm.use();
$battleOutputBox.append("<p>You will block the next attack with your shield charm.</p>");
player.Items.shieldCharm.used = true;
}
if (opponent.Poisoned === true) {
Poison();
} else if (opponent.Burned === true) {
Burn();
} else if (opponent.Frozen === true) {
Freeze();
}
if (opponent.currentHealth <= 0) {
player.Win = true;
return postBattle(opponent);
} else {opponentTurn();}
} else {
var noUsableItemP = $("<p id='noUsableItemP'>You have no usable items. Select another command.</p>");
$battleCommandPromptDiv.empty();
$battleCommandPromptDiv.append(noUsableItemP);
}
}
});
function opponentTurn() {
var c = Math.round(Math.random() * 10);
if (c > 5) {
opponent.attack(opponent.Attack, opponent.Luck, player.Defense);
if (player.Items.hasOwnProperty('shieldCharm')) {
if (player.Items.shieldCharm.active) {
var d = 0;
player.Items.shieldCharm.active = false;
} else {
var d = opponent.attackDamage;
}
} else {
var d = opponent.attackDamage;
}
player.currentHealth -= d;
$("#playersHealth").text("Your Health: " + player.currentHealth + "/" + player.totalHealth);
if (d === 0) {
$battleOutputBox.append("<p class='right'>You have blocked the attack.</p>");
} else {
$battleOutputBox.append("<p class='right'>" + d + " damage has been inflicted upon you.</p>");
scroll($battleOutputBox);
}
} else {
opponent.defend();
$battleOutputBox.append("<p class='right'>" + opponent.Name + " has doubled his defense for one turn.</p>");
}
if (player.DefenseDoubled === true) {
player.undefend();
}
if (player.currentHealth <= 0) {
postBattle(opponent);
}
}
function Poison() {
opponent.currentHealth -= 1;
$("#opponentsHealth").text("Enemy Health: " + opponent.currentHealth + "/" + opponent.Health);
$battleOutputBox.append("<p> " + opponent.Name + " was hurt by poison.</p>");
scroll($battleOutputBox);
$("#opponentStatus").empty();
$("#opponentStatus").append("<p style='color: green;' id='status'>Poisoned</p>");
}
function Burn() {
opponent.currentHealth -= 1;
$("#opponentsHealth").text("Enemy Health: " + opponent.currentHealth + "/" + opponent.Health);
$battleOutputBox.append("<p> " + opponent.Name + " was hurt by burn.</p>");
scroll($battleOutputBox);
$("#opponentStatus").empty();
$("#opponentStatus").append("<p style='color: red;' id='status'>Burned</p>");
}
function Freeze() {
opponent.currentHealth -= 1;
$("#opponentsHealth").text("Enemy Health: " + opponent.currentHealth + "/" + opponent.Health);
$battleOutputBox.append("<p> " + opponent.Name + " was hurt by freeze.</p>");
scroll($battleOutputBox);
$("#opponentStatus").empty();
$("#opponentStatus").append("<p style='color: blue;' id='status'>Frozen</p>");
}
}
function postBattle(opponentBattled) {
if (player.Win === true) {
addToValue(1);
inMaze = distance > 5 ? true : false;
$battleOutputBox.append("<p>You have won! You have gained " + player.EXPGainedCalculation(opponentBattled.Level, player.currentHealth, player.totalHealth) + " EXP. You need " + player.EXPNeededCalculation(player.Level) + " EXP to level up.</p>");
$battleOutputBox.append("<p>Click Yes to continue.</p>");
scroll($battleOutputBox);
player.Win = false;
battleInProgress = false;
} else {
$battleOutputBox.append('<p>You have fainted. Refresh to start over.</p>');
// Fix to restart quest
}
}
var e2 = new opponent(1, "Snake", "Rattler");
inMaze = false;
battle(e2);
В вашей battle
функции вы привязываетесь к обработчикам кликов. Эти обработчики никогда не сбрасываются. Если вы снова вызовете battle
, вы привяжете дополнительные обработчики, вы не замените их. В результате у вас теперь есть 2 набора обработчиков, один со старым opponent
и один с новым. Оба будут стрелять.
Для приложений с одной страницей очень рекомендуется использовать:
$(selector").off("click").on("click", function(){/* handler */});
В противном случае вы связываете несколько событий с одним и тем же элементом.
off
илиoff
unbind
.