Using BufferStrategy But Still Got Flicker

Hi,

I am using the game loop in the tutorial basic game, which uses BufferStrategy, but when I render my world I still get flicker.
If any one could help I would appreciate it. Loop source code:


public class Planetoids implements Runnable {

	public static int xOffs = 0, yOffs = 0;

	public final int WIDTH = 800;
	public final int HEIGHT = 600;

	private PlanetEarth earth;

	private JFrame frame;
	private Canvas canvas;
	private BufferStrategy bufferStrategy;

	public Planetoids() {
		frame = new JFrame("Planetoids Pre-Alpha 0.0.1");

		JPanel panel = (JPanel) frame.getContentPane();
		panel.setPreferredSize(new Dimension(WIDTH, HEIGHT));
		panel.setLayout(null);

		canvas = new Canvas();
		canvas.setBounds(0, 0, WIDTH, HEIGHT);
		canvas.setIgnoreRepaint(true);

		panel.add(canvas);

		canvas.addKeyListener(new InputManager());

		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.pack();
		frame.setResizable(false);
		frame.setVisible(true);
		frame.setLocationRelativeTo(null);

		canvas.createBufferStrategy(2);
		bufferStrategy = canvas.getBufferStrategy();

		canvas.requestFocus();
		init();
	}

	private void init() {
		earth = new PlanetEarth(30,30);
		earth.map = PlanetGenerator.loadMap(30, 30);
	}

	long desiredFPS = 60;
	long desiredDeltaLoop = (1000 * 1000 * 1000) / desiredFPS;

	boolean running = true;

	public void run() {

		long beginLoopTime;
		long endLoopTime;
		long currentUpdateTime = System.nanoTime();
		long lastUpdateTime;
		long deltaLoop;

		while (running) {
			beginLoopTime = System.nanoTime();

			render();

			lastUpdateTime = currentUpdateTime;
			currentUpdateTime = System.nanoTime();
			update((int) ((currentUpdateTime - lastUpdateTime) / (1000 * 1000)));

			endLoopTime = System.nanoTime();
			deltaLoop = endLoopTime - beginLoopTime;

			if (deltaLoop > desiredDeltaLoop) {
				// Do nothing. We are already late.
			} else {
				try {
					Thread.sleep((desiredDeltaLoop - deltaLoop) / (1000 * 1000));
				} catch (InterruptedException e) {
					// Do nothing
				}
			}
		}
	}

	private void render() {
		Graphics g =  bufferStrategy.getDrawGraphics();
		g.clearRect(0, 0, WIDTH, HEIGHT);
		render(g);
		g.dispose();
		bufferStrategy.show();
	}

	protected void update(int deltaTime) {

	}

	protected void render(Graphics g) {
		earth.render(g);
	}

	public static void main(String[] args) {
		Planetoids ex = new Planetoids();
		new Thread(ex).start();
	}

}

The world render code:


public void render(Graphics g) {
		super.render(g);
		int x = 0, y = 0;
		for (int i = 0; i < map.length; i++) {
			if (x == width) {
				x = 0;
				y += 1;
			}
			switch (map[i]) {
			case Tile.TILE_EARTH_DIRT:
				g.drawImage(Tile.TILE_EARTH_DIRT_IMG, x * 32 + Planetoids.xOffs, y * 32 + Planetoids.yOffs, 32, 32, null);
				break;
			case Tile.TILE_EARTH_GRASS:
				g.drawImage(Tile.TILE_EARTH_GRASS_IMG, x * 32 + Planetoids.xOffs, y * 32 + Planetoids.yOffs, 32, 32, null);
				break;
			case Tile.TILE_EARTH_STONE:
				g.drawImage(Tile.TILE_EARTH_STONE_IMG, x * 32 + Planetoids.xOffs, y * 32 + Planetoids.yOffs, 32, 32, null);
				break;
			case Tile.TILE_EARTH_SAND:
				g.drawImage(Tile.TILE_EARTH_SAND_IMG, x * 32 + Planetoids.xOffs, y * 32 + Planetoids.yOffs, 32, 32, null);
				break;
			}
			x++;
		}
	}

Max

I see nothing wrong with the code. What kind of flickering do you see?

When I move about, up and left it flickers

Strangely now I only get flicker when moving up?

What kind of flickering are you talking about? Flickering means that it disappears for a frame or two then reappears. Maybe you mean it stutters, where it doesn’t move smoothly?

It’s unique that you use int for delta. Show us your class code that moving.

Or do you mean that the image isn’t VSynced (ie. you’re seeing a bit of the current frame and a bit of the previous one)? BufferStrategy isn’t guaranteed to be VSynced so this can result in flicker, depending on the system (which is?).

This is the movement code


public void keyPressed(KeyEvent key) {
		switch (key.getKeyCode()) {
		case KeyEvent.VK_ESCAPE:
			System.exit(0);
			break;
		case KeyEvent.VK_W:
			Planetoids.yOffs += Player.moveSpeed;
			break;
		case KeyEvent.VK_S:
			Planetoids.yOffs -= Player.moveSpeed;
			break;
		case KeyEvent.VK_A:
			Planetoids.xOffs += Player.moveSpeed;
			break;
		case KeyEvent.VK_D:
			Planetoids.xOffs -= Player.moveSpeed;
			break;
		}

When I move quite often white rectangles appear instead of the tiles.

:o Please tell me you load images once in a constructor/init method somewhere and don’t reload them every time you render!

I load them statically in a Tile class?


private static Image TILE_DIRT_IMG = new ImageIcon("res/grass.png").getImage();

Does this load them every time I call it??

Oh ok never mind that’s fine. Side note: It’s best to use javax.imageio.ImageIO by calling its read(URL) method. You get a URL using ClassName.class.getClassLoader().getResource(“res/grass.png”);

Hmm white rectangles popping randomly or predictably?

Are there any other rendering codes?

Looking on your moving code inside KeyAdapter class, I guess you move hardly, one tile per keypress. If you want a smooth one, you should use delta to calculate the movement little by little each frame.

Like ?


Planetoids.xOffs += Player.moveSpeed * delta

Thanks, This seems to have stopped the flicker"! :slight_smile:

Yes inside your entity class, that’s normally what we do for continuous movement. If, in your case you want “blocky” move then yours is right. Just I can’t imagine if it’ll flicking.

Well I think it must of been that as it is now perfect :slight_smile:

I still don’t understand how blocky movement == flicker :stuck_out_tongue:

Someone needs to make a FAQ for this. How are we supposed to help people when they can’t describe the problem? =S

+1, let’s see how many threads that asking same problem again and again.