TransWikia.com

Pause updating but keep rendering

Game Development Asked by Yosoku Denkai on December 5, 2020

I am creating an implementation of Snakes and ladders
and I run into some issues.The game is updating too fast and I want to limit the framerate kinda,or make a pause so that the move is actually visible.I tried using Thread.sleep() but that created issues of its own.Have you solved any similar problems that could point me to the right direction?
I have to point out that run method is in an abstract class and my actual game extends this abstract class

This is the game loop :

public void run() {
    init();
    this.requestFocus();
    long lastTime = System.nanoTime();
    double amountOfTicks = 60.0;
    double ns = 1000000000 / amountOfTicks;
    double delta = 0;
    long timer = System.currentTimeMillis();
    int updates = 0;
    int frames = 0;
    while (running) {
      long now = System.nanoTime();
      delta = delta + (now - lastTime) / ns;
      lastTime = now;
      while (delta >= 1) {
        update();
        updates++;
        delta--;
      }
      render();
      frames++;
      if (System.currentTimeMillis() - timer > 1000) {
        timer = timer + 1000;
        if (this.FPSLOG)
          System.out.println("FPS: " + frames + " " + "Ticks: " + updates);
        frames = 0;
        updates = 0;
      }
    }
    stop();
  }

The render method :

private void render() {
    BufferStrategy bs = this.getBufferStrategy();
    if (bs == null) {
      this.createBufferStrategy(3);
      return;
    }
    Graphics g = bs.getDrawGraphics();
    g.setColor(background);
    g.fillRect(0, 0, getWidth(), getHeight());
    draw(g);
    g.dispose();
    bs.show();
  }

The game implementation of those methods:

@Override
    public void init() {
        setBackground(Color.black);
        board = new Board();
        player = new Player(Color.cyan,board.getTiles()[0]);
        dice = new Random();
    }

    @Override
    public void draw(Graphics g) {
        board.draw(g);
        player.draw(g);
    }


    @Override
    public void update() {
        for (int i = 0; i < dice.nextInt(7)+1; i++) {
            player.move();
        }
    }
public void move(){
        this.currentTile = this.currentTile.getNext() == null ? this.currentTile : this.currentTile.getNext();
        this.xPos = this.currentTile.getxPos();
        this.yPos = this.currentTile.getyPos();
    }

One Answer

The variable double amountOfTicks = 60.0; seems to be what's controlling your update rate. You might want to reduce that, this will update your logic less often, while keeping the same render rate.

Also, there is an issue with the update() function: each time you call the dice.nextInt(7) method, you generate a new value, changing the upper bound of your loop every iteration. I'm not sure this is what you expect. Also, you move your player many times per frame, which does not help your situation (all the loop iterations are performed in the same frame).

// The iterations of this loop 
for (int i = 0; i < dice.nextInt(7)+1; i++) {
    player.move();
}

// will look like this:
i = 0; dice.nextInt(7)+1 = 8; i < number? true
i = 1; dice.nextInt(7)+1 = 5; i < number? true
i = 2; dice.nextInt(7)+1 = 4; i < number? true
i = 3; dice.nextInt(7)+1 = 2; i < number? false

It is very unlikely that i will ever reach 7.

I suggest you add a new movesLeftThisTurn variable to your player, as well as a famesTillNextRoll variable. Once you roll the dice, you stick the value in movesLeftThisTurn, and you decrement it by one each frame that you move. Once it gets to 0, set the other variable to 5, and decrease it by one each frame. Once it gets to 0, roll the dice for movesLeftThisTurn and start over again.

Here is something like what I have in mind:

public void update() {
    if (player.movesLeftThisTurn > 0) {
        player.move();
        player.movesLeftThisTurn -= 1;

        if (player.movesLeftThisTurn == 0)
          player.famesTillNextRoll = 5; // This will pause the player at the current tile for 5 frames
    }
    else {
        if (player.famesTillNextRoll > 0)
            player.famesTillNextRoll -= 1; // Do nothing...

        if (player.famesTillNextRoll == 0)
            player.movesLeftThisTurn = dice.nextInt(7) + 1;
    }
}

Answered by Vaillancourt on December 5, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP