Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I would like a player to be able to move in a direction smoothly, whilst sticking to a fixed grid. Much like in Pokemon, how the player can move, but when the key is pressed and released quickly, they move to the next 'grid square' smoothly. Currently, my player moves at a stupid pace, because I am moving them on the "grid" axis (16px squares). I have tried but failed many a time to make a player smoothly move between squares. Here are the two important classes related to my issue;

Grid.java

package com.jackwilsdon.walktest;

import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;

public class Grid {
    public static final int BLOCK_SIZE = 16;

    public void drawDebugGrid(GameContainer gC, Graphics g)
    {
        int width = gC.getWidth();
        int height = gC.getHeight();

        int block_count_x = width/BLOCK_SIZE;
        int block_count_y = height/BLOCK_SIZE;

        boolean color = false;
        for (int cX = 0; cX < block_count_x; cX++)
        {
            for (int cY = 0; cY < block_count_y; cY++)
            {
                Location current = new Location(cX, cY);
                current = gridLocationToExact(current);

                if (color)
                {
                    g.setColor(new Color(180, 180, 180));
                } else {
                    g.setColor(new Color(200, 200, 200));
                }

                g.fillRect(current.x, current.y, BLOCK_SIZE, BLOCK_SIZE);

                color = !color;
            }
            color = !color;
        }
    }

    public static Location exactToGridLocation(Location l)
    {
        return new Location(l.x/BLOCK_SIZE, l.y/BLOCK_SIZE);
    }

    public static Location gridLocationToExact(Location l)
    {
        return new Location(l.x*BLOCK_SIZE, l.y*BLOCK_SIZE);
    }
}

Player.java

package com.jackwilsdon.walktest;

import java.util.ArrayList;
import java.util.List;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.SpriteSheet;

public class Player {

    // Grid related location
    public Direction direction = Direction.NORTH;
    public Location location = new Location(0, 0);

    // Actual (pixel) location
    private Location actual = new Location(0, 0);

    // Sprite stuff
    private SpriteSheet player = null;

    private int maxSteps = 2;
    private int step = 0;

    public List<Image> north = new ArrayList<Image>();
    public List<Image> east = new ArrayList<Image>();
    public List<Image> south = new ArrayList<Image>();
    public List<Image> west = new ArrayList<Image>();

    public Player() throws SlickException
    {
        player = new SpriteSheet("res/player.png", 16, 16);
        north.add(player.getSprite(0, 0));
        north.add(player.getSprite(1, 0));

        east.add(player.getSprite(0, 1));
        east.add(player.getSprite(1, 1));

        south.add(player.getSprite(0, 2));
        south.add(player.getSprite(1, 2));

        west.add(player.getSprite(0, 3));
        west.add(player.getSprite(1, 3));
    }

    public void nextStep()
    {
        step++;
        if (step > maxSteps-1)
        {
            step = 0;
        }
    }

    public void draw()
    {
        actual = Grid.gridLocationToExact(location);
        switch (direction)
        {
        case NORTH:
            north.get(step).draw(actual.x, actual.y);
            break;
        case EAST:
            east.get(step).draw(actual.x, actual.y);
            break;
        case SOUTH:
            south.get(step).draw(actual.x, actual.y);
            break;
        case WEST:
            west.get(step).draw(actual.x, actual.y);
            break;
        }
    }

    public void move()
    {
        switch (direction)
        {
        case NORTH:
            location.y -= 1;
            break;
        case EAST:
            location.x += 1;
            break;
        case SOUTH:
            location.y += 1;
            break;
        case WEST:
            location.x -= 1;
            break;
        }
    }
}

So, how do I (linearly?) interpolate between the two points? I am using Slick2D, so I have an update() method that is called where logic can take place.

share|improve this question
    
Does your player class have the ability to have an Update function that will be run every tick of your game logic? If so there is a nice elegant way to handle this. –  Blue Mar 25 '13 at 9:14
add comment

1 Answer

up vote 2 down vote accepted

It's as simple as

(1-t)A + tB

Whereas 0 <= t <= 1

A and B are your two points. You might need to write it like so:

player.x = (1-t)tileA.x + t*tileB.x;
player.y = (1-t)tileA.y + t*tileB.y;

So simply update t

t += speed*deltaTime;
//Do position interpolation
if(t > 1)
//change state.
share|improve this answer
    
Can I ask what deltaTime is? I am using it in my code, generated by Slick2D as a multiplier. Is it something to do with how fast the game is running? How is it calculated? Thanks :) Also, I got it working with smooth player movement, thankyou :) –  jackwilsdon Mar 24 '13 at 21:13
    
@jackwilsdon delta time is the time step between your current frame and last frame. I didn't really look at your code. I just assumed you are using timesteps. gamedev.stackexchange.com/questions/1589/… and stackoverflow.com/questions/7923349/slick2d-game-speed-changing –  Sidar Mar 25 '13 at 8:36
    
BTW, if you're satisfied with my answer; please accept it. So that this question can be marked as answered. –  Sidar Mar 25 '13 at 13:12
    
I made a mistake it's 1-t not t-1 –  Sidar Mar 30 '13 at 1:15
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.