1
\$\begingroup\$

I found this question with a really amazing answer How do I implement branching dialogue in javascript?

Unfortunately I can't seem to understand how to get this to work since the code posted isn't complete.

I've gotten my script to print out everything up to the decisions the player has to make, but I just can't understand how to feed the answer back into the script and give the player back the appropriate response.

Here's what I have so far

var current_step;

var story = [
  { m: "Hi!" },
  { m: "This is my new game." },
  { question: "Do you like it?", answers: [
    { m: "yes", next: "like_yes" },
    { m: "no", next: "like_no" },
  ] },
  { label: "like_yes", m: "I am happy you like my game!", next: "like_end" },
  { label: "like_no", m: "You made me sad!", next: "like_end" },
  { label: "like_end" },
  { m: "OK, let's change the topic" }
];

function execute_game() {
  var current_line = 0;
  while (current_line < story.length) {

    current_step = story[current_line];

    if (undefined !== current_step.m) {

      display_message(current_step.m);

      if (undefined !== current_step.next) {

        current_line = find_label(current_step.next);

      } else {

        current_line = current_line + 1;

      }

    } else if (undefined !== current_step.question) {

      display_message(current_step.question);
      display_answers(current_step.answers);
      return;

      // display the question: current_step.question
      // display the answers: current_step.answers
      // choose an answer
      // and change current_line accordingly

    }
  }
}

function display_message(varStore) {
    document.getElementById("container").innerHTML += varStore + "<br>";
}

function display_answers(varStore) {
    for (i = 0; i < varStore.length; i++) {
        document.getElementById("container").innerHTML += "<a href='" + varStore[i].next + "'>" + varStore[i].m + "</a><br>";
    }
}

What do I need to do from here?

\$\endgroup\$
  • 1
    \$\begingroup\$ It's not clear from your question where exactly your sourcecode stops doing what you want it to do. I would suspect it's the part where you create the href attribute of the links in display_answers, because those seem to result in links to other documents, which doesn't seem right to me. Is that correct? \$\endgroup\$ – Philipp Aug 2 '17 at 17:49
  • \$\begingroup\$ My sourcecode stops after giving the player inputs, the ones you mentioned. I left those href tags as a placeholder since I hoped that would be how the player would input their response, I am aware that at the moment they don't point to anything \$\endgroup\$ – Eight Aug 2 '17 at 17:55
0
\$\begingroup\$

One option would be to use hashkey navigation.

Have the links point to href's beginning with a # followed by the label of the next line of dialog.

The original intended purpose of this syntax are links within a HTML document. But the fact that clicking on them does not trigger a page reload makes them very useful for Javascript single-page applications like yours. They trigger the window.onhashchange event, which can then check location.hash to get the href of the link the user clicked on.

Here is a little proof-of-concept consisting of a javascript snippet which must run on page load and a piece of HTML which uses it:

window.onhashchange = function() {
   alert("You clicked on " + location.hash);
}
<a href="#Answer1">Click!</a>
<a href="#Answer2">Click!</a>
<a href="#Answer3">Click!</a>

But hashkey links have a side-effect you should be aware of: They generate history-entries in the user's browser history. See what happens when you run the code snippet above, click on some of the links and then click your browser's back-button. The user can navigate back and forth in your story using their web browser.

Another option which doesn't have this side effect is to use click handlers instead of links.

Create a HTML node (I would recommend a <button>, but it works with anything that looks clickable) and then assign an .onclick event handler to it.

function display_answers(varStore) {
    var container = document.getElementById("container")
    varStore.forEach(function(answer) {
        var answerButton = document.createElement("button");
        button.innerHTML = answer.m;
        button.onclick = function() {
            goto(answer.next);
        }
        container.appendChild(button);
    });
}

Note that I am using the Array.prototype.forEach function instead of a for-loop. That's not just a stylistic choice. This pattern makes sure that the current value of the variable answer is captured when the new anonymous function is created which then gets assigned to the onclick-handler.

This code also calls a new function goto(label) which you will have to implement on your own. But that shouldn't be hard: it needs to do the same thing execute_game() does, just start from the given label and not from line 0.

\$\endgroup\$
  • \$\begingroup\$ This does seem to work, my only problem is that after I find the index of the answer the user inputs, I try to run execute_game again, but of course running that again resets the current_line I input with goto. This would mean that I would have to make a completely different function for every dialogue I want to have. \$\endgroup\$ – Eight Aug 2 '17 at 18:41
  • \$\begingroup\$ Actually nevermind I think I found a solution for that problem. Thank you for your help! \$\endgroup\$ – Eight Aug 2 '17 at 18:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.