基于简单文本的角色扮演游戏中的随机怪物生成器
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..
我正在尝试创建一个基于文本的角色扮演游戏,以将我学到的知识付诸实践 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..