To be honest, I'm not to sure how to describe my problem, you can see it here. In that video of my code running, it is most prominent in the first few seconds.
Occasionally and randomly I am getting a weird flickery/stuttery/laggy glitch in my moving pipe across the screen, I've been trying to sort it out for 3 days now and I truly have no idea why it is occurring.. I have tested my code on other computers and the same happens! As this has been happening I have remained at 60fps.
Does anyone know why this would be occurring...?
My code: (I know this code is bad, its a rushed example) It will probably take a few tries to experience the same bug that I am facing......
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
public class Test extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
private static int width = 300 - 80;
private static int height = 168;
private static int scale = 3;
public static String title = "Test";
private Thread thread;
private JFrame frame;
private boolean running = false;
private BufferedImage image;
public Test() {
setPreferredSize(new Dimension(width * scale, height * scale));
frame = new JFrame();
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
}
public static int getWindowWidth() {
return width * scale;
}
public static int getWindowHeight() {
return height * scale;
}
public synchronized void start() {
running = true;
thread = new Thread(this);
thread.start();
}
public synchronized void stop() {
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run() {
long lastTime = System.nanoTime();
long timer = System.currentTimeMillis();
final double ns = 1000000000.0 / 60.0;
double delta = 0;
int frames = 0;
int updates = 0;
requestFocus();
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while (delta >= 1) {
update();
updates++;
delta--;
render();
frames++;
}
if (System.currentTimeMillis() - timer > 1000) {
timer += 1000;
System.out.println(updates + " tps, " + frames + " fps");
updates = 0;
frames = 0;
}
}
stop();
}
int x = width;
static BufferedImage img;
static {
try {
img = ImageIO.read(Test.class.getResource("/pipe.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
public void update() {
if (x + 30 <= -1) x = width;
else x-=2;
}
public void draw(Graphics2D g2)
{
g2.setColor(Color.red);
g2.drawImage(img, x, 10, 30, 90, null);
}
public void render() {
BufferStrategy bs = getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
drawToImage();
Graphics g = bs.getDrawGraphics();
g.setColor(new Color(0xff00ff));
g.fillRect(0, 0, getWidth(), getHeight());
g.drawImage(image, 0, 0, width * scale, height * scale, null);
g.dispose();
bs.show();
}
public void drawToImage()
{
Graphics2D g2 = (Graphics2D) image.getGraphics();
g2.clearRect(0, 0, width, height);
draw(g2);
g2.dispose();
}
public static void main(String[] args) {
Test game = new Test();
game.frame.setResizable(false);
game.frame.setTitle(Test.title);
game.frame.add(game);
game.frame.pack();
game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
game.frame.setLocationRelativeTo(null);
game.frame.setVisible(true);
game.start();
}
}
EDIT: Paint component code that produces same result:
import javax.swing.*;
import java.awt.*;
public class GamePanel extends JPanel implements Runnable
{
private int WIDTH = 200 * 4;
private int HEIGHT = 150 * 4;
int playerX = 30;
int playerY = 30;
Thread gameThread;
public GamePanel()
{
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setBackground(Color.BLACK);
setDoubleBuffered(true);
}
public void startGameThread()
{
this.gameThread = new Thread(this);
this.gameThread.start();
}
public void update()
{
this.playerX+= 5;
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.WHITE);
g2.fillRect(playerX, playerY, 32, 32);
g2.dispose();
}
@Override
public void run()
{
double drawInterval = 1000000000/60;
double delta = 0;
long lastTime = System.nanoTime();
long currentTime;
long timer = 0;
int drawCount = 0;
while (gameThread != null)
{
currentTime = System.nanoTime();
delta += (currentTime - lastTime) / drawInterval;
timer += (currentTime - lastTime);
lastTime = currentTime;
if (delta >= 1)
{
update();
repaint();
drawCount++;
delta--;
}
if (timer >= 1000000000)
{
System.out.println("FPS: " + drawCount);
drawCount = 0;
timer = 0;
}
}
}
public static void main(String[] args)
{
System.setProperty("sun.java2d.opengl", "true");
JFrame window = new JFrame();
window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
window.setResizable(false);
window.setTitle("Test");
GamePanel gamePanel = new GamePanel();
window.add(gamePanel);
window.pack();
window.setVisible(true);
gamePanel.startGameThread();
}
}