My game is flickering like hell ??

Am creating a 2D spaceship shooter but am having this problem with my spaceship flickering like hell. How can I solve this?


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;


class Raptor extends JFrame implements KeyListener
{
      Graphics2D g;
      JLabel raptorL;
      Thread loop;
      
      int x=400;
      int y=400;
      
      int skudXStart1=0;
      int skudYStart1=0;
      int skudXSlut1=0;
      int skudYSlut1=0;
      
      int skudXStart2=0;
      int skudYStart2=0;
      int skudXSlut2=0;
      int skudYSlut2=0;      
      
      boolean right,left,space;
            
      
      int enemy1x=600;
      int enemy1y=-100;
      
      Raptor()
      {
            addKeyListener(this);            
      
        setBounds(100,50,800,600);
        setVisible(true);            
      }
      public void paint(Graphics g1)
      {
            super.paint(g1);
            g = (Graphics2D) g1;
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g.drawImage((new ImageIcon("raptorSmall.gif")).getImage(),x,y,this); 
        g.setColor(Color.red);
        g.drawLine(skudXStart1,skudYStart1,skudXSlut1,skudYSlut1); 
        g.drawLine(skudXStart2,skudYStart2,skudXSlut2,skudYSlut2);   
        
        g.drawImage((new ImageIcon("Enemy1.gif")).getImage(),enemy1x,enemy1y,this);            

          loop = new Thread(new Runnable()            
          { 
             public void run()
             { 
      
                            if(right)
                            {
                               x+=1;
                            }
                            if(left)
                            {
                               x-=1;
                            }
                              if(space)
                              {                                                      
                             skudYStart1-=5;
                               skudYSlut1-=5;
                               
                             skudYStart2-=5;
                               skudYSlut2-=5;                         
                            }
                            
                            try{      
                            Thread.sleep(5000);          
                            }catch(InterruptedException a){System.out.println(a);}      

                               enemy1x-=1;
                               enemy1y+=1;        
                        
                                                         
             }
          });
          loop.start();   

        repaint();     
      }
      public void keyPressed(KeyEvent e) 
      {

            if(e.getKeyCode() == KeyEvent.VK_LEFT)
            {
             left=true;                   
            } 
            if(e.getKeyCode() == KeyEvent.VK_RIGHT)
            {               
               right=true;                         
            } 
        if(e.getKeyCode() == KeyEvent.VK_SPACE && skudYStart1 <= 0)
        {
              //System.out.println(skudYStart1);
              
                skudXStart1=x+20;
            skudYStart1=y+30;
            skudXSlut1=x+20;
              skudYSlut1=450;              
              
                skudXStart2=x+78;
            skudYStart2=y+30;
            skudXSlut2=x+78;
              skudYSlut2=450;                      
             
              space=true;
         
        }                              
      }
      public void keyReleased(KeyEvent e)
      {            

            
            if(e.getKeyCode() == KeyEvent.VK_LEFT)
            {
             left=false;      
            } 
            if(e.getKeyCode() == KeyEvent.VK_RIGHT)
            {               
               right=false;      
            } 
        if(e.getKeyCode() == KeyEvent.VK_SPACE)
        {      
           //space=false;      
           //loop=null;
        }      
                  
      }
      public void keyTyped(KeyEvent e){}
      
      public static void main(String[] aslan)
      {
            new Raptor();
      }
}

Ahh! My brain exploded! heh, just kidding, lemme see here…

Looks like every time you paint, a new thread is started, is that the right design? Also, every time you paint, you are creating a whole new ImageIcon. Maybe that could be pre-loaded?

Anyways, I think the main problem you are having is that the default implementation of update(Graphics g) is to do a clearRect of the display area before paint is called (hence, you flicker) Just rename your paint() method to update() and see how that goes.

Also, repaint() isn’t going to do what you expect, repaint() just ‘asks’ the toolkit to please redraw it when it’s convienent, but this will make any animation or time-related drawing (such as game programming) run like ass. So, take that repaint out of there and find another way (hint, have a main game loop thread that will call the paint routines at defined intervals.)

-Chris

Here is a version that should eliminate most of the flickering and run much smoother. It should also be easy to convert to full screen exclusive mode. Note: I based this on the original code you posted to forums.java.sun.com.

Rick


import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.image.*;


class Raptor extends JFrame implements KeyListener{
      Graphics2D g;
      JLabel raptorL;
      Timer loop;
      int x=400;
      int y=400;
      int skudXStart1=0;
      int skudYStart1=0;
      int skudXSlut1=0;
      int skudYSlut1=0;
      int skudXStart2=0;
      int skudYStart2=0;
      int skudXSlut2=0;
      int skudYSlut2=0;
      boolean right,left,space;
      Image raptorImage = null;
      Image buffer = null;
      BufferStrategy bs = null;
      Rectangle bounds = null;

      Raptor() {
            addKeyListener(this);
            setBounds(100,50,800,600);
            bounds = getBounds();
        setVisible(true);
      }

      private void render(Graphics g1){
            g = (Graphics2D) g1;
            Color c = g.getColor();
            g.clearRect(0,0,(int)bounds.getWidth(),(int)bounds.getHeight());
      //      g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        if ( raptorImage == null ){
                  System.out.println("Loading raptor image");
                  Image tempImage = new ImageIcon("raptorSmall.gif").getImage();
                  MediaTracker mt = new MediaTracker(this);
                  mt.addImage(tempImage,0);
                  try {
                        mt.waitForID(0);
                        mt.removeImage(tempImage,0);
                  } catch ( InterruptedException e ){
                        e.printStackTrace();
                  }
                  raptorImage = createImage(tempImage.getWidth(null), tempImage.getHeight(null));
                  Graphics g = raptorImage.getGraphics();
                  g.drawImage(tempImage,0,0,null);
                  g.dispose();
            }
        g.drawImage(raptorImage,x,y,this);
        g.setColor(Color.red);
        g.drawLine(skudXStart1,skudYStart1,skudXSlut1,skudYSlut1);
        g.drawLine(skudXStart2,skudYStart2,skudXSlut2,skudYSlut2);
        if ( space ){
                  skudYStart1-=5;
                  skudYSlut1-=5;
                  skudYStart2-=5;
                  skudYSlut2-=5;
                  if ( skudYStart1 <= 0 ){
                        space = false;
                  }
            }
            if ( left ){
                  x -= 1;
            }
            if ( right ){
                  x += 1;
            }
      }

      public void run(){
            while(true){
                  if ( bs == null ){
                        createBufferStrategy(2);
                        bs = getBufferStrategy();
                  }
                  Graphics g = bs.getDrawGraphics();
                  render(g);
                  bs.show();
                  g.dispose();
            }
      }

      public void paint(Graphics g1)      {
            super.paint(g1);
            render(g1);

      }

      public void keyPressed(KeyEvent e)       {
            if(e.getKeyCode() == KeyEvent.VK_ESCAPE ) {
                  System.exit(0);
            }
            if(e.getKeyCode() == KeyEvent.VK_LEFT) {
                  left=true;
            }
            if(e.getKeyCode() == KeyEvent.VK_RIGHT)      {
                  right=true;
                  x+=1;
            }
            if(e.getKeyCode() == KeyEvent.VK_SPACE) {
                  if (skudYStart1 <= 0){
                        skudXStart1=x+20;
                        skudYStart1=y+30;
                        skudXSlut1=x+20;
                        skudYSlut1=450;
                        skudXStart2=x+78;
                        skudYStart2=y+30;
                        skudXSlut2=x+78;
                        skudYSlut2=450;
                  }
                  space=true;

            }
    }

      public void keyReleased(KeyEvent e)      {
            if(e.getKeyCode() == KeyEvent.VK_LEFT){
                  left=false;
            }
            if(e.getKeyCode() == KeyEvent.VK_RIGHT){
                  right=false;
            }
            if(e.getKeyCode() == KeyEvent.VK_SPACE){
                  //space=false;
            }
      }

      public void keyTyped(KeyEvent e){}

      public static void main(String[] aslan)      {
            new Raptor().run();
      }
}

Question: is it possible to just get the Graphics2D via getGraphics of the bufferStrategy once and not need to dispose() every iteration (I thought that getting and destroying could lead to a lot of garbage) or does the buffer strategy basically require that every render frame you get graphics->draw->dispose?

-Chris

Thx alot Chris and Rick for your answers… Specially Rick for your very nice improvedment of my code. I will go through your changes and try to understand them :slight_smile:

Now I have this question…
I want a enemy spaceship to fly against the spaceship efter some delay, how do I do this? The way the code is now the enemy spaceship does this without any delay…


import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
import java.awt.image.*; 
 
 
class Raptor extends JFrame implements KeyListener
{ 

       Graphics2D g; 
       Timer loop; 
       
       int x=400; 
       int y=400; 
       int skudXStart1=0; 
       int skudYStart1=0; 
       int skudXSlut1=0; 
       int skudYSlut1=0; 
       int skudXStart2=0; 
       int skudYStart2=0; 
       int skudXSlut2=0; 
       int skudYSlut2=0;        
       boolean right,left,space; 
       Image raptorImage = null; 
       
       Image enemy1 = null;
       int enemy1x = 500;
       int enemy1y = -50;
       
