Javascript l oop работает с первого раза, но работает с NaN второй раз без логики - PullRequest
0 голосов
/ 26 января 2020

Я занимаюсь разработкой игры javascript и изменяю значения из файла JSON через al oop. Однако l oop иногда заменяет значения, которые он должен изменить, на «NaN» и получает случайную букву из префиксного слова массива. Я пытался отлаживать значения и вводить фиксированные значения существ, но это не сделало меня мудрее.

Код работает в ПЕРВОЕ ВРЕМЯ RAN в JSFiddle: https://jsfiddle.net/ezwad5mL/2/, но каждый раз, когда вы запускаете его, он перезаписывает значения в l oop с помощью NaN и буквы. Я думаю, это потому, что функция random_int нуждается в 2 значениях, но она вводит только 1 во второй раз, когда вы ее запускаете, что как-то совпадает со значением предыдущего ввода (которое она изменила во втором для l oop). Я не понимаю, как этот код не сбрасывает 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)

Ответы [ 2 ]

3 голосов
/ 27 января 2020

Чтобы понять проблему, нам нужно понять, как работают массивы. Следующий пример может открыть вам глаза на проблему.

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"

1 голос
/ 27 января 2020

Я думаю, что объяснение Нико Грефа правильное. Чтобы это исправить, вы можете создать клон объекта и поместить его в storedDungeon.

storedDungeon.push({...randomObject})

Обратите внимание, что spread syntax не глубокий клон вашего объекта , Так что он работает только на первом уровне объекта, который должен соответствовать вашему текущему дизайну.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...