Calculating motion of an object?

I'm trying to do it myself right now, but there's a ton of things wrong with it - for example, the object won't slow down to a halt if I let go of the directional key. For some reason, it speeds up.. if anyone could help me with this, I'd greatly appreciate it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// in main.cpp
        typedef sf::Vector2f v2f;
        if (Input.IsKeyDown(sf::Key::Left))
            player->Move(v2f(-.5,0));
        else if (Input.IsKeyDown(sf::Key::Right))
            player->Move(v2f(.5,0));
        else if (Input.IsKeyDown(sf::Key::Up))
            player->Move(v2f(0,-.5));
        else if (Input.IsKeyDown(sf::Key::Down))
            player->Move(v2f(0,.5));
        else
            player->Move(v2f(0,0)); 
        // So that even if the user does not add motion to the object,
        // it will still be able to move.   



1
2
3
4
5
6
7
8
9
void Player::Move(sf::Vector2f dir)
{
    sf::Vector2f loc  = sprite.GetPosition();
    CalculateMotion(dir);

    if ((loc.x > 0 && loc.y < 800-sprite.GetSize().x) &&
        (loc.y > 0 && loc.y < 600-sprite.GetSize().y))
    sprite.Move(velocity);
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
void Player::CalculateMotion(sf::Vector2f dir)
{
    const double PLAYERACC = .00025;
    const double PLAYERVEC = .01;

    // Determine which way to add velocities, and such!
    if (dir.x > 0)
    {
        velocity.x+=PLAYERVEC;
        accel.x+=PLAYERACC;
    }
    else if (dir.x < 0)
    {
        velocity.x-=PLAYERVEC;
        accel.x-=PLAYERACC;
    }

    if (dir.y > 0)
    {
        velocity.y+=PLAYERVEC;
        accel.y+=PLAYERACC;
    }
    else if (dir.y < 0)
    {
        velocity.y-=PLAYERVEC;
        accel.y-=PLAYERACC;
    }

    // Account for its current accel.
    velocity.x += .05*accel.x;
    velocity.y += .05*accel.y;

    // Account for friction
    double xfrict, yfrict;
    // I'm not quite sure how friction should be calculated..which is      
    // probably why it's not working correctly.
    xfrict = PLAYERACC*(.0001*(velocity.x+.01)); 
    yfrict = PLAYERACC*(.0001*(velocity.y+.01)); 

    if (accel.x > 0)
        accel.x -= xfrict;
    else if (accel.x < 0)
        accel.x += xfrict;

    if (accel.y > 0)
        accel.y -= yfrict;
    else if (accel.y < 0)
        accel.y += yfrict;



accel and velocity are members of a Player object.
Last edited on
Few problems in CalculateMotion method.

1) You have no condition for if (dif.x == 0 && dir.y == 0) to reset the accel variable. So when no key is pressed, it's going to use the last value. Because you're always adding the accel to the velocity (line 30/31) the accel will forever increase once no key is pressed.

2) You're not reducing the amount of accel/velocity when no key is pressed. This is tied closely with 1).

Thanks, motion is still a little weird, but at least it slows down properly. I guess I'll have to actually study the physics of an object if I want to do this more accurately, though.
Topic archived. No new replies allowed.