我正在开发一个JavaScript游戏,并通过循环更改JSON文件中的值。但是,循环有时会用“ NaN”替换应更改的值,并从数组的前缀字中获取一个随机字母。我尝试调试这些值并放入固定的生物值,但这使我无所适从。
该代码在JSFiddle中的FIRST TIME RAN中起作用:https://jsfiddle.net/ezwad5mL/2/,但是每当您第二次运行它时,它都会用NaN和字母覆盖循环中的值。我认为这是因为函数random_int
需要2个值,但是在您第二次运行它时才输入1,这在某种程度上与先前输入(在第二个For循环中更改)相同。我不明白的是,如果第二次触发,此代码不会重置storedDungeon
。
我理解我所认为的问题,但是我不知道我写的东西有什么问题,为什么第一次没问题,但是第二次搞砸了。
function random_item(items){
return items[Math.floor(Math.random()*items.length)];
}
function random_int(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
var storedDungeon = []
const jsonCreatures = {
"easy": [
{ "name": "Scorchbird", "hp": [6,13], "prefix": ["Weak", "Small", "Young", "Wild"],
"damage": [1,5], "droprateCommon": [0,60], "droprateRare": [70, 90]},
{ "name": "Reanimated Corpse", "hp": [8,15], "prefix": ["Weak", "Festering"], "damage":
[3,5], "droprateCommon": [0,40], "droprateRare": [50, 80]}
]}
var randNumber = 2
for (let i = 0; i < randNumber; i++) {
let randomObject = random_item(jsonCreatures.easy)
storedDungeon.push(randomObject)
}
for (let o = 0; o < storedDungeon.length; o++) {
storedDungeon[o].hp = random_int(storedDungeon[o].hp[0], storedDungeon[o].hp[1])
storedDungeon[o].damage = random_int(storedDungeon[o].damage[0],storedDungeon[o].damage[1])
storedDungeon[o].prefix = random_item(storedDungeon[o].prefix)
}
console.log(storedDungeon)
要了解该问题,我们需要了解数组如何工作。下面的示例可能会引起您的注意。
const creatures = [
{
name: 'Scorchbird'
}
]
const dungeon = []
dungeon.push(creatures[0])
dungeon[0].name = 'Reference to the object!'
console.log(creatures)
// [
// {
// name: 'Reference to the object!'
// }
// ]
当我们向地牢数组中添加生物(对象)时>
dungeon.push(creatures[0])
我们实际上添加了对原始对象的引用,而不是其副本。
这意味着您这样做
storedDungeon[o].hp = random_int( storedDungeon[o].hp[0], storedDungeon[o].hp[1] )
您更改了原始生物的对象及其属性。
在这种情况下,将数组hp: [6, 13]
替换为随机数(单个!),例如hp: 8
当您的代码第二次运行时,现在有hp数组可以执行hp[0]
和hp[1]
,只有一个数字。这就是为什么函数random_int
返回NaN(不是数字)的原因。
与损害和前缀相同的效果。但是,由于前缀是字符串,因此random_item
函数将在此字符串中返回随机字符。这是因为可以像在数组中一样通过它们的索引访问字符串的字符:"im a string"[1] = "m"
我认为NicoGräf的解释是正确的。要解决此问题,您可以创建对象的克隆并将其推送到storedDungeon
。