6

I'm writing a text-based game in javascript, and one of the main "features" is a input box which accepts a user input, and submits the input by a button tag. In my main game loop a call the button's onclick:

var game_u = new game_util();

                function Game_Main(){
                    while(active){
                        input = game_u.getText();
                        //p = new player();
                        active = false;
                    }
                }

                function game_util(){
                    this.getText = function(){
                        //The Submit button 
                        confirm_plr.onclick = function(){
                            //Input value
                            return player_in.value;
                        }
                    }
                } 

The problem with this way, though is that the while loop does not "wait" for the submit button to be clicked to get the input from the `game_u.getText(); function and continues on with the loop.

Is there a better way for me to do this, it is my first wack at a text-based game? I don't want to use the prompt method, because it breaks the immersion of the gameplay.

I'm also coming from Java, an object-oriented programming language, so that's why I use a while loop.

Any help is appreciated.

TheRailsRouter
  • 115
  • 1
  • 6
  • a `prompt` box, like an `alert` will pause execution – Sterling Archer Nov 13 '15 at 20:33
  • Possible duplicate of [Sleep in Javascript - delay between actions](http://stackoverflow.com/questions/758688/sleep-in-javascript-delay-between-actions) – Sterling Archer Nov 13 '15 at 20:34
  • Move game_u.getText() into a global variable when the button is clicked, and then "consume" this in the game loop by setting it back to blank when done reading it during one iteration of the game loop. That's one possibility. Note: persistent javascript loops are a bit unusual. – ebyrob Nov 13 '15 at 20:35
  • 3
    you might want to look at using callbacks – blueberryfields Nov 13 '15 at 20:35
  • Here's a few ways to get around the current lack of "await" in javascript...https://thomashunter.name/blog/the-long-road-to-asyncawait-in-javascript/ – Nikki9696 Nov 13 '15 at 20:36
  • 4
    You should not be using that `while` loop here in the first place – but rather embrace the fact that JavaScript is an event-driven language. – CBroe Nov 13 '15 at 20:39
  • @ebyrob But the button click will never occur ... – Teemu Nov 13 '15 at 20:42
  • Second for callbacks. You should pop the dialog to get input from the user - and set event handlers for the submit from that dialog. I would seriously reconsider the structure of your application as you are going to run into a lot of problems if it's entirely loop-driven. – Stan Shaw Nov 13 '15 at 20:43
  • If I shouldn't be using a while loop, what would replace it? – TheRailsRouter Nov 13 '15 at 20:43
  • I will look into callbacks, thank you. – TheRailsRouter Nov 13 '15 at 20:45
  • without knowing what you're trying to do, that's impossible to answer. But it should be event driven. User actions should trigger the execution of functions that interpret their input and update the display and/or prompt the user for more input. I don't understand why you have a while loop or what its purpose is, though, so like I said it's impossible to answer that question. – Stan Shaw Nov 13 '15 at 20:45
  • I came from Java so I have a Java mindset, that's why I used a while loop. – TheRailsRouter Nov 13 '15 at 20:46
  • @TheRailsRouter See my updated answer. Use an event listener. – Jonathan Lam Nov 13 '15 at 20:47
  • Your while loop should be providing some functionality that you couldn't easily get elsewhere. If you don't know why it's there, it's probably safe bet that it should be replaced. A loop is typically used when you want to continue executing a process until some condition is met (1000 iterations, or until a sum exceeds a threshold, etc.). – Stan Shaw Nov 13 '15 at 20:49
  • Also, OOP languages don't necessitate the use of while loops. Objectives do. I code almost entirely in C#/JS/SQL and I couldn't tell you the last time I needed a while loop. Out of curiosity, why do you think that your Java experience means that you should use while loops? – Stan Shaw Nov 13 '15 at 20:52
  • It's just the way I learned it, while loops certainly aren't necessary, I was just taught this way. – TheRailsRouter Nov 13 '15 at 20:54

3 Answers3

4

If you want to suspend with user input, a simple prompt() box will do.

Try this:

var input = prompt("Enter data here", "");

This will wait for input and store it into variable input.

See working example on JSFiddle.net.


AFAIK, synchronous JS is not possible, as according to this SO post:

JavaScript is asynchronous, you cannot "pauses" execution. Moreover, while javascript is running the entire user interface freezes, so the user cannot click the button.

As to your question,

If I shouldn't be using a while loop, what would replace it?

because JS is event driven, and you're trying to run code every time that button is clicked (and input is entered), just use a onclick handler.

So, rather than this:

while(active) {
    input = game_u.getText();
    p = new player();
    active = false;
}

You can do:

document.getElementById("button").addEventListener("click", function() {
    input = game_u.getText();
    p = new player();
    active = false;
});

This will run the code every time the button is clicked, essentially the same as what you're trying to do.

Community
  • 1
  • 1
Jonathan Lam
  • 16,831
  • 17
  • 68
  • 94
  • I'm trying to avoid the prompt method, since it breaks the immersion of my game. A white pop-up box is not what I'm trying to do, thanks anyways. – TheRailsRouter Nov 13 '15 at 20:41
2

One approach is to break the different stages of your game into functions corresponding to the different stages (rooms, levels etc.) which are called depending on the user's input; you will also need a variable that saves the game's current state (room in the example below).

(function Game() {
    var room = 1;
    document.getElementById('playerSubmit').addEventListener('click', function() {
        var playerInput = document.getElementById('playerInput').value;
        if (playerInput == "Go to room 2") {
            room = 2;
        }
        if (playerInput == "Go to room 1") {
            room = 1;
        }
        if (room == 1) {
            room1(playerInput);
        } else if (room == 2) {
            room2(playerInput);
        }
        document.getElementById('playerInput').value = '';
    });
    function room1(playerInput) {
        output('You are in the first room and entered the command ' + playerInput);
    }
    function room2(playerInput) {
        output("Now you're in room 2. Your command was " + playerInput);
    }
    function output(text) {
        document.getElementById('output').innerHTML += '<p>' + text + '</p>';
    }       
})();
#output {
    border: solid 1px blue;
    width: 500px;
    height: 400px;
    overflow: scroll;
}
label {
    display: block; margin-top: 1em;
}
<div id="output"></div>
<label for="playerInput">Player input</label>
<input id="playerInput" type="text" size=50 />
<input id="playerSubmit" type="button" value="Submit" />

http://jsfiddle.net/spjs8spp/2/

Stuart
  • 9,597
  • 1
  • 21
  • 30
1

You've gotten some great info in the commentary. An evented model might be ideal, but you can do persistent loops. I'm not as familiar with it, but HTML5 Canvas is just that. Maybe look into that some, since nobody else mentioned it yet.

HTDE
  • 487
  • 1
  • 4
  • 14