1

I'm making something like a text adventure game in Javascript, in a browser.

I've made almost all of it except the bit of logic that actually handles user input and the programme's response to said input. Currently, I'm a bit stumped on the best way to go about this.

My current idea is a recursive switch function:

mainLoop("Introduction");

function mainLoop(section) {
    switch(section) {
        case "Introduction":
            // Do stuff with the introductory scene
            // Await input
            mainLoop("Gather supplies");
            break;

        case "Gather Supplies":
            // Do stuff
            mainLoop("Make a decision");
            break;

        case "Make a decision":
            // Do stuff
            // Await decision (userDecision)
            if(userDecision == "Left") {
                mainLoop("Ending 1");
            } else {
                mainLoop("Ending 2");
            }
            break;

        case "Ending 1":
            // Do stuff
            break;

        case "Ending 2":
            // Do stuff
            break;
    }
}

My issue is that I have no idea how to await user input.

I've considered having a while loop run forever and only progress when it receives a signal from some handleUserInput(), but as I understand it, that would take up the whole thread - I couldn't run another secondaryLoop() with its own whiles alongside the mainLoop().

What's the best way to go about this?

EDIT: I should specify that detecting the input itself is already set up. The user types their sentence/command, it's passed to handleUserInput() which (in this example) would then generate a string corresponding to the relevant case in the mainloop. If I were to not use this technique, then handleUserInput() would do whatever the mainloop requires it to do.

snazzybouche
  • 2,241
  • 3
  • 21
  • 51
  • Is the app running in node or web browser? – phuzi Jul 18 '18 at 17:32
  • @phuzi It's in a web browser. – snazzybouche Jul 18 '18 at 17:33
  • 1
    what about eventlisteners for key events? instead of infinite loops, just wait for the next mouse or key click? – Doug Jul 18 '18 at 17:34
  • in that case you'll need to register event handlers on whatever input controls you have – phuzi Jul 18 '18 at 17:34
  • event listener on input field, so you would run `mainLoop(section)` on submit – Georgy Jul 18 '18 at 17:34
  • You could consider using a button, when the user clicks the button it submits the text they've entered. – Woohoojin Jul 18 '18 at 17:35
  • Possible duplicate of [Simplest way to detect keypresses in javascript](https://stackoverflow.com/questions/16089421/simplest-way-to-detect-keypresses-in-javascript) – Heretic Monkey Jul 18 '18 at 17:35
  • Say I were to run `mainLoop("Make a decision")` from the submit - would I then need to assign a different `case` to each choice? – snazzybouche Jul 18 '18 at 17:36
  • 6
    Your thinking about this wrong. You want your code to event-oriented if you want your code to something when an event happens. So instead of having a main loop, JavaScript is already set up to be event driven with the DOM through event listeners. It already has an event loop. – Andrew Li Jul 18 '18 at 17:36
  • its not as simple as event listener...because you need some type of game loop...and consistent behavior across computers and browsers....id imagine there's a framework out there for games in javascript – Ctznkane525 Jul 18 '18 at 17:38
  • Since your function is recursive already, it is perfectly suited for callback style. `case "Make a decision": onNextInput(userDecision => { … mainLoop(…); … }); break;` – Bergi Jul 18 '18 at 17:44
  • @Bergi: This seems to be the sort of thing I'm looking for - how would I define `onNextInput()`? It seems the contents of that function would answer my question – snazzybouche Jul 18 '18 at 17:47
  • @snazzybouche You said "*detecting the input itself is already set up. The user types their sentence/command, it's passed to …*". This should happen in `onNextInput` and call the callback argument. It probably outputs some text and installs event listeners on buttons or something, I don't know - can you show us what you are doing? – Bergi Jul 18 '18 at 17:53

1 Answers1

0

Self-answer.

I eventually worked out how to do this, and it was a lot simpler than I expected.

I began by passing the case arguments to a function that provided those options to the user. Where input from the user was not required, I bypassed this step, and called mainLoop as above with the next case.

mainLoop("Introduction");

function mainLoop(section) {
    switch(section) {
        case "Introduction":
            // Do stuff with the introductory scene
            presentOptionsToUser(["Gather supplies"]);
            break;

        case "Gather Supplies":
            // Do stuff
            mainLoop("Make a decision");
            break;

        case "Make a decision":
            // Do stuff
            presentOptionsToUser(["Ending 1","Ending 2"]);
            break;

        case "Ending 1":
            // Do stuff
            break;

        case "Ending 2":
            // Do stuff
            break;
    }
}

presentOptionsToUser takes the array of possible options and creates buttons for the user to press (or some other form of input). These buttons have mainLoop functions associated with them - for example, mainLoop("Ending 1").

In this way, the recursive loop is maintained, but is broken up by user input.

snazzybouche
  • 2,241
  • 3
  • 21
  • 51