【问题标题】:Javascript loop terminates partway through when accessing a prototype function访问原型函数时,Javascript 循环中途终止
【发布时间】:2019-12-12 19:06:29
【问题描述】:

我正在用 JavaScript 编写一场战斗。该程序有时会运行,有时不会。有时它会在抛出错误之前循环 5-6 次。

功能是玩家、武器、敌人和战斗模拟。 原型上的函数是 applyDamage、isAlive、attackWith、attack、createEnemies、createPlayers、run。

我正在练习使用原型,但我不太清楚如何使用它们。有 5 名玩家和 20 名敌人组成的阵列。

在一些循环迭代后出现此错误:

console.log("Your fighter is: " + myPlayer.name);
                                           ^

“TypeError: 无法读取未定义的属性‘名称’”

有时错误出现在代码的不同部分。我想在将玩家送入战斗之前检查玩家是否还活着。一旦他们死了,我不希望他们重返战场,所以我使用 Player.prototype 中定义的函数检查他们是否还活着。

    while (myPlayer.isAlive == false) {
      myPlayer = players[Math.ceil(Math.random() * 5)];
    }

我有时会遇到 TypeError: Cannot read property 'isAlive' of undefined.

你能帮我弄清楚这个原型的东西,如果我做得对吗?谢谢!!!

代码:

function Player(name, weapons) {
 // Each player has a name, an initial health of 10, an 
 // initial strength of 2, and an array of weapons objects
  this.name = name;
  this.health = 10;
  this.strength = 2;
  this.weapons = weapons;
}

// applyDamage deals damage to the Player - takes an integer 
// input and subtracts that from the player's health
Player.prototype.applyDamage = function(damage) {
  console.log(damage + " damage applied!");
  // Subtract damage received from the player's health
  this.health -= damage;
  console.log(this.name + "\'s health is now " + this.health);
};

// isAlive checks if the player's health is >0. Returns true 
// if it is and false if not.
Player.prototype.isAlive = function() {
  if (this.health > 0) {
    return true;
  } else {
    return false;
  }
};

// attackWith uses a random number between 7 and 0, selects 
// the weapon at that index, and returns the weapon
Player.prototype.attackWith = function() {
  let choice = Math.ceil(Math.random() * (7));
  return this.weapons[choice];
};


function Weapon(name) {
  // Each weapon has an assigned name and random damage level
  this.name = name;
  this.damage = Math.ceil(Math.random() * 5); 
  //random number between 1 and 5
}

// attack checks if the fighters are dead, then applies damage 
// based on strength and weapon
Weapon.prototype.attack = function(player, enemy) {
  while (player.isAlive && enemy.isAlive) {
    // Calculate actual damage = 
    // strength of player * damage value of weapon
    let actualDamage = player.strength * this.damage;
    console.log("\n" + player.name + " attacks " + enemy.name 
+ "!");

    // Call the applyDamage function of the Enemy object and 
    // pass the actual damage value calculated
    enemy.applyDamage(actualDamage);
    console.log("Enemy health is " + enemy.health);

    // Call the isAlive function of the Enemy object. If the 
    // enemy is dead, exit.
    // If the enemy is not dead, call the attack function and 
    // pass it the player object.
    if (enemy.isAlive) {
      console.log("\n" + enemy.name + " attacks " 
                  + player.name + "!");
      enemy.attack(player);
    } else {
      return "enemyDead";
    }
  }
};


function Enemy() {
  // The default enemy has a name of Enemy, health of 5, and 
// strength of 2
  this.name = "Enemy";
  this.health = 5;
  this.strength = 2;
}

// applyDamage takes an integer input and subtracts that from 
// the enemy's health
Enemy.prototype.applyDamage = function(damage) {
  console.log(this.name + " is hit with " + damage 
              + " damage.");
  this.health -= damage;
};

// isAlive checks if the enemy's health is greater than 0. 
// Returns true if it is and false if not.
Enemy.prototype.isAlive = function() {
  if (this.health > 0) {
    return true;
  } else {
    return false;
  }
};

// attack takes a player input and calls the applyDamage of 
// the player using enemy's strength as input
Enemy.prototype.attack = function(player) {
  //console.log("\n" + this.name + " attacks!");
  player.applyDamage(this.strength);
};

function BattleSimulation() {
  // The battle simulation has an array of players and enemies
  this.players = [];
  this.enemies = [];
}

// createEnemies uses a loop to create 20 Enemy instances and 
// populate the Enemies array property
BattleSimulation.prototype.createEnemies = function() {
  for (var i = 0; i < 20; i++) {
    this.enemies.push(new Enemy());
  }
};

// createPlayers creates 8 weapons objects and 5 player 
// instances.
BattleSimulation.prototype.createPlayers = function() {
  // Create 8 weapons objects in weaponsCache
  var w1 = new Weapon('Marshmallows');
  var w2 = new Weapon('Snowflakes');
  var w3 = new Weapon('The love you didn\'t get as a child');
  var w4 = new Weapon('Machine guns');
  var w5 = new Weapon('Paper cuts');
  var w6 = new Weapon('A really tough personal trainer');
  var w7 = new Weapon('Stepping on a lego');
  var w8 = new Weapon('Very short vampires');
  var weaponsCache = [w1, w2, w3, w4, w5, w6, w7, w8];

  // Create 5 player instances and add to the players array
  var p1 = new Player('Kate', weaponsCache);
  var p2 = new Player('Charming Male Companion', weaponsCache);
  var p3 = new Player('Iron Professor', weaponsCache);
  var p4 = new Player('Golden Army Captain', weaponsCache);
  var p5 = new Player('Lieutenant Hadrian', weaponsCache);
  this.players = [p1, p2, p3, p4, p5];
  return this.players;

};

// run the battle
BattleSimulation.prototype.run = function() {
  console.log("Simulating Battle");

  // Create enemies
  var enemies = this.createEnemies();

  // Create players
  var players = this.createPlayers();

  var enemyBodyCount = 0;
  var playerBodyCount = 0;

  // Until all the players are dead or all the enemies die
  do {
    // Select random player
    var myPlayer = players[Math.ceil(Math.random() * 5)];

    // Pick a new player if dead
    while (myPlayer.isAlive) {
      myPlayer = players[Math.ceil(Math.random() * 5)];
    }

        console.log("\nNew fight!");
    console.log("Your fighter is: " + myPlayer.name);

    // Select a random enemy
    var myEnemy = this.enemies[Math.ceil(Math.random() * 20)];

    // Check if the enemy selected is alive. Pick a new enemy if dead.
    while (myEnemy.isAlive==false) {
      myEnemy = this.enemies[Math.ceil(Math.random() * 20)];
    }

    console.log("Your enemy is: " + myEnemy.name + ", with " + myEnemy.health + " health");

    // Call the attackWith method on the player to get a weapon to attack with
    var myWeapon = myPlayer.attackWith();
    console.log("Your weapon is: " + myWeapon.name);

    // Call the attack method on the weapon and pass it the current player and current enemy
    var whosDead = myWeapon.attack(myPlayer, myEnemy);

    if (whosDead == "enemyDead") {
        enemyBodyCount++;
    } else {
        playerBodyCount++;
    }

  //  let enemyBodyCount = 0;
  // for (let i = 0; i < 20; i++) {
  //    if (enemies[i].isAlive <= 0) {
  //      enemyBodyCount++;
  //      console.log(enemyBodyCount);
  //    }
  //  }
  //    let playerBodyCount = 0;
  //   for (let i = 0; i < 5; i++) {
  //    if (this.players[i].isAlive <= 0) {
  //      console.log(players[i]);
  //      playerBodyCount++;
  //      console.log(playerBodyCount);
  //    }
  //  }*/

    if (playerBodyCount >= 6) {
      console.log("\nSorry, Scarlett Byte has defeated you and conquered the free world.");
    }
    if (enemyBodyCount >=20) {
      console.log("\nCongratulations, you have defeated Scarlett Byte");
    }
    else {
        continue;
    }
 } while (playerBodyCount < 6 || enemyBodyCount < 21);

  //console.log(players);
  //console.log(enemies);
};

// Test program
var simulator = new BattleSimulation();
simulator.run();

【问题讨论】:

  • Math.ceil(Math.random() * 5) 正在选择一个从 1 到 5 的数字。如果您想要一个介于 0 和 player.length - 1 之间的数字,请使用 Math.floor(Math.random() * players.length)

标签: javascript function loops prototype javascript-objects


【解决方案1】:

您是否在运行 this.createPlayers 后检查了您的玩家数组的值以确保它已被填充?错误似乎说不是。

【讨论】:

  • 哇,我想就是这样。我正在为代码的另一部分创建随机数 1-5 并重用该代码,忘记将其更改回 0-4。谢谢!!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-14
  • 1970-01-01
  • 2017-09-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多