Note that there are some explanatory texts on larger screens.

plurals
  1. POFlickering images in JPanel
    text
    copied!<p>I have created a game which paints images to a JPanel. This runs with a JTimer which executes every 14 milliseconds to move the background, moves obstacles and moves the player (helicopter). I get flickering of the background and of the obstacles occasionally, and it does not run particularly smoothly. Is there a way I can get around this? Do I need to use threads and animate in a different class? I also used double buffering, but then I found out that JPanels are double buffered anyway, so I removed it.</p> <p>Here is the code from the Panel class.</p> <pre><code>class ImagePanel extends JPanel implements KeyListener, MouseListener, MouseMotionListener { /** * */ private static final long serialVersionUID = -6096603231469523786L; Plane o1 = new Plane(); Tank o2 = new Tank(); ArrayList&lt;Plane&gt; planeArray; ArrayList&lt;Tank&gt; tankArray; ArrayList&lt;Missile&gt; missileArray; int bgx; int bgxTwo; int time; int y; int score; int obsNum; int obsNum2; int planeSpeed; int missileSpeed; int count; boolean holding; boolean gameOver; boolean startscreen; boolean shooting; boolean obsOne = false; boolean obsTwo = false; Color colorone = Color.WHITE; Color colortwo = Color.WHITE; Color restartColor = Color.white; Color menuColor = Color.white; Color bulletColor = Color.white; Font f1; Font f2; Font f3; String version = "Get To The Chopper Beta 1.2"; int level = 1; java.util.Timer movementtimer; TimerTask task; java.util.Timer obstacletimer; TimerTask taskTwo; private Image image; private Image imageTwo; private Image chopper; private Image chopper2; private Image tank; private Image plane; private Image missile; private Image explosion; BufferedImage bufferedImage; Graphics buffer; java.net.URL bgurl; java.net.URL curl; java.net.URL c2url; java.net.URL turl; java.net.URL purl; java.net.URL murl; java.net.URL eurl; // ///////// CONSTRUCTOR SETS NON-CHANGABLE VARIABLES //////////////// public ImagePanel() { setFocusable(true); addKeyListener(this); addMouseListener(this); addMouseMotionListener(this); f1 = new Font("Helvetica", Font.BOLD, 10); f2 = new Font("Helvetica", Font.PLAIN, 30); f3 = new Font("Helvetica", Font.PLAIN, 25); startscreen = true; getImages(); planeArray = new ArrayList&lt;Plane&gt;(); tankArray = new ArrayList&lt;Tank&gt;(); missileArray = new ArrayList&lt;Missile&gt;(); repaint(); } public void getImages() { bgurl = getClass().getResource("images/background.png"); switch (level) { case (1): bgurl = getClass().getResource("images/grassbackground.png"); bulletColor = Color.black; break; case (2): bgurl = getClass().getResource("images/snowbackground.png"); bulletColor = Color.red; break; } curl = getClass().getResource("images/heli.png"); c2url = getClass().getResource("images/heli2.png"); turl = getClass().getResource("images/tank.png"); purl = getClass().getResource("images/plane.png"); murl = getClass().getResource("images/missile.png"); eurl = getClass().getResource("images/explosion.png"); try { image = Toolkit.getDefaultToolkit().getImage(bgurl); imageTwo = Toolkit.getDefaultToolkit().getImage(bgurl); chopper = Toolkit.getDefaultToolkit().getImage(curl); chopper2 = Toolkit.getDefaultToolkit().getImage(c2url); tank = Toolkit.getDefaultToolkit().getImage(turl); plane = Toolkit.getDefaultToolkit().getImage(purl); missile = Toolkit.getDefaultToolkit().getImage(murl); explosion = Toolkit.getDefaultToolkit().getImage(eurl); } catch (Exception ex) { System.out.println("File Not Found"); } } // //////// SETS VARIABLES WHEN GAME IS STARTED OR RESTARTED // ////////////////// public void startGame() { bgx = 0; bgxTwo = 800; y = 50; score = 0; holding = false; gameOver = false; time = (int) (Math.random() * 500 + 500); obsNum2 = 0; shooting = false; count = 1; planeSpeed = -6; missileSpeed = -7; planeArray.clear(); tankArray.clear(); missileArray.clear(); colorone = Color.WHITE; colortwo = Color.WHITE; restartColor = Color.white; menuColor = Color.white; movementtimer = new java.util.Timer(); task = new TimerTask() { public void run() { moveImage();repaint(); } }; movementtimer.schedule(task, 0, 13); obstacletimer = new java.util.Timer(); taskTwo = new TimerTask() { public void run() { generateObstacle(); } }; obstacletimer.schedule(taskTwo, 2000, time); } // ////////// COLLISION DETECTION ////////////////// public void moveImage() { moveBackground(); addToScore(); if (holding) { y += -3; } else { y += 3; } for (int i = 0; i &lt; planeArray.size(); i++) { Plane plane = planeArray.get(i); if (y + 30 &gt;= plane.yPos &amp;&amp; y + 30 &lt;= plane.yPos + 30 &amp;&amp; plane.xPos &gt;= 200 &amp;&amp; plane.xPos &lt;= 250 || y &gt;= plane.yPos &amp;&amp; y &lt;= plane.yPos + 30 &amp;&amp; plane.xPos &gt;= 200 &amp;&amp; plane.xPos + 50 &lt;= 250) { gameOver = true; System.out.println("Crash with plane!"); } } for (int i = 0; i &lt; tankArray.size(); i++) { Tank tank = tankArray.get(i); if (y + 30 &gt;= tank.yPos &amp;&amp; y + 30 &lt;= tank.yPos + 30 &amp;&amp; tank.xPos &gt;= 200 &amp;&amp; tank.xPos &lt;= 250 || y &gt;= tank.yPos &amp;&amp; y &lt;= tank.yPos + 30 &amp;&amp; tank.xPos &gt;= 200 &amp;&amp; tank.xPos + 50 &lt;= 250) { gameOver = true; System.out.println("Crash with a tank"); } if (shooting) { if (y + 30 &gt;= tank.bulletYPos &amp;&amp; y &lt;= tank.bulletYPos &amp;&amp; tank.bulletXPos &gt;= 200 &amp;&amp; tank.bulletXPos &lt;= 250) { gameOver = true; System.out.println("Shot down"); } } } for (int i = 0; i &lt; missileArray.size(); i++) { Missile missile = missileArray.get(i); if (y + 30 &gt;= missile.yPos &amp;&amp; y + 30 &lt;= missile.yPos + 30 &amp;&amp; missile.xPos &gt;= 200 &amp;&amp; missile.xPos &lt;= 250 || y &gt;= missile.yPos &amp;&amp; y &lt;= missile.yPos + 30 &amp;&amp; missile.xPos &gt;= 200 &amp;&amp; missile.xPos + 50 &lt;= 250) { gameOver = true; System.out.println("Crash with a missile"); } } if (y &gt;= 300) { gameOver = true; } else if (y &lt;= -15) { gameOver = true; } } // //////// MOVES BACKGROUND ////////////// public void moveBackground() { bgx += -5; if (bgx == -800) { bgx = 800; } bgxTwo += -5; if (bgxTwo == -800) { bgxTwo = 800; } for (int i = 0; i &lt; planeArray.size(); i++) { Plane obs = planeArray.get(i); obs.xPos = obs.xPos - 6; } for (int i = 0; i &lt; tankArray.size(); i++) { Tank obs = tankArray.get(i); obs.xPos = obs.xPos - 5; if (shooting) { obs.bulletYPos = obs.bulletYPos - 2; obs.bulletXPos = obs.bulletXPos - obs.angle; } } for (int i = 0; i &lt; missileArray.size(); i++) { Missile obs = missileArray.get(i); obs.xPos = obs.xPos - 7; } } public void addToScore() { score += 5; increaseDiff(); } public void increaseDiff() { if (score == 10000) { shooting = true; for (int i = 0; i &lt; tankArray.size(); i++) { Tank tank = tankArray.get(i); tank.bulletXPos = tank.xPos; } } if (score &gt; 5000 &amp;&amp; score &lt; 9999) { time = (int) (Math.random() * 400 + 250); planeSpeed = -7; missileSpeed = -8; } else if (score &gt; 10000 &amp;&amp; score &lt; 14999) { time = (int) (Math.random() * 400 + 150); planeSpeed = -8; missileSpeed = -10; } else if (score &gt; 15000 &amp;&amp; score &lt; 19999) { time = (int) (Math.random() * 400 + 150); planeSpeed = -9; missileSpeed = -11; obsNum2 = (int) (Math.random() * 2 + 1); } else if (score &gt; 20000 &amp;&amp; score &lt; 29999) { time = (int) (Math.random() * 300 + 100); planeSpeed = -10; missileSpeed = -13; obsNum2 = (int) (Math.random() * 2 + 1); } else if (score &gt; 30000) { time = (int) (Math.random() * 300 + 100); planeSpeed = -12; missileSpeed = -15; obsNum2 = (int) (Math.random() * 2 + 1); } } public void generateObstacle() { obsNum = (int) (Math.random() * 5 + 1); if (obsNum == 1 || obsNum == 4 || obsNum2 == 1) { planeArray.add(new Plane()); } if (obsNum == 2) { tankArray.add(new Tank()); } if (obsNum == 3 || obsNum == 5 || obsNum2 == 2) { missileArray.add(new Missile()); } } public void update(Graphics g) { paint(g); } // /////////////// MAIN PAINT METHOD ////////////////////// @Override public void paint(Graphics g) { g.clearRect(0,0,800,400); if (!startscreen) { g.drawImage(image, bgx, 0, null); g.drawImage(imageTwo, bgxTwo, 0, null); for (int i = 0; i &lt; planeArray.size(); i++) { Plane obs = planeArray.get(i); if (obs.xPos &lt;= -50) { planeArray.remove(i); } else { g.drawImage(plane, obs.xPos, obs.yPos, null); } } for (int i = 0; i &lt; tankArray.size(); i++) { Tank obs = tankArray.get(i); if (obs.xPos &lt;= -50) { tankArray.remove(i); } else { g.drawImage(tank, obs.xPos, obs.yPos, null); if (shooting) { g.setColor(bulletColor); g.fillOval(obs.bulletXPos, obs.bulletYPos, 5, 5); } } } for (int i = 0; i &lt; missileArray.size(); i++) { Missile obs = missileArray.get(i); if (obs.xPos &lt;= -50) { missileArray.remove(i); } else { g.drawImage(missile, obs.xPos, obs.yPos, null); } } if (gameOver) { movementtimer.cancel(); obstacletimer.cancel(); g.setColor(Color.WHITE); g.setFont(f2); g.drawString("GAME OVER", 250, 150); g.setFont(f3); g.drawString("Your score: " + score, 250, 200); g.setColor(restartColor); g.drawString("Click to restart!", 250, 250); g.setColor(menuColor); g.drawString("Back to menu", 250, 300); g.drawImage(explosion, 200, y, this); } } else if (startscreen) { g.drawImage(image, 0, 0, this); g.drawImage(imageTwo, 0, 0, this); g.drawImage(chopper, 200, 50, this); g.setColor(Color.WHITE); g.setFont(f2); g.drawString("Choose a level:", 200, 150); g.setFont(f3); g.setColor(colorone); g.drawString("Grass Level!", 250, 200); g.setColor(colortwo); g.drawString("Snow Level!", 250, 250); } if (count &lt;= 9 &amp;&amp; !gameOver &amp;&amp; !startscreen) { g.drawImage(chopper, 200, y, this); count++; } else if (count &gt;= 10 &amp;&amp; count &lt; 20 &amp;&amp; !gameOver &amp;&amp; !startscreen) { g.drawImage(chopper2, 200, y, this); count++; } else if (count == 20 &amp;&amp; !gameOver &amp;&amp; !startscreen) { count = 1; g.drawImage(chopper, 200, y, this); } g.setFont(f1); g.setColor(Color.WHITE); g.drawString(version, 10, 10); g.drawString("Score: " + score + "", 700, 10); } // ///////////////////OVERRIDE KEYPRESSED EVENTS////////////////////// @Override public void keyPressed(KeyEvent e) { // TODO Auto-generated method stub if (e.getKeyCode() == 32) { holding = true; repaint(); } } @Override public void keyReleased(KeyEvent e) { // TODO Auto-generated method stub if (e.getKeyCode() == 32) { holding = false; repaint(); } } @Override public void keyTyped(KeyEvent e) { // TODO Auto-generated method stub } public void mousePressed(MouseEvent e) { if (e.getX() &gt;= 250 &amp;&amp; e.getX() &lt;= 400 &amp;&amp; e.getY() &gt;= 180 &amp;&amp; e.getY() &lt;= 200 &amp;&amp; startscreen) { startscreen = false; level = 1; getImages(); startGame(); } if (e.getX() &gt;= 250 &amp;&amp; e.getX() &lt;= 400 &amp;&amp; e.getY() &gt;= 230 &amp;&amp; e.getY() &lt;= 250 &amp;&amp; startscreen) { startscreen = false; level = 2; getImages(); startGame(); } if (e.getX() &gt;= 250 &amp;&amp; e.getX() &lt;= 420 &amp;&amp; e.getY() &gt;= 230 &amp;&amp; e.getY() &lt;= 250 &amp;&amp; gameOver) { startGame(); } if (e.getX() &gt;= 250 &amp;&amp; e.getX() &lt;= 420 &amp;&amp; e.getY() &gt;= 280 &amp;&amp; e.getY() &lt;= 320 &amp;&amp; gameOver) { gameOver = false; startscreen = true; repaint(); } } @Override public void mouseClicked(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mouseEntered(MouseEvent e) { // TODO Auto-generated method stub } public void mouseMoved(MouseEvent e) { if (e.getX() &gt;= 250 &amp;&amp; e.getX() &lt;= 400 &amp;&amp; e.getY() &gt;= 180 &amp;&amp; e.getY() &lt;= 200 &amp;&amp; startscreen) { colorone = Color.RED; repaint(); } else if (e.getX() &gt;= 250 &amp;&amp; e.getX() &lt;= 400 &amp;&amp; e.getY() &gt;= 230 &amp;&amp; e.getY() &lt;= 250 &amp;&amp; startscreen) { colortwo = Color.RED; repaint(); } else if (startscreen) { colorone = Color.white; colortwo = Color.white; repaint(); } if (e.getX() &gt;= 250 &amp;&amp; e.getX() &lt;= 420 &amp;&amp; e.getY() &gt;= 230 &amp;&amp; e.getY() &lt;= 250 &amp;&amp; gameOver) { restartColor = Color.red; repaint(); } else if (e.getX() &gt;= 250 &amp;&amp; e.getX() &lt;= 420 &amp;&amp; e.getY() &gt;= 280 &amp;&amp; e.getY() &lt;= 320 &amp;&amp; gameOver) { menuColor = Color.red; repaint(); } else if (gameOver) { restartColor = Color.white; menuColor = Color.white; repaint(); } } @Override public void mouseExited(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mouseReleased(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mouseDragged(MouseEvent arg0) { // TODO Auto-generated method stub } } </code></pre> <p>Sorry about all the code, as you may be able to tell, I am new to Java and programming in general (started last year at college), but it is something I wish to progress with and make a career out of.</p> <p>Thanks Tom</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload