Help with animation technique

I have recently been working on a simple 2d demo which is basically a map with static objects, and lots creatures moving around on the map. The actual viewport can be moved around using the arrow keys as the map is much larger than the viewport. Currently the map is stored as a 2d integer array with each variable representing a tile on the map and each tile is the same size ( currently 48x48 ). Just the portion of the map which is in the viewport is rendered. Every turn each creature (which there are lots of 500+) looks around the map(2d array) and decides which is the best position for them to move.

This being said, the problem I am having is that right now my creatures move 1 map position per turn, but since the map positions are 48x48px, its not a smooth animation, but more of a jump.

1 solution I have thought of is to have all the objects (creatures) not have to live entirely in a specific tile, but be able to move in small increments. This is a problem because when it’s their turn to look around, or act on a creature around them, the computations will be much much more complicated and slow the entire thing down. I was thinking If I used this method I would need to figure out how to do some sort of ray-casting or more advanced collision detection.

2nd solution I have thought of is to only allow the creatues to be positioned on a perticular tile, but have them “transition” between tiles on each turn. My problem with this solutions is that eventually I want to give the user control of 1 of the creatures and it would be awkward and restrictive to have to move an entire tile space(like chess).

Any help with this would be greatly appretiated.

If we’re talking 2D only here then allowing the creatures to move and existing in smaller than tile increments (solution 1) won’t actually be as tricky as you seem to think.

Theres lots of tutorials about this stuff plattered across the web.

Kev

The easiest way is to have the creatures with an 8bit fixed point position.
They then move between between the central point s(128,128) of the tiles, and their current tile is just(xCoord>>8,yCoord>>8) so your current turn/interact logic can stay the same.
When moving, just move by, for example, 8 a frame (preferable scaled to elapsed time if you can), and when they reach (or overshoot) the centre point, force it to be ‘128,128’.

I don’t quite understand. I have been codeing for years, but this is my first attempt at doing anything like this. Would it be possible that I could send you the code to have you look at it? Or do you know of any examples I might be able to checkout? I have been stuck on this problem for quite some time.

Seems Yabb screwed up my post with smilies - Oops!

Basically, you creatures have an x,y coordinate in the world. Presumably your creatures already have this, but at the moment x =2, y=2 means the creature is in map position (2,2)

For fixed point, you basically multiply up all the x/y coordinates by 256. The easiest (fastest) way is the shift operator: x<<8 == x*256

When you want to know what tile a creature is in, you simply divide the coordinates by 256 using the shift right operator: x>>8 == x / 256


int tile_x = obj.x>>8;
int tile_y =obj.y>>8;

Everything else can stay the same for now.
When you draw them, use this to position the creatures properly, so their position relative to the top left corner is:


int sx = (obj.x * 48)>>8;
int sy = (obj.y * 48)>>8;

When it comes to moving, just add small increments to the x/y, and catch it when it reaches the midpoint of a tile (128). Use time.getMillis (or another timer) to get the number of milliseconds that have passed since the last update and do:


static int TIME_TO_MOVE_1_SPACE 400

int moveLeft(int elapsed)
{
    x += 256 * elapsed / TIME_TO_MOVE_1_SPACE;
    if( x >= 128)
    {
        x = 128;
        return true;
    }
    return false;
}

& similar for other directions.

Then when the creature decides to move left (making sure it is currently not moving & is positioned at 128,128 within a tile) you want to set his ‘state’ as movingleft. Keep moving until the function returns true (has reached the destination):



int state;
static final int STATE_STAND = 0;
static final int STATE_MOVE_LEFT = 1;
...

void update(int elapsed)
{
    switch(state)
    {
    case STATE_MOVE_LEFT:
        if(moveLeft(elapsed))
            state = MOVE_STAND;
            break;
    case STATE_STAND:
        // decide what to do now...

// etc. etc.

there are many other methods of doing the same thing, but this sort of state machine is nice & easy to understand so is good for showing what I’m trying to explain!

Hope it helps,

  • Dom

Thanks a ton. That actually helped quite a bit, and gave me a bunch of good ideas.