基于简单文本的角色扮演游戏中的随机怪物生成器

Random Monster Generator in simple Text Based RPG

我正在尝试创建一个基于文本的角色扮演游戏,以将我学到的知识付诸实践 javascript。我尝试了两种方法,一种有效,另一种无效,我想知道为什么。

在第一个中,我创建了一个对象 "monster",它使用一种方法来设置每个怪物的所有属性(生命值、攻击点等)。这个问题是我必须一个一个地写属性,这让代码对我来说太长了。

/* Write JavaScript here */
/* Write JavaScript here */
$(document).ready(function() {

 var hero = {
  hitPoints: 13,
  armorClass: 10,
  attackBonus: 1,
  weaponDamage: 7,
  heroStats: function() {
   return "Hero" + "<br/>" +
    "Hit Points: " + this.hitPoints + "<br/>" +
    "Armor Class: " + this.armorClass + "<br/>" +
    "Attack Bonus: " + this.attackBonus + "<br/>" +
    "Weapon Damage: " + this.weaponDamage;
  },
  alive: true
 };

 var monster = {
  name: "",
  hitPoints: 0,
  armorClass: 0,
  attackBonus: 0,
  weaponDamage: 0,
  monsterStats: function() {
   return this.name + "<br/>" +
    "Hit Points: " + this.hitPoints + "<br/>" +
    "Armor Class: " + this.armorClass + "<br/>" +
    "Attack Bonus: " + this.attackBonus + "<br/>" +
    "Weapon Damage: " + this.weaponDamage;
  },
  monsterSelected: false,
  selectMonster: function() {
   if (this.monsterSelected === false) {
    switch (Math.floor(Math.random() * 2) + 1) {
     case 1:
      this.name = "Werewolf";
      this.hitPoints = 20;
      this.armorClass = 8;
      this.attackBonus = 4;
      this.weaponDamage = 3;
      this.monsterSelected = true;
      break;
     case 2:
      this.name = "Goblin";
      this.hitPoints = 15;
      this.armorClass = 10;
      this.attackBonus = 4;
      this.weaponDamage = 3;
      this.monsterSelected = true;
      break;
    }
   }
  },
  alive: true
 };

 monster.selectMonster();
 $(".hero_info").html(hero.heroStats());
 $(".monster_info").html(monster.monsterStats());

 $("button").click(function() {
  battle(monster);
 });



 function battle(actualmonster) {
  if (actualmonster.alive === false) {
   actualmonster.monsterSelected = false;
   actualmonster.selectMonster();
   $(".monster_info").html(actualmonster.monsterStats());
   $(".battle_info").html("");
   actualmonster.alive = true;
  } else {
   var d20 = Math.floor(Math.random() * 20) + 1;
   var d_wp = Math.floor(Math.random() * hero.weaponDamage) + 1;
   if (d20 + hero.attackBonus > actualmonster.armorClass) {
    $(".battle_info").html("You attack!: d20+" + hero.attackBonus + ": " + (d20 + hero.attackBonus) + " vs AC " + actualmonster.armorClass + "<br/>" + "You hit!: d" + hero.weaponDamage + ": " + d_wp);
    actualmonster.hitPoints = actualmonster.hitPoints - d_wp;
    $(".monster_info").html(actualmonster.monsterStats());
   } else {
    $(".battle_info").html("You miss!: d20+" + hero.attackBonus + ": " + (d20 + hero.attackBonus) + " vs AC " + actualmonster.armorClass);
   }
   if (actualmonster.hitPoints <= 0) {
    actualmonster.hitPoints = 0;
    $(".monster_info").html(actualmonster.monsterStats());
    $(".battle_info").html("You killed the monster!");
    actualmonster.alive = false;
   } else {
    var d20_m = Math.floor(Math.random() * 20) + 1;
    var d_wp_m = Math.floor(Math.random() * monster.weaponDamage) + 1;
    if (d20_m + actualmonster.attackBonus > hero.armorClass) {
     $(".battle_info").append("<br/>Monster attacks you!: d20+" + actualmonster.attackBonus + ": " + (d20_m + actualmonster.attackBonus) + " vs AC " + hero.armorClass + "<br/>" + "Monster hits you!: d" + actualmonster.weaponDamage + ": " + d_wp_m);
     hero.hitPoints = hero.hitPoints - d_wp_m;
     $(".hero_info").html(hero.heroStats());
    } else {
     $(".battle_info").append("<br/>Monster miss!: d20+" + hero.attackBonus + ": " + (d20_m + monster.attackBonus) + " vs AC " + hero.armorClass);
    }
   }
  }
 }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<p class="monster_info"></p>
  <p class="battle_info"></p>
  <p class="hero_info"></p>
  <button type="button">Attack</button>
  </body>

在第二个中,我创建了一个构造函数,而不是创建对象 "monster",因此我可以用更短和更简单的方式定义怪物(例如:var phantom = new monster (prop1, prop2, prop3...)).当我为每场战斗尝试 select 一个随机怪物时,问题就来了。我尝试了很多东西,但问题仍然存在:如果为 select 怪物创建一个随机函数,则每次单击攻击按钮时都会出现这种情况,从而造成混乱。这让我发疯,我不知道该怎么办。有什么建议么?提前致谢。

$(document).ready(function() {

    var hero = {
        hitPoints: 13,
        armorClass: 10,
        attackBonus: 1,
        weaponDamage: 7,
        heroStats: function() {
            return "Hero" + "<br/>" +
                "Hit Points: " + this.hitPoints + "<br/>" +
                "Armor Class: " + this.armorClass + "<br/>" +
                "Attack Bonus: " + this.attackBonus + "<br/>" +
                "Weapon Damage: " + this.weaponDamage;
        },
        alive: true
    };

    function monster(name, hitpoints, armorclass, attackbonus, weapondamage) {
        this.name = name;
        this.hitPoints = hitpoints;
        this.armorClass = armorclass;
        this.attackBonus = attackbonus;
        this.weaponDamage = weapondamage;
        this.monsterStats = function() {
                return this.name + "<br/>" +
                    "Hit Points: " + this.hitPoints + "<br/>" +
                    "Armor Class: " + this.armorClass + "<br/>" +
                    "Attack Bonus: " + this.attackBonus + "<br/>" +
                    "Weapon Damage: " + this.weaponDamage;
            },
            this.selected = false;
        this.alive = true;
    }

    function selectMonster() {
        var werewolf = new monster("Werewolf", 5, 4, 4, 3);
        var goblin = new monster("Goblin", 15, 4, 4, 3);
        switch (Math.floor(Math.random() * 2) + 1) {
            case 1:
                if (werewolf.selected === false) {
                    werewolf.selected = false;
                    return werewolf;
                }
                break;
            case 2:
                if (goblin.selected === false) {
                    goblin.selected = false;
                    return goblin;
                }
                break;
        }
    }

    $(".hero_info").html(hero.heroStats());
    $(".monster_info").html(selectMonster().monsterStats());

    $("button").click(function() {
        battle(selectMonster());
    });



    function battle(actualmonster) {
        if (actualmonster.alive === false) {
            actualmonster.selected = false;
            actualmonster.selectMonster();
            $(".monster_info").html(actualmonster.monsterStats());
            $(".battle_info").html("");
            actualmonster.alive = true;
        } else {
            var d20 = Math.floor(Math.random() * 20) + 1;
            var d_wp = Math.floor(Math.random() * hero.weaponDamage) + 1;
            if (d20 + hero.attackBonus > actualmonster.armorClass) {
                $(".battle_info").html("You attack!: d20+" + hero.attackBonus + ": " + (d20 + hero.attackBonus) + " vs AC " + actualmonster.armorClass + "<br/>" + "You hit!: d" + hero.weaponDamage + ": " + d_wp);
                actualmonster.hitPoints = actualmonster.hitPoints - d_wp;
                $(".monster_info").html(actualmonster.monsterStats());
            } else {
                $(".battle_info").html("You miss!: d20+" + hero.attackBonus + ": " + (d20 + hero.attackBonus) + " vs AC " + actualmonster.armorClass);
            }
            if (actualmonster.hitPoints <= 0) {
                actualmonster.hitPoints = 0;
                $(".monster_info").html(actualmonster.monsterStats());
                $(".battle_info").html("You killed the monster!");
                actualmonster.alive = false;
            } else {
                var d20_m = Math.floor(Math.random() * 20) + 1;
                var d_wp_m = Math.floor(Math.random() * hero.weaponDamage) + 1;
                if (d20_m + actualmonster.attackBonus > hero.armorClass) {
                    $(".battle_info").append("<br/>Monster attacks you!: d20+" + actualmonster.attackBonus + ": " + (d20_m + actualmonster.attackBonus) + " vs AC " + hero.armorClass + "<br/>" + "Monster hits you!: d" + actualmonster.weaponDamage + ": " + d_wp_m);
                    hero.hitPoints = hero.hitPoints - d_wp_m;
                    $(".hero_info").html(hero.heroStats());
                } else {
                    $(".battle_info").append("<br/>Monster miss!: d20+" + hero.attackBonus + ": " + (d20_m + actualmonster.attackBonus) + " vs AC " + hero.armorClass);
                }
            }
        }
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="monster_info"></p>
  <p class="battle_info"></p>
  <p class="hero_info"></p>
  <button type="button">Attack</button>

在你的怪物构造函数中,你在你的 return 声明中做了一些你可能不想做的事情。当你有类似 return x + 1, foo = 3, bar = false 的东西时,表达式从左到右求值, 最后一个 是 returned。也就是说,您正在重新调整 this.alive 的状态,而不是 returning 构造函数中预期的 this

尝试重构您的代码以显式 return 您希望由构造函数创建的怪物对象,看看您是否仍然存在问题。通常,您希望 return 独立存在,以避免语法混乱。

第二种方法很好,但你用起来很奇怪。 selectMonster 将随机生成带有一些随机逻辑的怪物并调用 new monster。但是随后您无缘无故地多次调用 selectMonster()

您的代码应如下所示:

var current_monster = selectMonster(); // note that you already have function named monster
$(".monster_info").html(current_monster.monsterStats());

$("button").click(function() {
    battle(current_monster);
});

你也可以通过原型设计来定义你的怪物:

function Monster(name, hp, attack) {
    this.name = name;
    this.hp = hp;
    this.attack = attack;
    this.alive = true;
    // etc
}
Monster.prototype.monsterStats = function() {
    return this.name + "<br/>" +
        "Hit Points: " + this.hitPoints + "<br/>" +
        "Armor Class: " + this.armorClass + "<br/>" +
        "Attack Bonus: " + this.attackBonus + "<br/>" +
        "Weapon Damage: " + this.weaponDamage;
}

function Werewolf() {
    Monster.call(this, "werewolf", 5, 4); // call parent
}
Werewolf.prototype = new Monster();

function Goblin() {
    Monster.call(this, "goblin", 15, 3); // call parent
}
Goblin.prototype = new Monster();

var goblin = new Goblin();
console.log(goblin.hp); // 15
console.log(goblin.monsterStats()); // goblin <br /> etc..