Thread: Smooth walking on tile based map system

  1. #1
    Registered User
    Join Date
    Dec 2008
    Posts
    104

    Smooth walking on tile based map system

    Hello,

    I am developing a small game which requires the use of a map system. I chose to make that map system work upon a tile-based system. At the moment, each tile is 32x32, and I contain 24x20 tiles on my map.

    A walking system is also required for this game I'm developing, so I ran into some issues with making the loaded sprite walk "smoothly". At the moment, it jumps from tile to tile in order to walk. This makes it seem very unrealistic. I have tried many different ways to make the walking "smoother", but it requires me to change my tile's size in order to accommodate the sprite's size. This would not be an issue if I only used the same sprite in the game, but since I load different sprites which contain different measurements, I do not know how to make my walking system accommodate all of the sprites in order to make the walking realistic.

    I am not requesting any code whatsoever, simply ideas.

    Thank you

  2. #2
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    This should probably go in the Game Programming forum.

  3. #3
    Registered User
    Join Date
    Dec 2008
    Posts
    104
    True, but it's more of a design issue then anything else. Therefore, I assumed it would be proper to post it here in order to see some ideas.

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    So you want to use a grid for your background basically, but you don't want to actually make movement stick to this grid? You want it to slide slowly across from one tile to the next? Well, then just decide how many frames you are going to use for sliding, and update that many times.

    You need to remember that now you can't use the indexes of the background tiles for movement points, but will instead have to use the position on the screen. IE: Take "frames" number of baby steps across, rather than one big jump.

    Now, do you move your character on your background, or does your character stay centered, and the background moves around them?
    Hope is the first step on the road to disappointment.

  5. #5
    Registered User
    Join Date
    Dec 2008
    Posts
    104
    I move my character on my background.

    I did not completely comprehend your idea; if you could reword it, it would be great.

  6. #6
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> I did not completely comprehend your idea; if you could reword it, it would be great.

    In other words, forget about the tiles for a moment. You have a sprite, and the coordinate attached to some point on the sprite (eg: center, corner, etc). To make things simple the coordinate is relative to the screen (upper left point being origin on most systems, but it varies). When you move the 'character', you simply update the coordinate associated with the sprite, and then call a redraw function that copies the sprite at that position on the screen. So if you're coordinate was attached to the center of the sprite, the x offset would be:
    start_x = screen_x + sprite_x - ( sprite_width / 2 )
    Of course screen_x is probably 0, so that could be ommited. Naturally, using the top left corner of the sprite instead make the calculation much simpler.

    Once you have that working, just set it up so that the background is drawn first, of course.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  7. #7
    Registered User
    Join Date
    Dec 2008
    Posts
    104
    Sebastiani, thank you for your response. That was not my specific question, but no matter, your reply helped me come up with a simplistic idea. My problem was that my character was attached to a tile, and drawn on that tile. I simply relieved the character from being drawn on a tile, and limited only the background (grass, lake, etc) to be drawn in tiles.

    So basically, my paint method is as follows:
    Code:
    //draw tiles
    //draw sprites onto the screen
    I was so stuck into thinking that I needed to depend on the tiles for the player movement, that I did not realize the obvious; I didn't need to depend on them.

    Anyways, thank you all for your suggestions.

  8. #8
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by abraham2119 View Post
    That was not my specific question, but no matter, your reply helped me come up with a simplistic idea.
    Actually, it was your specific question.

    If you want them to not be instantly from one tile to the next, then you need to draw them at various stages along the way from tile A to tile B. That was exactly your question.


    Quzah.
    Hope is the first step on the road to disappointment.

  9. #9
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    The sprite has both a tile where it is located and an offset in pixels from the corner of that tile. To move the sprite, you increment the pixel offset smoothly and check for when it exits the bounds of the tile, and move it to the next tile. (Of course, the sprite also has an origin with respect to it's position, which I didn't implement here since that's orthogonal to this problem. I also didn't do any bounds checking, since the game should do that, not the sprite)

    Code:
    class Sprite
    {
        Sprite( int initialX, int initialY )
            : mOffsetX( initialX ), mOffsetY( initialY )
        {
            mTileX = mOffsetX / TILE_WIDTH;
            mOffsetX = mOffsetX % TILE_WIDTH;
            mTileY = mOffsetY / TILE_HEIGHT;
            mOffsetY = mOffsetY % TILE_HEIGHT;
        }
    
        void Move( int moveX, int moveY )
        {
            BumpCoordinate( mOffsetX, mTileX, TILE_WIDTH, moveX );
            BumpCoordinate( mOffsetY, mTileY, TILE_HEIGHT, moveY );
        }
    
        // Get the coordinate of the current tile (measured in tiles)
        int GetTileX() const { return mTileX; }
        int GetTileY() const { return mTileY; }
    
        // Get the absolute position in pixels
        int GetX() const { return mTileX * TILE_WIDTH + mOffsetX; }
        int GetY() conset { return mTileY * TILE_HEIGHT + mOffsetY; }
    
    private:
        int mTileX;
        int mTileY;
        int mOffsetX;
        int mOffsetY;
    
        void BumpCoordinate( int &coord, int &tile, int size, int bump )
        {
            coord += bump;
            // Avoid division and modulus for the common case where we don't move
            // farther than a single tile at once.
            while( coord >= size ) { coord -= size; ++tile; }
            while( coord < 0 ) { coord += size; --tile; }
        }
    };
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. New editor updates
    By VirtualAce in forum Game Programming
    Replies: 8
    Last Post: 11-05-2005, 03:26 PM
  2. Replies: 4
    Last Post: 06-13-2005, 09:03 AM
  3. Replies: 3
    Last Post: 06-13-2005, 07:28 AM
  4. Setting Up a sector based grid system
    By Auron in forum C Programming
    Replies: 6
    Last Post: 05-20-2005, 08:19 AM
  5. Operating system construction
    By AdamLAN in forum Tech Board
    Replies: 7
    Last Post: 03-05-2005, 01:31 PM