Search code examples
htmlalgorithmgame-physics

Position of an object 1 second ago, and not 30 gameloops ago


I'm designing a game using HTML5 though the question i'm about to ask is not dependent on the technology used. Here is a WIP: http://lajili.com/fierysnake

Looks fine, but I have a major problem: the vertical speed of the snake is factor of the power of your computer/smartphone. And I need to control exactly that speed, so the snake can make 90° between each turn, and synchronize it with the speed of the tunnel. As you know, when you move a gameobject in a game, you correct his speed using the "delta-time", that is to say, the timelapse from the last gameloop. And that works fine for the head. But the second bodypart is dependant on the head to move, because it is "where the head was x frame ago". but the position of the head x frames ago is dependant on the delta time of x frames ago. And the third body part is dependant on the delta time x*2 frames ago etc. etc. But the major problem is how to calculate "x frames ago". You see, depending on the computing power of the machine, since 3 seconds ago, 60 gameloops or 90 gameloops could have been called. I need a way to tell "the position '1 second ago' and not '30 frames ago' because that may not be correct. But I don't see how to do that.


Solution

  • You have to keep track of the position of the "head" for the last couple of seconds. If the head only moves to the left or right, it's enough to record its new speed in a single dimension when the direction was changed. Something like the following JSON array:

    [
        {
            speed: 2.5,
            time:  5.321
        }, {
            speed: -2.5,
            time:  4.284
        }, {
            speed: 2.5,
            time:  3.252
        }
        // ...
    ]
    

    If you know the current position and current time, you can compute all previous positions of the "head". But things will be easier (and more accurate since you're dealing with floating point numbers) if you also record the position when a direction change occurred:

    [
        {
            speed:    2.5,
            time:     5.321,
            position: 1.072
        }, {
            speed:    -2.5,
            time:     4.284,
            position: 11.782
        }, {
            speed:    2.5,
            time:     3.252,
            position: 3.652
        }
        // ...
    ]
    

    With this information, you only have to find the right segment for a moment in the past and then you can interpolate the position. You only have to keep records for a certain period and can delete them if they're older to avoid an ever growing queue.