3
\$\begingroup\$

I'm using Slick 2D/Java to play around with graphics. Getting an image to move is easy:

Input input = gc.getInput();

        if(input.isKeyDown(sprite.up)){
            sprite.y--;
        }else if (input.isKeyDown(sprite.down)){
            sprite.y++;
        }else if (input.isKeyDown(sprite.left)){
            sprite.x--; 
        }else if (input.isKeyDown(sprite.right)){
            sprite.x++; 
        }

However, this is called on every update, so if you hold up, the sprite moves to the edge of the screen in a few hundred milliseconds. Since coordinates are integers, I can't add less than 1 to slow the sprite down. I'm assuming I must have to implement a timer of some sort or something. Any advice?

\$\endgroup\$
3
  • \$\begingroup\$ Rphello101, check out the class I linked to you in a previous answer. I solves a lot of the problems you're facing. Just read through it and see what it's doing. \$\endgroup\$
    – House
    Oct 7, 2012 at 18:47
  • \$\begingroup\$ Are you updating like while(running){update()} or are you doing it with a delay? Like (1 / 60) perhaps. \$\endgroup\$
    – Lysol
    Oct 7, 2012 at 20:12
  • \$\begingroup\$ Slick has its own method called update(). I'm not sure how it works. I haven't looked at the code. \$\endgroup\$
    – rphello101
    Oct 8, 2012 at 15:35

2 Answers 2

5
\$\begingroup\$

rate * time = distance

  1. Establish a rate of movement in whatever units of measure you want (such as pixels per millisecond).
  2. Get the time since the last update that has passed (elapsed time).
  3. Establish the direction of movement (you're already doing that).
\$\endgroup\$
2
  • \$\begingroup\$ I understand the physics, but how do I implement this? So my rate is a constant, like .3. Would time be delta (a variable of the Slick method update())? \$\endgroup\$
    – rphello101
    Oct 8, 2012 at 15:34
  • \$\begingroup\$ Yes, time is a delta between the time of the last update and the time of the current update. So, you could do something like position += direction * speed * dt where speed is your rate, dt is the delta time between the last and current updates, and direction contains which way you want to move. direction is specific to a scenario, but in your case, you could just set X and Y directions as 1, 0 or -1 depending on which way to move on that axis. \$\endgroup\$ Oct 8, 2012 at 15:44
2
\$\begingroup\$

Use separate real numbers to store position with sub-pixel accuracy and then cast them into integers to draw. If you can't modify your sprite class to contain real numbers, just create a new wrapper class that contains a sprite and real coordinates. Something like:

class Entity
{
  Sprite sprite;
  double x;
  double y;
  ...
  void translate( double dx, double dy )
  {
    x += dx;
    y += dy;
    sprite.x = (int) Math.floor(x);
    sprite.y = (int) Math.floor(y);
    // floor() prevents weirdness dealing with negative numbers like -0.1
    // (int)(-0.1) rounds up to 0 but (int)Math.floor(-0.1) rounds down to -1
  }
}

...
Entity entity = new Entity( sprite );
...
if(input.isKeyDown(sprite.up)) entity.translate(0,-0.1);
\$\endgroup\$
3
  • \$\begingroup\$ That is exactly what I would have suggested. If the issue is that one pixel per turn is too fast, move them less than one pixel using doubles instead of int. +1 \$\endgroup\$
    – AturSams
    Oct 7, 2012 at 18:53
  • \$\begingroup\$ I considered this. I just didn't know if it was good form. I'll try it though, thanks. \$\endgroup\$
    – rphello101
    Oct 7, 2012 at 19:45
  • \$\begingroup\$ This won't fix the issue. It is a good improvement to the code but the problem is still there. Slick2d uses a variable update rate, which means that the movement speed will differ depending on the FPS of the target system. Justin Skiles answer should help to fix the problem. \$\endgroup\$ Oct 7, 2012 at 21:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .