1 2 Previous Next 19 Replies Latest reply: Mar 11, 2010 7:55 AM by 843853 RSS

    Flickering only in the beginning

    843853
      Hi

      Firstly, sorry if my English isn't very well. Perhaps my problem it's of a newbie, but it's causing me trouble. I'm finishing a desktop game in java (not an applet, but a normal window). The dynamics of the game is as follows: first of all, the game shows a presentation screen a few seconds. After doing that, the game shows the menu buttons (start, options, exit).

      The question is that I'm not able to remove flickering in the presentation screen, before the options. Furthermore, the bug isn't reproducible: sometimes it doesn't flicker, sometimes it flickers once, and sometimes it's flickering during all the presentation (4 or 5 seconds). Once the buttons are shown the it never flickers, and I suspect that it's due a problem when I fill the buffer, but really I don't know. If you could help me, I'd very thankful. Regards:

      Alejandro
        • 1. Re: Flickering only in the beginning
          843853
          Alessandro,

          I don't know how anyone could help you either, you've not shown us anything, nor have you told us anything specific that may lead us to formulating a theory on what is happening.

          Having said that--here are things I check when I'm having flicker problems:

          1 - how is my rendering happening?
          - is double buffering used? (SWING double buffers now by defualt)
          2 - is my animation loop implemented properly (SWING use javax.swing.Timer)
          3 - is my animation delay appropriate to eliminate flicker.
          4 - do I have tight paint/paintComponent logic?
          5 - is my graphics driver installed properly for my graphics card on my computer?
          6 - how long has it been since I rebooted?
          7 - is Windows in a invalid state while I try my app?
          • 2. Re: Flickering only in the beginning
            843853
            Hello morgalr. Sorry, you're right, I haven't post much information. I haven't enough time now, but I hope that tomorrow morning I'll have time for a detailed explanation. I post here the constructor of my class Ventana (Ventana = Window in spanish). Thank you in any case! I'll post again tomorrow.

            public Ventana() {
            panel = new JPanel();
            panel.setIgnoreRepaint(true);
            panel.setDoubleBuffered(true);

            this.cargaGraficos();
            this.setIgnoreRepaint(true);
            this.setSize(ANCHO+8,ALTO+27);
            this.setResizable(false);

            this.setTitle("TROPLAY - El juego de la tenia");
            try {
            icono = getToolkit().getImage(directorio + "icono.png");
            } catch (Exception e) {
            System.err.println("Error en la carga de imágenes" + e.toString());
            }

            this.setIconImage(icono);

            this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {System.exit(0);}
            });

            container = this.getContentPane();
            container.add(panel);
            //Toolkit.getDefaultToolkit().sync();

            container.setFocusable(true);
            container.requestFocus();
            //Toolkit.getDefaultToolkit().sync();

            this.setVisible(true);
            this.createBufferStrategy(2);

            bf = getBufferStrategy();

            [more stuff...]
            }
            • 3. Re: Flickering only in the beginning
              843853
              Alessandro,

              That code has nothing to do with your flicker. Also please post using code tags. You need to uses code tags to have properly formatted code and to keep your post from being corrupted by the forum software interpreting character combinations as screen formatting.
              • 4. Re: Flickering only in the beginning
                843853
                Hello morgalr. As I said yesterday, I'm back here... I'll response you in the same order:

                1) The rendering of the image is controlled by a class Presentation before the buttons appear, and after that is controlled by a class Menu. Definitely, in each moment of the game there is a diferent class controlling the rendering of the window (calling the draw method of the window). These classes are: PresentationControl, Menu, and Game. I post the code of the Presentation class:
                class PresentationControl extends ControllerClass {
                    private Window wind = null;
                    private FlowController controller = null;
                    private boolean haveEnd = false;
                    private int counter = 0;
                    
                    public PresentationControl (Window wind, FlowController control) {
                        this.window = wind;
                        this.controller = control;
                        this.gameLoop();
                    }
                    
                    /**
                     * The loop of the Presentation class
                     */
                    public void gameLoop() {
                        while (!acabar) {
                            window.draw(null, null, 3); //Render call
                            
                           //Sleep
                            try {
                                Thread.sleep(70);
                            } catch (InterruptedException ex) {
                                Logger.getLogger(Menu.class.getName()).log(Level.SEVERE, null, ex);
                            }
                            
                            haveEnd = endLoop(); //End condition
                        }
                    }
                    
                    /**
                     * Used for waiting a short time before the buttons appear. Returns if we have to end the presentation
                     */
                    public boolean endLoop() {
                        counter++;
                        return (counter == 60);
                    }
                
                    public void InputControl() {}
                }
                And here is part of the Window.draw code:
                      public void draw(boolean[] show, int[] graphics, int drawType) {
                          g = bf.getDrawGraphics();
                          
                          try {
                              g.drawImage(graphicsArray[background][0], 4, 24, this); //The Image of the presentation (background is
                                                                                                            adjusted dinamically, in this case is the initial screen)
                              
                              //Diferent renderings depending on the moment
                              switch(drawType) {
                
                                  [The stuff here is for other cases, not presentation, I have cut it...]
                
                                  case 3: //There is nothing to do because we have drawn the screen yet
                                      break;
                              }
                              
                              [Other stuff irrelevant]
                          }
                          finally {
                              g.dispose();
                          }
                
                          bf.show();
                          Toolkit.getDefaultToolkit().sync();
                      }
                2) and 3) are responsed in 1), I think

                4) Sorry, I don't understand the 4 point. But I'm not using such methods
                5) I think so, because I have tested the program in three different computers anf the problem is the same
                6) I'm spending many hours in the computer, there are moments that I have just started the computer, and others that it's turned on since many hours ago
                7) I think this question is responsed in 5), and I have tested the program beneath linux and windows (I am programming in linux)
                • 5. Re: Flickering only in the beginning
                  843853
                  You're using AWT, right?

                  At the beginning of your application when it flickers, I believe you are suffering from a loading problem. Your system is just settling in.

                  -look at your drive I/O during this time and CPU usage, you should see that you have excessive drive I/O or your CPU is maxing out trying to process what has just been loaded.

                  At any other time--like after a long time of being on: your getting hit by the garbage collector and at other times where there is inactivity for a long time and you come back, then you are getting hit by paging delays or other system resources being awakened.

                  In your gameloop, I've never been a big fan of using sleep for animation timing. If you have high cpu or other load conditions, that sleep is still going to sleep for 70 ms and your endloop is till going to add it's delay, so your frame rates drop. If you use a timer and think of your game as nothing more than an animation in which you interactively add and control objects, then you will have a much better outlook on the problem. You need a constant frame rate, you cannot get that with what you have. You need to set up an animation loop--a timer with a listener setting the frame rate. Once you have that, then you need to make changes to your graphics as controlled by your characters and the normal game flow.

                  I like to render to a BufferedImage and use that to paint the screen. This will result in a very tight graphics update routine that is called at a constant frame rate. The trick then is to use non-screen painting cpu cycles between the timer events to update the game state--show movement and other activities. There are several tutorials out there that will show this method, and I believe it is what is shown in the Java Tutorials for basic animation and gaming.
                  • 6. Re: Flickering only in the beginning
                    843853
                    Thaks a lot morgalr. Your post seems to be useful. I'll try to change these things and I tell you if it works
                    • 7. Re: Flickering only in the beginning
                      843853
                      As first step, I have implemented a frame rate display. The fps starts unstable (19, 15, 14, 13 fps) and it stabilizes after 8 or 9 frames, around 12.6 fps. With a timer, The fps value would become constant since the first frame?
                      • 8. Re: Flickering only in the beginning
                        843853
                        I generally run 50+ frames per second, 20 millisecond timing or less. Be sure you're using the javax.swing.Timer:
                        Timer t = new Timer(20, this);
                        t.start();
                        You also may want to implement a splash screen or some type of visual static display while loading at the start.
                        • 9. Re: Flickering only in the beginning
                          843853
                          The splash screen while loading graphics isn't necessary, because I am loading the images before the window is shown. I have implemented a simple loop with a timer (a very simple test), with the following code:
                          public class Pepin extends JFrame implements ActionListener{
                              private Timer timer = null;
                              private int delay = 70;
                              private int contador = 0;
                              
                              public Pepin() {
                                  timer = new Timer(delay, this);
                                  timer.setInitialDelay(0);
                                  timer.setCoalesce(false);
                                  timer.addActionListener(this);
                                  timer.start();
                              }
                              
                              public void actionPerformed(ActionEvent e) {
                                  System.out.println("Step " + counter + " " + (System.currentTimeMillis() % 1000));
                                  counter++;
                              }
                          I have done it with the aim of viewing the constant pace of the timer. Generally it works, but there are many repetitions that supposedly shouldn't occur. Do you know why?

                          Here is a part of the output:

                          [...]
                          Step 114 535
                          Step 115 535 -> Repetition
                          Step 116 605
                          Step 117 606 -> Almost repetition
                          Step 118 675
                          Step 119 676 -> Almost repetition
                          Step 120 745
                          Step 121 745 -> Repetition
                          Step 122 815
                          Step 123 816 -> Almost repetition
                          Step 124 886
                          Step 125 886 -> Repetition
                          [...]

                          Thank you, I think it's almost done!
                          • 10. Re: Flickering only in the beginning
                            843853
                            Remove the following line of code:
                            timer.addActionListener(this);
                            When you do
                            timer = new Timer(delay, this);
                            You have already set the ActionListener for the Timer to "this"--your Pepin JFrame, you need not add it again.
                            • 11. Re: Flickering only in the beginning
                              843853
                              Hello again. I have removed the use of sleep an replaced it with the use of timer. Yesterday I spent the time correcting the bugs that the new approach originated in the old code. Now, with the bug fixed, the flickering still occurs! It is a very subtle problem, I think. Any idea? Nevertheless now I understand the difference between the use of a timer (and its advantage) and the non-use :D
                              • 12. Re: Flickering only in the beginning
                                843853
                                Are you using SWING? If you are still having clicker problems, then post your paintComponent code and execution path, something is probably very wrong there.
                                • 13. Re: Flickering only in the beginning
                                  843853
                                  Yes, I'm using the swing timer, not the standard one. But I haven't any method called paintComponent. I'm using the code posted a few days ago, like this:
                                        public void draw(boolean[] show, int[] graphics, int drawType) {
                                            g = bf.getDrawGraphics();
                                            
                                            try {
                                                [Draw stuff...]
                                            }
                                            finally {
                                                g.dispose();
                                            }
                                  
                                            bf.show();
                                  }
                                  And the following is for getting the BufferStrategy, within the Window class constructor:
                                  [...]
                                  this.createBufferStrategy(2);
                                           
                                  bf = getBufferStrategy();
                                  [...]
                                  I don't know if I'm answering you
                                  • 14. Re: Flickering only in the beginning
                                    843853
                                    alessandro_ wrote:
                                    [...]
                                    this.createBufferStrategy(2);
                                    
                                    bf = getBufferStrategy();
                                    This part is redundant, since SWING default is double buffered.

                                    Edited by: morgalr on Mar 9, 2010 6:03 PM -- the following added

                                    Any code in your draw that does not have to do with actually displaying the image on the screen needs to be removed and your new algorithm sould look like this:

                                    your Timer event happens
                                    render all graphics to a BufferedImage
                                    draw to screen (call your streamlined draw method)
                                    1 2 Previous Next