The flickering doesnt always happen, but when it does (about 50% of time) its very bad. I tried doing a few things, initialy i was using canvas then i tried changing to jpanel and overriding paintcomponent, but the problem continues.
Im using two different methods to paint, that i call on my main loop (the first one paints a background terrain and the second one paints images on top of it) at 60 fps.
This is how i created the Jpanel:
private void createDisplay(){
frame = new JFrame(title); //linha mais importante, é criada uma JFrame com as propriedades definidas em baixo
frame.setSize(width, height); //tamanho
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //linha necessário para que a operação acabe quando se sai da janela
frame.setResizable(false); //remove a opção de alterar o tamanho da janela
frame.setLocationRelativeTo(null); //definição da posição relativa, neste caso nula
frame.setVisible(true); //torna a janela visivel
canvas = new JPanel();
//canvas = new Canvas(); //inicialização da canvas
canvas.setPreferredSize(new Dimension(width, height)); //alteração do tamanho da canvas
canvas.setMaximumSize(new Dimension(width, height)); //tamanho máximo e minimo são definidos para que a
canvas.setMinimumSize(new Dimension(width, height)); //canvas tenha sempre o mesmo tamanho
frame.add(canvas); //linha essencial, adicina a canvas á jframe
frame.pack(); //necessário para que a canvas fique bemcentrada na frame (para que se veja toda a canvas)
frame.addMouseListener(new MouseInput());
canvas.addMouseListener(new MouseInput());
}
This is part of my main class loop where i invoke the paint methods:
@Override
public void run() {
init();
Terrain.init();
int fps = 60;
double timePerTick = 1000000000 / fps;
double delta = 0;
long now;
long lastTime = System.nanoTime();
@SuppressWarnings("unused")
int ticks = 0;
long timer = 0;
while(running) {
now = System.nanoTime();
delta += (now - lastTime) / timePerTick;
timer += now - lastTime;
lastTime = now;
if(delta >= 1){
gamepack.Terrain.paintComponent(g);
gamepack.Units.tick();
gamepack.Enemy.tick();
//gamepack.Enemy.render();
gamepack.Render.paintComponent(g);
ticks++;
delta--;
}
if(timer >= 1000000000){
//System.out.println(ticks); Verificação das actualizações (ticks e render por segundo)
ticks = 0;
timer = 0;
}
}
stop();
}
This is the first paint method for the terrain (its very long i only included the first part):
public static void paintComponent(Graphics g) {
// bs = Display.getCanvas().getBufferStrategy();
//if(bs==null) {
// Display.getCanvas().createBufferStrategy(3);
// return;
//}
g = Display.getCanvas().getGraphics();
g.clearRect(0, 0, 510, 510);
//Primeira Linha (1)
g.drawImage(grasstopleftcorner ,0,0, null); //1
g.drawImage(grasstopleftcorner ,34,0, null); //2
g.drawImage(path ,68,0, null); //3
g.drawImage(path ,102,0, null); //4
g.drawImage(grasstopleftcorner ,136,0, null); //5
g.drawImage(grasstopleftcorner ,170,0, null); //6
g.drawImage(grasstopleftcorner ,204,0, null); //7
g.drawImage(grasstopleftcorner ,238,0, null); //8
g.drawImage(grasstopleftcorner ,272,0, null); //9
g.drawImage(grasstopleftcorner ,306,0, null); //10
g.drawImage(grasstopleftcorner ,340,0, null); //11
g.drawImage(grasstopleftcorner ,374,0, null); //12
g.drawImage(grasstopleftcorner ,408,0, null); //13
g.drawImage(grasstopleftcorner ,442,0, null); //14
g.drawImage(grasstopleftcorner ,476,0, null); //15
//Segunda Linha (2)
g.drawImage(grasstopleftcorner ,0,34, null); //1
g.drawImage(grasstopleftcorner ,34,34, null); //2
g.drawImage(path ,68,34, null); //3
g.drawImage(path ,102,34, null); //4
g.drawImage(grasstopleftcorner ,136,34, null); //5
g.drawImage(grasstopleftcorner ,170,34, null); //6
g.drawImage(grasstopleftcorner ,204,34, null); //7
g.drawImage(grasstopleftcorner ,238,34, null); //8
g.drawImage(grasstopleftcorner ,272,34, null); //9
g.drawImage(grasstopleftcorner ,306,34, null); //10
g.drawImage(grasstopleftcorner ,340,34, null); //11
g.drawImage(grasstopleftcorner ,374,34, null); //12
g.drawImage(grasstopleftcorner ,408,34, null); //13
g.drawImage(grasstopleftcorner ,442,34, null); //14
g.drawImage(grasstopleftcorner ,476,34, null); //15
And this is the last paint method for the images to be painted on top of the terrain (or background):
public static void paintComponent(Graphics g){
//Código Comum a todas as Classes
//bs = Display.getCanvas().getBufferStrategy();
//if(bs==null) {
/// Display.getCanvas().createBufferStrategy(3);
// return;
//}
g = Display.getCanvas().getGraphics();
//g.clearRect(0, 0, 510, 510);
//Enemies
p=0;
//Este while serve para actualizar as imagens de todas as unidades ao incrementar o p, todas as variáveis do drawimage são actualizadas no tick()
while(p<Main.enemylist.size()){
if(Main.enemylist.get(p).health > 0){
// g.drawImage(Main.castleimg,(int) 100,(int)100, null);
g.drawImage(Main.enemylist.get(p).usedimg.getSubimage(Main.enemylist.get(p).imgx*32, Main.enemylist.get(p).imgy*32 , 32, 32),(int) Main.enemylist.get(p).targetx - 16,(int) Main.enemylist.get(p).targety- 16, null);
}
p++;
}
//Units
p=0;
//Este while serve para actualizar as imagens de todas as unidades ao incrementar o p, todas as variáveis do drawimage são actualizadas no tick()
while(p<Main.dudelist.size()){
if(Main.dudelist.get(p).selected){
g.drawImage(Main.dotimage,(int) Main.dudelist.get(p).currentx + 7,(int) Main.dudelist.get(p).currenty - 19, null);
}
if (Main.dudelist.get(p).health > 0){
// g.drawImage(Main.castleimg,(int) 100,(int)100, null);
g.drawImage(Main.dudelist.get(p).usedimg.getSubimage(Main.dudelist.get(p).imgx*32, Main.dudelist.get(p).imgy*32 , 32, 32),(int) Main.dudelist.get(p).currentx ,(int) Main.dudelist.get(p).currenty, null);
}
p++;
}
g.dispose();
}
I hope i explained my problem well and that i included all thats needed, im fairly new to java and programming, hopefully it wasnt very confusing.