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 want to make an RPG game in which I move tile by tile. So when I hit up, the tile row that I am on decreases by one for example. Also, it's supposed to be a slow movement so that I can see the change in tile, i.e. I can see my sprite move from tile to tile. Currently, with the code I have, when I hit a direction on my keyboard, I move several blocks within seconds and by the time I release the button I have already gotten a nullPointerException error because I have left the map. How can I slow down the movement?

share|improve this question

3 Answers 3

This sounds like an input problem. You need to check your inputs to see if you've already processed a key press. Keep the state of the keyboard from the last frame and check it when you're on your new frame. Only move if the key was not being pressed in the previous frame. Similar to responding to the event of pressing the key instead of the key being down.

For example:

currentKeys.fillFromKeyboard();

if(currentKeys.isDown(Key.UP) && !previousKeys.isDown(Key.Up))
    character.moveUp();

...

previousKeys.fill(currentKeys);

That will apply one move to each key press. If you wanted to have a held key repeat movements you can do something like:

int repeatDelay = 500; //time in MS that we'll delay before repeating a key

if(currentKeys.isDown(Key.UP) && (getCurrentGameTime() - timeMoved) >= repeatDelay) {
    character.moveUp();
    timeMoved = getCurrentGameTime();
}

Additionally, you should probably be checking bounds when moving. So check that your character's position + movement amount is withing world bounds, before moving.

share|improve this answer
    
moveUp would also have to be changed to be aware of if the character is currently moving, otherwise tapping up a few times would still move the character upwards several blocks. –  CiscoIPPhone Jul 8 '12 at 18:53
    
@CiscoIPPhone Good point. The move up command can either queue up movements if the character is currently moving or additional moves can be ignored. I think expected behavior would be to ignore the additional input, but that's something you'll have to play test. –  Byte56 Jul 8 '12 at 18:57
    
Thanks, you helped me figure things out. –  user1264811 Jul 9 '12 at 3:27

Just a note on structure - you are calling repaint(); in your update(); function, but it would probably be better if you didn't chain the calls like that, but rather have those in your main game loop, ie.:

while(true) {
   update();
   render();  // if you use double-buffering, which you probably should
   repaint();
}
share|improve this answer
    
Hahaha yes I realized that last night thank you. –  user1264811 Jul 9 '12 at 15:32
up vote 1 down vote accepted

This is the code I used.

// These numbers represent the different directions in movement.
private final int STILL = 0, LEFT = 1, UP = 2, RIGHT = 3, DOWN = 4,
        STOP = 5;
// The current direction of movement of the player.
public int movement = 0;

// The move method, like any other player class.
private void move() {
// The keyboard input class works like this:
// If the up keyboard button is pressed, player.movement = player.UP,
// if right is pressed, player.movement = player.RIGHT, etc.
// and if no key is pressed, player.movement = player.STILL;

    if (movement == UP) {
        moveUp();
    }
    if (movement == LEFT) {
        moveLeft();
    }
    ....
    if (movement == STILL) {
        setDx(0);
        setDy(0);
    }
}

private void moveLeft() {
// Because this intends to work on a tile grid, this method checks if
// the tile to the left of the player is occupied.
    if (!tileIsOccupied(LEFT)) {
// The player can press a key every 200 ms. Sets the time moved to this 
// point in time. If a player attempts to move before those 200 ms are
// over, no movement will occur.
        setTimeMoved(getCurrentTime());
// This tile is essential the tile to the left of the player.
        Tile tile = getGrid().getTiles()[getTileRow() - 1][getTileColumn()];
// If the xpos of the player is greater than the xpos of the tile, keep moving
// left.
        if (getXpos() > tile.getXpos()) {
            setDx(-1);
            setXpos(getXpos() + getDx());
        }
// If the xpos of the player is less than or equal to that of the tile, 
// set the player's position equal to the tiles. In other words, when
// the player has moved to the tile.
// Set this current tile to equal the player's tile, and movement is reset to
// still. 
        if (getXpos() <= tile.getXpos()) {
            setTileColumn(tile.getTileColumn());
            setTileRow(tile.getTileRow());
            setXpos(tile.getXpos());
            setMovement(STILL);
        }
    } else
        movement = STILL;
}

// It's essential that the update function be called on a loop. Otherwise, the
// player will not move. 
public void update() {
    move();
}
share|improve this answer
    
-1 Answers that are just code are poor. Generally it doesn't explain things as nicely as some text, and in this case, it makes the answer too localized to this question, making it less useful to future visitors. It's not even commented code. –  Byte56 Dec 22 '12 at 15:49
    
I added comments. Hopefully this will be more useful to future visitors. –  user1264811 Dec 22 '12 at 16:29
    
That's better, it explains the code, but it doesn't explain how you solved the problem. –  Byte56 Dec 22 '12 at 16:48

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.