Question

I'm currently developing a small game for a class using Crafty, and our game requires the passage of time. To give context, it's a tamagotchi-like game where the player controls a creature and feeds it, grooms it, etc., when required, so we need to measure time for things such as "every five minutes the creature will be hungry" or "after a certain amount of time (say, 20 minutes) the creature will die of natural causes and the game will end". My problem is that I'm not sure what is the best way to go about this. Should I use setInterval? setTimeout? My own timer class? I don't know what's the most common solution for instances like these. So far I've tried the first two options without successful results.

I also tried looking for any crafy functions for time; and the closest I could find was Crafty.bind("EnterFrame", function() { ... }), so I could 'manipulate' time frame by frame, but this didn't work either. Thanks in advance.

Was it helpful?

Solution

When the game starts, get a timestamp with new Date().getTime(), and keep it in a variable. On regular intervals (you can use setInterval), compare that with the current timestamp, and act according to how much time has passed.

I suggest building an array with the timed events, and checking its elements from the timer callback. Something like this:

var startTime = new Date().getTime();

// List of timed events
// (times are in milliseconds)
var events = [
    { time: 5000, text: "do something after 5 secs"},
    { time: 10000, text: "do something after 10 secs"},
    { time: 20000, text: "do something after 20 secs"}
];

// Check for events every second
setInterval(function() {
    var timePassed = new Date().getTime() - startTime;
    console.log("passed: " + timePassed + " milliseconds");

    // Check all events
    for(var i=events.length-1; i>=0; i--) {

        // If an event has expired, remove it from the list,
        // (and do whatever tou need to do)
        if(events[i].time <= timePassed) {

            // log the event text to the console
            console.log(timePassed + "ms passed. " + events[i].text);

            // remove from array
            events.splice(i, 1);
        }
    }

}, 1000);

DEMO (open your browser console to see the output).

OTHER TIPS

Rather than use the single timestamp as in bfavartto's answer, you could expand that to set multiple, dynamic timestamps in a "time" array (or object) or even simply as individual variables and then update them as actions occur.

A simple version would be something like:

// Initialize the variables at the beginning of the game
var lifeStamp = new Date().getTime();
var foodStamp = lifeStamp ;
var groomStamp = lifeStamp ;

function feed() {

    /*** Do feed-realted stuff here ***/

    // reset the "feed" timestamp
    foodStamp = new Date().getTime();
}

function groom() {

    /*** Do groom-realted stuff ***/

    // reset the "groom" timestamp
    groomStamp = new Date().getTime();
}

That way, you could keep your intervals, but reset them by resetting the timestamps that your intervals compare against for different types of actions. At the same time, the "life" timestamp would stay the same, while the other ones changed.

Edit: Re-looking at bfavartto's answer, it looks like you would need to store off and "original" list of any action-specific events as well, so that, as you reset the timestamps, you could reset the actions that go with them.

Edit #2: One more thing . . . if you want these creatures to last past the current page load, you might want to look into using cookies or HTML5's LocalStorage to store these timestamps. That would allow you to (practically) use much longer intervals, as well as let users leave the page and come back to pick up where they left off (though, I'd imagine that there would be a considerable amount of other data that would need to be stored as well, in order to allow users to leave and come back).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top