JavaScript состояний и заявлений - PullRequest
1 голос
/ 04 апреля 2020

Извините за заголовок, я не мог придумать правильный заголовок в отношении моей проблемы.

Так что в настоящее время у меня есть функциональный код, который работает нормально, но у меня есть эта небольшая проблема, которую я не могу решить.

По сути, я добавляю действие, скажем, на север, и затем появится текст, говорящий, что вы входите в церковь, вы хотите исследовать? И тогда вы получаете два варианта: Да и Нет.

Если вы выбрали да, будет отображаться текст, говорящий о том, что вы вошли в церковь и, если коротко, вы избежите почти смертельного опыта в качестве игрока

Если вы выбрали нет и отступили, вам будет сказано, что вы благополучно отступили от церкви. Но проблема в том, что после того, как я выбрал вариант «да» или «нет» для этого экземпляра, я не могу добавить что-либо еще в поле ввода, чтобы продолжить свои действия на go на юг, запад, восток или даже на север снова. Вместо этого ничего не происходит. Я хотел бы, чтобы после того, как игрок получил сообщение «Вы благополучно отступили от церкви», вместо того, чтобы зайти в тупик ограничения по типу, поле ввода не ограничено и обычно функционирует подобно этому. сделал, прежде чем вы решили войти в церковь. Я надеюсь, вы понимаете, о чем я. Если вы этого не сделаете, просто введите это в поле ввода: -North -Yes -Retreat

, а затем попробуйте ввести действие после этого, например, "Север". Ничего не произошло. То, что я хотел бы случиться, это способность продолжать двигаться в любом направлении, выбранном игроком.

Вот код:

...

        else if (newInput == "North") {
            textInput = "you went to the Abandoned Church. Do you explore?";
            state = "sites"
            document.getElementById("message").innerHTML = textInput;
        }

    } else if (state == "sites") {
        // Handle commands when game state is in "store"
        if (newInput == "No") {
        textInput = "You decided not to explore the church";
            state = "sites"
            document.getElementById("message").innerHTML = textInput;


        } else if (newInput == "Yes") {
            textInput = "You decided to explore the church and found and found that there were two zombies roaming around. They haven't noticed you. Do you still stay or retreat?";
            state = "zombies"
            document.getElementById("message").innerHTML = textInput;
        } else if (newInput == "No") {
            // Change the state to something else
        }

    } else if (state == "zombies") {
        // Handle commands when game state is in "dragon"

        if (newInput == "Stay And Explore") {
            textInput = "You decided to stay but it didn't take long for the zombies to notice you. Right in the nick of time, you managed to escape, shutting the doors behind you.";
            document.getElementById("message").innerHTML = textInput;
        } else if (newInput == "Retreat") {
            textInput = "You retreated the church safely. Where do you go now?";
            document.getElementById("message").innerHTML = textInput;
        }
        if (newInput = "Retreat") {
          document.getElementById("message").innerHTML = textInput;
          //UNDEFINED! <--When I type North after Retreat, it comes as Undefined, I don't know if I was close to coming to a solution in what I wanted which was to take the player back to the action they were on before which was North and are free to change their action and to head to any other location.

        }

    }
}

.. .

Ответы [ 2 ]

0 голосов
/ 04 апреля 2020

Когда вы отступаете от церкви, вы не устанавливаете переменную состояния в ее первоначальное значение («init»). Вот почему ввод "Север" не имеет никакого эффекта; он все еще находится в состоянии "зомби", и в зомби нет опции "Север" else-if.

Другая возможная проблема с вашим кодом состоит в том, что вы не выходите из функции после отображения сообщения. Например, после того, как вы введете «Да» в состоянии «сайты», состояние изменится на «зомби», и весь код в «зомби», в противном случае также будет выполнен, - это не то, что вы хотите, как если бы Состояние "зомби" имеет "Да", оно также будет выполнено. Вы должны вернуться после отображения сообщения. Кроме того, рассмотрите возможность использования оператора switch, так как они больше подходят для этого типа потока.

В более общей заметке написание длинной цепочки оператора else-if может быстро привести к перегрузке. Рассмотрим реализацию конечного автомата. Например, создайте объект для каждого состояния с массивом возможных команд, сообщениями для каждой команды и следующим состоянием, в которое он вас переводит.

let states = {
  "sites": {  
    commands: [
      {
        input: "yes",
        msg: "You decided to explore the church and found and found that there were two zombies roaming around. They haven't noticed you. Do you still stay or retreat?",
        next: "zombies"
      }
     ]
  },
  "zombies": {
    commands: [
      {
        input: "retreat",
        msg: "You retreated the church safely. Where do you go now?",
        next: "init"
      }
    ]
  }
}

let state = 'sites'

// just for illustration
function button() {
  let command = states[state].commands.find(command => command.input = newInput);
  
  if (typeof command === 'undefined') {
    document.getElementById("message").innerHTML = `${newInput} is not a valid command`;
    return;
  }
  
  document.getElementById("message").innerHTML = command.msg;
  state = command.next;
}

Таким образом, вы можете сделать свою игру более масштабируемой.

0 голосов
/ 04 апреля 2020

для начала:

const inSelect =  document.getElementById('select-input')
  ,   btGo     =  document.getElementById('bt-go')
  ,   message  =  document.getElementById('message')
  ,   stateText =
        { 'init': { 'Help1': { next:'init', txt:'[Page 1 of 2. Type \'Help2\' for page 2] Commands you....' }
                  , 'Help2': { next:'sites', txt:'[Page 2 of 2] Commands you can use: <li>North One More</li><li ....' }
                  , 'South': { next:'sites', txt:'You went to abandoned city street 3' }
                  , 'South Again': { next:'sites', txt:'You went to abandoned city street 3' }
                  }
        , 'sites': { 'No': { next:'sites', txt:'You decided not to explore the church' }
                   , 'Yes': { next:'zombies', txt:'You decided to explore the church and found .......' }
                  }
        }


var state = 'init';

makeInSelect(state)

function makeInSelect( newState )
  {
  inSelect.innerHTML = ''
  for (let inp of Object.keys(stateText[newState]) )
    {
    inSelect.add(new Option(inp,inp)) 
    }
  }

btGo.onclick=_=>
  {
  let nextCase = stateText[state][inSelect.value]

  state = nextCase.next
  message.innerHTML = nextCase.txt

  makeInSelect(state)
  }
<div id="message">...</div>

<select   id="select-input"></select>

<button id="bt-go"> GO </button>
...