1
\$\begingroup\$

I'm prototyping a 2d HTML5 game with similar interaction to Diablo II. (See an older post of mine describing the interaction here: How can I imitate interaction and movement in Diablo II?)

I just got the player click-to-move system working using the Bresenham algorithm but I can't figure out how to efficiently render the player's avatar as he moves across the screen. By the time redraw() is called, the player has already finished moving to the target point. If I try to call redraw() more frequently (based on my game timer), there's incredible system lag and I don't even see the avatar image glide across the screen.

I have a game timer based off this awesome timer class: http://www.dailycoding.com/Posts/object_oriented_programming_with_javascript__timer_class.aspx

In the future, there will be multiple enemies chasing the player. Fast pace is essential to the experience.

What should I do?

\$\endgroup\$
2
  • \$\begingroup\$ It is very unclear what your problem is, do your characters always exist on exact tile boundaries? If things are too fast, in general you want to move smaller steps at once. If things are too slow, you should use bigger steps, or skip frames. In general it is a bad idea to synchronise the game logic to rendering, because you'll end up with inconsistent speed on different platforms. \$\endgroup\$
    – MarkR
    Commented Apr 6, 2012 at 12:21
  • \$\begingroup\$ It might help if you could provide a link to your game's prototype in this question, so that people can review your code and view its behaviour. \$\endgroup\$
    – MarkR
    Commented Apr 6, 2012 at 12:23

1 Answer 1

0
\$\begingroup\$

You should probably cache your player move in an array, and step through it frame after frame. Let's say you store your Bresenham result in an array called path, you'll need an additional variable to hold the current position, let's call it pathMarker:

var path = new Array();
var pathMarker = -1;

Somewhere in you're update function, you'll need something like this:

// if our player clicked somewhere, compute a new path
if (click.x != -1 && click.y != -1)
{
    bresenham(path, click);
    pathMarker = -1;
}

// if there's a current path, move along it
if (path.length > 0)
{
    ++pathMarker;

    if (pathMarker >= path.length)
    {
        // reached the end of path, clear everything
        var path = new Array();
        pathMarker = -1;
    }
    else
    {
        // set the player at current path position
        player.pos = path[pathMarker]:
    }
}

Depending on the size of your grid, this could be too slow or too fast.

If it's too slow this means that instead of incrementing pathMarker one by one you'll have to use greater steps, e.g. replace ++pathMarker by:

    var speed = 4; // for instance
    pathMarker += speed

If it's too fast you can step only once in a while instead of each frame:

    var framesForAMove = 4; // for instance
    if ((frameCount % framesForAMove) == 0)
    {
        ++pathMarker;
    }

NB: using discrete grid positions directly isn't a really good idea in a lot of contexts: variable framerate, variable player speed, etc. But it's simpler to grasp, and quick to code, so very appropriate for prototyping.

\$\endgroup\$
4
  • \$\begingroup\$ Thanks, I like your idea of using a cached path and I'm trying to make that work with my code. I think that it will run too fast, but I haven't found any good resources on doing lerp. Are there any that you'd recommend? The best resources would be one that can explain the math to me like I'm 5 years old. :) \$\endgroup\$
    – user422318
    Commented Apr 4, 2012 at 16:34
  • \$\begingroup\$ Just google more about linear interpolation, I'm sure you'll find something that fits you. And if you're still confused, well, ask another question :) If there's something you'll use lots of times in gameplay programming, it's the lerp function. But for the moment, forget about lerp, you can just advance on your path once in a while, I'll edit my answer above to reflect that. Oh and by the way, maybe Bresenham is overkill for you, you should probably forget about discrete-grid motion and try out what Jimmy suggested: gamedev.stackexchange.com/a/26347/14808. \$\endgroup\$ Commented Apr 4, 2012 at 16:50
  • \$\begingroup\$ I was just re-reading my response and I'm a little confused about the cached path. If I try to update with each iteration of the Bresenham, the rendering happens too fast. Why wouldn't this happen if I'm just looping through it? Should I call the update function (which increments pathIndex) based on the timer interval? Bresenham is already implemented and too way too long. >< I just have to figure out how to get pathfinding working in time, and I'm very worried about that. \$\endgroup\$
    – user422318
    Commented Apr 4, 2012 at 16:54
  • \$\begingroup\$ You need to decouple your rendering from your Bresenham iterations. Just make it a separate bresenham function that you'd call as in my example above, and update/draw your game independently. Also, learn about what a game loop is: active.tutsplus.com/tutorials/games/…. \$\endgroup\$ Commented Apr 4, 2012 at 17:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .