General libGdx question (stuttering, "blurring" trouble)

hi everyone,
yes… am trying to learn libGdx again, i thought about the time am going to spend learning lwjgl and somehow i decided that libGdx will fit me better, anyway, back to the topic,
i am learning libGdx from some examples i found i also took a look on this guy channel he has some good tutorials to get started with libGdx,
so,
for now i didn’t have a debugging error, i just want to understand how some stuff works, mainly the game loop,
it said that the render() method is the main game loop

[quote]Method called by the game loop from the application every time rendering should be performed. Game logic updates are usually also performed in this method.
~libGdx-wiki~
[/quote]
now when i have a class that implements “Screen” the render method had a float parameter in it called “Delta” which when i print it, i get a value between 0.016 and 0.017, i have no idea what is that Delta variable, and why it’s called only when the class implement Screen (it doesn’t exist when the class extends Game)
in short term, what i want to know for now, should i create a method (or class) to know the frame rate,delta and all the other things we need to have a correct game loop or did libGdx do all that in the render() method ?

thank you

the render method is already everything you need, in this case here you dont need to write your own gameloop.
It will usually sync to vsync, which is usually 60 hertz meaning 60 fps.

using delta timing (aka variable time step) vs frame based (fixed time step) is a kinda of religious war. Mainly because using delta is very hard as it will usually result in stuttering and stuff.

Delta in math is of course difference. The difference it gives you here (in seconds) the time between this and the last frame.
Ideally you want to go 60 FPS, which is 1000ms / 60 FPS = 16 ms. That means, normally in gaming you have 16 ms to get your shit straight. So when you see 0.016 thats the ideal case.
Of course one frame takes longer than another because maybe there is a lot going on on screen.
So when a frame takes a long time, the idea is that when you know this time, you can use it as a factor in you game calculation, like the speed of flying objects, and thus be in sync, to compensate if you will.

The problem is that these delta times, depending on your game, whats going on and your device and have extraordinary differences/spikes. So you need to use a low pass filter (if you know signal / audio stuff) for example and try to smooth it, but if you do it too much you defeat the purpose…

I believe that when you program for a console, these developers dont actually use delta, because it runs everywhere the same - just make sure you never go below 60 fps (or 30 which is unfortunately the standard often)

So I’m an advocater of fixed/frame based. I have used delta in the past, rarely successful really but sometimes you really need it, depending on the circumstances. But normally I say: Have a minimum system requirement, and make it so that you game runs rock solid 60 FPS

another thing I have implemented in all games is a 30 FPS mode, in which everything is double speed but only 30 FPS. Listening to John Carmack, this seems to be a very popular thing to do, if not ideal, and I wouldn’t recommend switching during the game, but apparently some games actually do this.
Kinda like “game is slowing down ? -> switch to 30 FPS mode”, “game is fast again -> switch back to 60” which results in ugly “wobble” mostly.

Overall its a big topic and any one person who says “its dead easy you moron” has probably no idea (and for some reason its always the delta lovers who are like this :D)

Cas was also kinda unpleased with using delta IIRC, but no idea how he does it currently.

wow :o
i thought it must be a lot more simple than that, thanx a lot for those clarification
by the way the reason i posted this is that the game is a flickering, it really hurts my eyes when i move the player

well if you use delta simply, there you go.
if not you’re probably doing something wrong =D

i didn’t use delta, libGdx did ::slight_smile:


public class SplashScreen implements Screen {
//many useless things 

@Override
	public void render(float delta) {
		control();
		playerUpdate();
		Gdx.gl.glClearColor(0.2f, 0.2f, 0.3f, 1);
		Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

		System.out.println(delta);
		
		heroSprite.setColor(1, 1, 1, 1);
		heroSprite.setX(player.getX());
		heroSprite.setY(player.getY());
		
		batch.begin();
		heroSprite.draw(batch);
		batch.end();
	}

private void playerUpdate() {

		int xSpeed = 10;

		player.setX(playerX);
		player.setY(playerY);
		player.setWidth(playerW);
		player.setHeight(playerH);

		if (leftPressed) {
			playerX -= xSpeed;
		}
		if (rightPressed) {
			playerX += xSpeed;
		}
		if(upPressed){
			playerY+=xSpeed;
		}
		if(downPressed){
			playerY-=xSpeed;
		}
	}

	private void control() {
		if (Gdx.input.isKeyPressed(Keys.DPAD_LEFT)) {
			leftPressed = true;
		} else {
			leftPressed = false;
		}

		if (Gdx.input.isKeyPressed(Keys.DPAD_RIGHT)) {
			rightPressed = true;
		} else {
			rightPressed = false;
		}

		if (Gdx.input.isKeyPressed(Keys.DPAD_UP)) {
			upPressed = true;
		} else {
			upPressed = false;
		}
		if (Gdx.input.isKeyPressed(Keys.DPAD_DOWN)) {
			downPressed = true;
		} else {
			downPressed = false;
		}
	}


}

sooo :smiley: ??

Ah yes screens do this automatically. I don’t use screens… :smiley:

Offtopic:

-      if (Gdx.input.isKeyPressed(Keys.DPAD_RIGHT)) {
-         rightPressed = true;
-      } else {
-         rightPressed = false;
-      }

+      rightPressed = Gdx.input.isKeyPressed(Keys.DPAD_RIGHT);

any other details ::slight_smile: ??
@Riven
thanx ;D

You’re not using the delta here, you should use it in the playerUpdate method :


   private void playerUpdate(float delta) {
      // 10 represents here the speed in pixels ( or whatever unit you're using ) per second
      int xSpeed = 10 * delta;

      player.setX(playerX);
      player.setY(playerY);
      player.setWidth(playerW);
      player.setHeight(playerH);

      if (leftPressed) {
         playerX -= xSpeed;
      }
      if (rightPressed) {
         playerX += xSpeed;
      }
      if(upPressed){
         playerY+=xSpeed;
      }
      if(downPressed){
         playerY-=xSpeed;
      }
   }

i tried that, 1st i had to use a real big number (xSpeed = 700 * delta) to have a reasonable movement and yet, the result are still the same,
thanx

Something else, you should have your player coordinates as floats ( don’t know if it’s the case here ) and also your xSpeed variable.

yes am using float variables

Player update method should be in the player, not the screen code - like the act() method if you’re using scene2d.

that seems correct from the design and OOP view, but is it really going to fix the flickering problem ??
(am not at home now, i can’t test it )
thanx

Remember that delta is usually a difference in time measured in seconds so all your movement is measured as “pixels-per-second” as opposed to “pixels-per-frame”.

guys i still can’t find a solution for the flickering issue :frowning:

those are my classes :

the general main class :


package com.me.mygdxgame;

import com.badlogic.gdx.Game;
import com.me.mygdxgame.Screen.SplashScreen;

public class MyGdxGame extends Game {

	public static final String VERSION = " alpha # 0.0.1";
	public static final String LOG = "";
	
	private SplashScreen splash = new SplashScreen(this);

	@Override
	public void create() {
		splash.init();
	
		setScreen(splash);
		
		
	}

	@Override
	public void dispose() {
		super.dispose();
	}

	@Override
	public void render() {
		super.render();
	}

	@Override
	public void resize(int width, int height) {
		super.resize(width, height);
	}

	@Override
	public void pause() {
		super.pause();
	}

	@Override
	public void resume() {
		super.resume();
	}
}


the Screen class :

package com.me.mygdxgame.Screen;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.me.mygdxgame.MyGdxGame;
import com.me.mygdxgame.entities.Player;

public class SplashScreen implements Screen {

	private MyGdxGame game;

	private boolean leftPressed, rightPressed, upPressed, downPressed;

	private Texture heroTexture;
	private Sprite heroSprite;
	private SpriteBatch batch;

	private Player player;
        private float xSpeed, ySpeed, xDirection, yDirection;
	
        public SplashScreen(MyGdxGame game) {
		this.game = game;
	}

	public void init() {
		System.out.println("the game is started");
		player = new Player(100, 100, 16, 16);
	}

	@Override
	public void render(float delta) {

		Gdx.gl.glClearColor(0.2f, 0.2f, 0.3f, 1);
		Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);

		control();
		player.update(xDirection, yDirection);

		heroSprite.setColor(1, 1, 1, 1);
		heroSprite.setX(player.getX());
		heroSprite.setY(player.getY());

		batch.begin();
		heroSprite.draw(batch);
		batch.end();
	}

	@Override
	public void resize(int width, int height) {
	}

	@Override
	public void show() {

		heroTexture = new Texture("data/heroRight.png");
		heroTexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
		heroSprite = new Sprite(heroTexture);

		batch = new SpriteBatch();
		
		xSpeed = 10;
		ySpeed = 10;
	}

	@Override
	public void hide() {
	}

	@Override
	public void pause() {
	}

	@Override
	public void resume() {
	}

	@Override
	public void dispose() {
	}

	private void control() {

		leftPressed = Gdx.input.isKeyPressed(Keys.DPAD_LEFT);

		rightPressed = Gdx.input.isKeyPressed(Keys.DPAD_RIGHT);

		upPressed = Gdx.input.isKeyPressed(Keys.DPAD_UP);

		downPressed = Gdx.input.isKeyPressed(Keys.DPAD_DOWN);

		if (rightPressed) {
			xDirection = xSpeed;
		} else if (leftPressed) {
			xDirection = -xSpeed;
		} else {
			xDirection = 0;
		}

		if (upPressed) {
			yDirection = ySpeed;
		} else if (downPressed) {
			yDirection = -ySpeed;
		} else {
			yDirection = 0;
		}
	}

}

the player class :

package com.me.mygdxgame.entities;

/**
 * this class will hanle the player properties
 */

public class Player {

	private float x, y, width, height;

	public Player(float x, float y, float width, float height) {
		this.x = x;
		this.y = y;
		this.width = width;
		this.height = height;
	}

	// setting values
	public void setX(float x) {
		this.x = x;
	}

	public void setY(float y) {
		this.y = y;
	}

	public void setWidth(float width) {
		this.width = width;
	}

	public void setHeight(float height) {
		this.height = height;
	}

	// getting values
	public float getX() {
		return this.x;
	}

	public float getY() {
		return this.y;
	}

	public float getWidth() {
		return this.width;
	}

	public float getHeight() {
		return this.height;
	}

	public void update(float xSpeed, float ySpeed) {

		this.x += xSpeed;
		this.y += ySpeed;

	}
}


the desktop main class :

package com.me.mygdxgame;

import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;

public class Main {
	public static void main(String[] args) {
		
		LwjglApplicationConfiguration cfg = new LwjglApplicationConfiguration();
		
		cfg.title = "Hello libGdx" + MyGdxGame.VERSION;
		cfg.useGL20 = false;
		cfg.width = 800;
		cfg.height = 600;
		cfg.resizable = true;

		new LwjglApplication(new MyGdxGame(), cfg);
	}
}

PS :
i know that i may not be using delta when i call the update method from the player class, but even when i did (player.update(1000*delta) ) the game still have the same issue
any advice please ?

thank you

If the render loop is capped to 60fps (and your monitor probably as well if you dont have a newer one with 120Hz or an ancient crt display) the maximum number of different visible screens are 60, but you are moving with 600 pixel per second, so you can never see a fluid movement at that speed. Even if you would break it down to update(1) and render at 600fps.

any suggestion to fix that please ??
thank you

Btw, instead of this:

public void update(float xSpeed) {
      if (SplashScreen.leftPressed) {
         this.x -= xSpeed;

      }
      if (SplashScreen.rightPressed) {
         x += xSpeed;
      }
      if (SplashScreen.upPressed) {
         y += xSpeed;
      }
      if (SplashScreen.downPressed) {
         y -= xSpeed;
      }
   }

Do not get used to such cross dependencies, bad style.

Just hand in x and y speed, which are zero in case of no movement. Let some kind of an input listener decide what speed to set on which key event.

public void update(float xSpeed, float ySpeed)

@65K
thank you
(code edited)