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'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?

share|improve this question
    
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. –  Byte56 Oct 7 '12 at 18:47
    
Are you updating like while(running){update()} or are you doing it with a delay? Like (1 / 60) perhaps. –  Aidan Mueller Oct 7 '12 at 20:12
    
Slick has its own method called update(). I'm not sure how it works. I haven't looked at the code. –  rphello101 Oct 8 '12 at 15:35

2 Answers 2

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);
share|improve this answer
    
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 –  Zehelvion Oct 7 '12 at 18:53
    
I considered this. I just didn't know if it was good form. I'll try it though, thanks. –  rphello101 Oct 7 '12 at 19:45
    
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. –  tom van green Oct 7 '12 at 21:02

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).
share|improve this answer
    
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())? –  rphello101 Oct 8 '12 at 15:34
    
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. –  Justin Skiles Oct 8 '12 at 15:44

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.