0
votes

I have this code, that uses linear interpolation on sprite movement:

public void update(float dt) {

    vx += (targetX - vx) * dt;
    vy += (targetY - vy) * dt;
    x += vx * dt;
    y += vy * dt;
    playerSprite.setPosition(x, y);
    // other stuff, not related to the problem
}

public static void moveUp() {
    targetY = -moveSpeed;
}

public static void moveDown() {
    targetY = moveSpeed;
}

public static void moveLeft() {
    targetX = -moveSpeed;
}

public static void moveRight() {
    targetX  = moveSpeed;
}

targetX and targetY are where the sprite should be heading.

vx and vy are the variables used for the current velocity of the sprite, both initialized to 0.

dt is the difference in frame time since the last time the screen was updated.

moveSpeed is initialized to 150.

The movement is smooth, which is what I want, however, the sprite never has it's speed (clarification: absolute value of velocity) slowed down. So, I can never get the sprite to stop moving, and if I just press a movement key and let it move, it just keeps going. How would I implement friction in my current case?

1
You will need to recalculate the velocity in a series of deltas or differences with the velocity decreasing each recalculation. See game physics friction - Richard Chambers
This is similar to the problem of implementing flick scrolling with friction and braking using an inertial body simulation slowing down the scrolling of the displayed data. - Richard Chambers
Can I see this in code? I don't quite understand. @RichardChambers - Tetramputechture
Please update your source code example in your question with comments to indicate what the variables represent along with units of measurement. - Richard Chambers
Done! @RichardChambers - Tetramputechture

1 Answers

0
votes

I am not sure as to the units and the coordinate system you are using so I am going to provide a simple example.

In the Java source below I start at a position 10, 10 in a two dimensional space or plane. The current velocity of the sprite is 0.0,15.0 meaning each time period, velocity is in distance divided by time such as feet per second, the sprite will move 0 units in the X direction and 15 units in the Y direction.

The loop below is a simple recalculation in which each time through the loop represents some amount of time and at the bottom of the loop new values are calculated for the distance traveled during the time period at the given velocity. We also slow down the object by modifying the velocity.

I print this as a comma separated values list of data points so that I could pull the sequence into Excel and graph the values. When I graphed the Y position values with a simple line chart, what I see is the Y position has large changes in the beginning and there is a nice curve of positional values which show less and less distance moved each time period until it reaches its final value when the velocity is zero.

public static void main(String[] args) {
    // TODO Auto-generated method stub

    int i;

    double  dVelocityX = 0.0;
    double  dVelocityY = 15.0;
    double  dFriction  = 0.90;    // simple friction coefficient, 1.0 means no friction

    int     xStart = 10;
    int     yStart = 10;

    System.out.print(" i,xStart,yStart,dVelocityX,dVelocityY\n");
    for (i = 0; i < 60; i++) {
        System.out.print(i+"," + xStart + "," + yStart+"," + dVelocityX + "," + dVelocityY + "\n");
        xStart += dVelocityX;
        yStart += dVelocityY;
        dVelocityX *= dFriction;
        dVelocityY *= dFriction;
    }
}

The actual data output has starting coordinates of 10,10 and by the time the velocity is practically zero at the end the coordinates are 10,138 at time 26 seconds.

You have to create a kind of physical world simulation in which you specify some units of measurement to everything in order for it to actually seem somewhat realistic. So you may have units such as a large table top (a two dimensional plane) which is 1000 millimeters wide and 1000 millimeter long and this table top is marked off in units of one millimeter. Next you have a round puck that is one millimeter in diameter. You place the puck at coordinate 10,10 where the center of the puck is 10 millimeters from the left edge of the table and 10 millimeters from the bottom edge of the table, the edge next to you. You give the puck a push so that it starts off at a velocity of 15 millimeters per second and you push it from the bottom so that it is moving along the lengthwise dimension of the table, the positive Y direction. If there is no friction then at the end of the first second it will have moved from position 10,10 to position 10,25 then the next second to position 10,40.

If you were to plug this into this simulator you would see output something like:

 i,xStart,yStart,dVelocityX,dVelocityY
0,10,10,0.0,15.0
1,10,25,0.0,15.0
2,10,40,0.0,15.0
3,10,55,0.0,15.0
4,10,70,0.0,15.0
5,10,85,0.0,15.0
6,10,100,0.0,15.0
7,10,115,0.0,15.0
8,10,130,0.0,15.0
9,10,145,0.0,15.0
10,10,160,0.0,15.0
11,10,175,0.0,15.0
12,10,190,0.0,15.0
13,10,205,0.0,15.0
14,10,220,0.0,15.0

Then if you change the friction from a value of dFriction from 1.0, meaning no friction, to a value of .90 you will see that the puck slows down as it travels so that in the same time of 14 seconds it has not moved as far as it did in a frictionless universe.

 i,xStart,yStart,dVelocityX,dVelocityY
0,10,10,0.0,15.0
1,10,25,0.0,13.5
2,10,38,0.0,12.15
3,10,50,0.0,10.935
4,10,60,0.0,9.8415
5,10,69,0.0,8.85735
6,10,77,0.0,7.971615000000001
7,10,84,0.0,7.174453500000001
8,10,91,0.0,6.457008150000001
9,10,97,0.0,5.811307335000001
10,10,102,0.0,5.230176601500001
11,10,107,0.0,4.707158941350001
12,10,111,0.0,4.236443047215001
13,10,115,0.0,3.8127987424935013
14,10,118,0.0,3.4315188682441513

Now if you change your units of measurement so that you are using a finer resolution in calculating position, say using micrometers rather than millimeters, and a finer resolution in time, say using hundredths of a second rather than seconds, then smaller differences in position will become more noticeable and pronounced. So you may have to work with the scale of the universe in order to determine what units to use for your simulation.

With animation such as moving a sprite you have to pick a time period in which the moving animation is reasonably smooth as you are presenting to the user a series of frames or images in which the position of the sprite changes just a touch from frame to frame. The faster the sprite moves, the faster the frame display rate must be in order to provide a smooth motion.