Constant Updating

Many programs need to either be able to react to user input or be able to change their own state continuously after starting. For such a requirement we must find a way to allow the code you write to re-run itself at regular intervals for indefinite periods of time. Where might you use such an approach?

A web site with complex animation may need code that runs repeatedly to control that animation even after the page has been loaded would also require constantly running code. Imagine a weather web site where an image of clouds appear to move in the background. Not only does the image of the cloud have to constantly be moving but once it gets to the edge of the screen it needs to be placed back at its starting location so that the animation can continue to be seen. This movement and regular reseting of position is not something that can be done with simple CSS and would require JavaScript of some kind.

A web-based game for one, no matter how simple, needs to be able to react to user input so that the player can actually "play" the game. To know when the player is inputting commands via a keyboard or mouse the program must be constantly listening for such input. Computer programs can not simply "wake up" when the interface hardware is used. Even in cases where a game has a player-controlled character you have to consider what happens when the user is not giving their on screen avatar a command. There may be monsters within the game that need to move on their own as well regardless of player input. This kind of artificial intelligence would require a constantly updating program.

Whatever your purpose may be, how exactly would you go about creating such a state? Essentially what you want to do to create constantly updating logic is to create a "loop" of logic. But this isn't the kind of loop you would apply to an array. This "loop" is simply logic that has the ability to be called multiple times in a row.

One single call to update your program can be referred to as just that - your "update loop".

Generally you do not want to call code as quickly as the computer can possibly do it. Light programs can be updated hundreds, if not thousands of times on a fast computer, which would be a huge waste. For any program that makes use of real time graphics you typically don't need to exceed 60 updates per seconds since this is the refresh rate of the majority of monitors on the market today. Any update rate higher than that would simply result in logic being updated without the result actually being drawn to the screen.

There are two main ways in which we'll go over how to create a constantly updating program. The first will make use of a inherent JavaScript Timer method, the second will make use of a listener.

setTimeout & setInterval

In JavaScript there are two inherent functions that can be used to run, and then repeatedly re-run a single function, "setTimeout & setInterval". Both will take the name of the function you wish to repeat and the amount of time that the program will wait before calling that function as function arguments.

There are two important things to remember about the arguments.

  • The name of the function used must NOT have parenthesis as this will just be the same as calling the function.
  • The time format is measured in milliseconds. This means that if you want a time of 1 second that you'll actually need to use 1000.

setTimeout

"setTimeout" is useful for cases where you want a delayed implementation that only happens once. For instance...


setTimeout( func, 3000);

function func(){
    // Code that will run 
	// after 3 seconds.    
}

If run this code will wait 3 second before running the function "func".

So if "setTimeout" only calls a function once then how can we use it to create a constantly run function? Like so...


func();
function func(){
    // Code that runs as 
	// soon as it is called.

    // Set a timer to call 
	// this code again.
    setTimeout( func, 3000); 
}

With the code above we call the function once manually and the call "setTimeout" from within the function itself. This creates an endless loop where, after the function finished with its normal code, it sets a timer for itself to be called again after 3 seconds.

The problem with "setTimeout" is that it does not take the time to execute your code into account. This means that if you do place it at the end of a long function with many, many instructions then the time your PC takes to run that code will be ADDED onto the time defined by "setTimeout".

So if for one loop your program does what it need to do in 1 second, but for the next loop it takes two seconds, and your "setTimeout" argument is 3 seconds then the first loop calculation will take a total of 4 seconds while the seconds loop calculation will take 5 seconds. In other words "setTimout" does not ensure regular intervals of code execution.

setInterval

Our alternative option is "setInterval". This function works in much the same way but instead of having to be called at the end of the update function can be defined once and simply calls the function on its own.

Let's look at one particular use of this method. In this case we'll make a simple clock that will appear on the client computers page.



Your current time, in hours, minutes, and seconds...
TIME


/*
With one line of code we create a setInterval object and give it two parameters
to use.  The name of the function and the time between calls to that function.

In this particular example we only need the clock to update once a second, so we
can set the update time to 1000 milliseconds, or 1 whole second.
*/

var update_loop = setInterval(Main, 1000);

/*
Then we call the main update function once to begin with.  This is because the
"setInterval" method calls the defined function AFTER the amount of time you've
entered as the second argument.  That means that if we set it to a time of one
second then the displayed information will not actually be displayed for a full
second.  It's not much but we want the clock in this example to display as soon
as the page is loaded.
*/

Main();

// Now we can write out our main update function.

function Main(){    

    // Thankfully JavaScript has an inherent time object we can use.
    // It does need to be called every time you want an update value however.
    var time = new Date();

    // The "Date" method has predefined methods of its own.  These three for
    // instance will return hours, minutes, and seconds as you might guess.
    var hours = time.getHours();
    var minutes = time.getMinutes();
    var seconds = time.getSeconds();

    // We can then reference these values to create our clock as the inner
    // html of any div we choose.
    document.getElementById("demo").innerHTML = hours + ':' + minutes + ':' + seconds;

}

As you might guess. Now that we have a single function that is constantly being updated at regular intervals we can use that one function to branch out to any number of queries, tests, actions, and reactions.

Update Architecture

Of course most programs will need more functionality then to simply count numbers on screen. Especially in a web based game you need to be mindful of how all active (and inactive) objects are organized so that you can access them as easily an efficiently as possible.

Really the vast majority of complexity in any given program will be "where" you keep your variables on top of what order they come in. If a single piece of information needs to be used by multiple functions then it will need to be placed outside of those functions, and for the sake of readability the functions themselves should be listed in an order of use.

At this time the code below is NOT an operable game. It is merely an example how what the layout of a game's code might look like.



// If we want to make use of mouse position then we need to
// keep variables for it of course.

var mouse_x;
var mouse_y;

// If we are making a game we'll want to keep track of our
// individual components like enemies, projectiles, and / or
// powerups within lists.

var enemies = [];

var projectiles = [];

var coins = [];

// While the game / program is running we of course need to 
// keep track of how hardware interfaces are being used.

var key_up = false;
var key_down = false;
var key_left = false;
var key_right = false;

// Now when the program runs there may be default values and
// objects that need to be created first before we can run
// our regular logic on them.  For instance if we want to 
// make a list of enemies then we don't need to create each
// one one at a time - we can do it in an initialization
// function.

Init();

function Init(){
    // Populate the "enemies" list with a series of 
    // individual enemy objects which are all given the same
    // properties to read and write to.
    for( i = 0; i < 10; i++ ){
        var new_enemy = { active : true,
                          firing : 2,
                          worth  : 10 };
    }

    // The above "enemies" array now holds ten copies of the
    // same object we've written within the Init() funciton.

    // We can then do similar operations for any list that
    // needs to be populated with pre-made objects at 
    // runtime.
}

// Listeners to collect info about interfaces.
document.addEventListener("keydown", key_down);
document.addEventListener("keyup", key_up);

// Start the main loop.
var update_loop = setInterval(Main, 16);

function Main(){    
    
    // Update all components added to the main list.
    for ( var i = 0; i < list_update.length; i++ ){
        
        list_update[i]();
        
    }
    
    // Rest mouse_click after other code that might need it
    // has used it.
    if ( mouse_click ){
        mouse_click = false;
    }

    for( i = 0; i < enemies.length; i++ ){
        // Here we can run logic on all of the enemy objects
        // within the "enemies" array to make them move, 
        // shoot, die, or whatever they may need to do.
    }
    
    // A similar loop can be run for all other arrays as 
    // well.

    // After all logic has been run for our program we don't
    // need to do anything else.  Since we invoked 
    // "setInterval" we don't need to call the function
    // again ourselves - it will be called by the variable
    // we made at the beginning of this section 
    // automatically.
}

// Whether or not you want "helper" functions like the ones
// you see below to appear above or below in your JavaScript
// is typically inconsequential.  In other languages like
// C++ you would declare ALL functions at the beginning of
// your code but here that is not required.

function key_down(){
    // Here is where we'd check for all the key presses we
    // need to for our program.
}
function key_up(){
    // Here is where we'd check for all the key releases we
    // need to for our program.
}