Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread only running correctly if there is a System.out.println() inside the while true loop

Basicly, I'm making a game which to update the players position, it uses this thread:

@Override
public void run() {
    while(true) {
        System.out.println();
        updatePos(x, y);
    }

}

Which works fine, but if I remove the System.out.println(), it ceases to function. I have no idea why this is, the whole class is as follows:

public class Player extends Block implements KeyListener, Runnable {

int x;
int y;
int speed;

boolean upPressed; 
boolean downPressed;
boolean rightPressed;
boolean leftPressed;

static Sprite sprite = new Sprite("grass.png");

public Player(int x, int y, int speed) {
    super(x, y, sprite);
    this.x = x;
    this.y = y;
    this.speed = speed;
    Thread playerThread = new Thread(this, "Player Thread");
    playerThread.start();
}

@Override
public void keyPressed(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_UP) {
        y -= speed;
    }

    if (e.getKeyCode() == KeyEvent.VK_DOWN)
        downPressed = true;

    if (e.getKeyCode() == KeyEvent.VK_RIGHT)
        rightPressed = true;

    if (e.getKeyCode() == KeyEvent.VK_LEFT)
        leftPressed = true;

}

@Override
public void keyReleased(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_UP)
        upPressed = false;

    if (e.getKeyCode() == KeyEvent.VK_DOWN)
        downPressed = false;

    if (e.getKeyCode() == KeyEvent.VK_RIGHT)
        rightPressed = false;

    if (e.getKeyCode() == KeyEvent.VK_LEFT)
        leftPressed = false;

}

@Override
public void keyTyped(KeyEvent e) {

}

@Override
public void run() {
    while(true) {
        System.out.println();
        updatePos(x, y);
    }

}}

Final note: Ingore the boolean upPresses and downPressed, the only thing I'm focusing on is this:

if (e.getKeyCode() == KeyEvent.VK_UP) {
    y -= speed;
}
like image 318
Derek Avatar asked Feb 17 '26 12:02

Derek


1 Answers

A loop like

while(true) {
    updatePos(x, y);
}

would completely hog the CPU. Reason it starts behaving better with a println is probably because you yield a few hundred cycles per iteration for I/O.

I suggest you add a small sleep-method according to the desired frame rate:

while (true) {
    try {
        Thread.sleep(10); // for 100 FPS
    } catch (InterruptedException ignore) {
    }
    updatePos(x, y);
}

or, even better, go with an event driven approach with for instance a java.util.Timer. (That would be more Java idiomatic.)

like image 114
aioobe Avatar answered Feb 19 '26 01:02

aioobe



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!