       BufferStrategy bs = null; 
       Rectangle bounds = null; 
 
     Raptor()
     { 
        addKeyListener(this); 
        setBounds(100,50,800,600); 
        bounds = getBounds(); 
        setVisible(true); 
     } 
 
     private void render(Graphics g1)
     { 
            g = (Graphics2D) g1; 
            g.clearRect(0,0,(int)bounds.getWidth(),(int)bounds.getHeight()); 
            
            if(raptorImage == null)
            {  
                       
                   Image tempImage = new ImageIcon("raptorSmall.gif").getImage();             
                   raptorImage = createImage(tempImage.getWidth(null), tempImage.getHeight(null)); 
                   Graphics g = raptorImage.getGraphics(); 
                   g.drawImage(tempImage,0,0,null); 
                   g.dispose(); 
                   
            }             
            g.drawImage(raptorImage,x,y,this); 
            g.setColor(Color.red); 
            g.drawLine(skudXStart1,skudYStart1,skudXSlut1,skudYSlut1); 
            g.drawLine(skudXStart2,skudYStart2,skudXSlut2,skudYSlut2);             
            if (space)
            { 
                  skudYStart1-=5; 
                  skudYSlut1-=5; 
                  skudYStart2-=5; 
                  skudYSlut2-=5; 
            
            if (skudYStart1 <= 0)
            { 
                space = false; 
            } 
        } 
        if (left)
        { 
            x -= 1; 
        } 
        if (right)
        { 
            x += 1; 
        } 
        
        if(enemy1 == null)
        {
              Image tempImage2 = new ImageIcon("Enemy1.gif").getImage();
              enemy1 = createImage(tempImage2.getWidth(null), tempImage2.getHeight(null)); 
              Graphics g = enemy1.getGraphics(); 
                  g.drawImage(tempImage2,0,0,null); 
                  g.dispose();               
        }
        g.drawImage(enemy1,enemy1x,enemy1y,this); 
        enemy1x-=1;
        enemy1y+=1;
     } 
     public void run()
     { 
        while(true)
        { 
           if (bs == null)
           { 
              createBufferStrategy(2); 
              bs = getBufferStrategy(); 
           } 
           Graphics g = bs.getDrawGraphics(); 
           render(g); 
           bs.show(); 
           g.dispose(); 
        } 
     } 
 
     public void paint(Graphics g1)
     { 
         super.paint(g1); 
         render(g1); 
     } 
 
     public void keyPressed(KeyEvent e)
     { 
           if(e.getKeyCode() == KeyEvent.VK_ESCAPE )
           { 
              System.exit(0); 
           } 
           if(e.getKeyCode() == KeyEvent.VK_LEFT)
           { 
              left=true; 
           } 
           if(e.getKeyCode() == KeyEvent.VK_RIGHT)
           { 
              right=true; 
           } 
           if(e.getKeyCode() == KeyEvent.VK_SPACE)
           { 
                if (skudYStart1 <= 0)
                { 
                      skudXStart1=x+20; 
                      skudYStart1=y+30; 
                      skudXSlut1=x+20; 
                      skudYSlut1=450; 
                      skudXStart2=x+78; 
                      skudYStart2=y+30; 
                      skudXSlut2=x+78; 
                      skudYSlut2=450; 
              }
               
              space=true; 
 
         } 
     } 
     public void keyReleased(KeyEvent e)
     { 
        if(e.getKeyCode() == KeyEvent.VK_LEFT)
        { 
           left=false; 
        } 
        if(e.getKeyCode() == KeyEvent.VK_RIGHT)
        { 
           right=false; 
        } 
        if(e.getKeyCode() == KeyEvent.VK_SPACE)
        { 
        } 
     } 
     public void keyTyped(KeyEvent e){} 
 
     public static void main(String[] aslan)
     { 
          new Raptor().run(); 
     } 
} 


[quote]Question: is it possible to just get the Graphics2D via getGraphics of the bufferStrategy once and not need to dispose() every iteration (I thought that getting and destroying could lead to a lot of garbage) or does the buffer strategy basically require that every render frame you get graphics->draw->dispose?

-Chris
[/quote]
All the examples I have seen get the graphics object each time you want to draw. Maybe someone like Jeff could shed some light on the garbage collection impact of doing this.

[quote]Now I have this question…
I want a enemy spaceship to fly against the spaceship efter some delay, how do I do this? The way the code is now the enemy spaceship does this without any delay…
[/quote]
You could call System.currentTimeMillis() at the start of the game, then call it in the loop and launch the enemy after it has changed by an amount that you specify. However, remember that System.currentTimeMillis() has a limited resolution on Windows, so it may not be as accurate as you would like, but I think it would be good enough for a delay timer like this.

Rick