A damn good performance improvement

66fps - 88fps.

Trick?

When you set up a Window ALWAYS use:

SwingUtilities.invokeLater
(
new Runnable()
{
public void run()
{
doWindowSwingInit();
}
}
);

I was using J2D.

Code:


private static Main instance;
    private BufferStrategy bs;
    private Graphics2D g;
    
    //game
    private GameStart game;
    
    private int fps;
    
    
    private void loop()
    {
      g = (Graphics2D)bs.getDrawGraphics();
      g.clearRect(0, 0, getWidth(), getHeight());
      
      //logic
      game.logic();
      
      //rendering
      game.render(g);      
      
      //print fps in bottom corner
      g.setColor(Color.BLACK);
      g.drawString("FPS:" + fps, 15, getHeight() - 15);
      
      bs.show();
      g.dispose();
    }
    
    
    /** Creates a new instance of Main */
    public Main()
    {
      this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      this.setSize(640, 480);
      this.setLocationRelativeTo(null);
      this.setLocation(getX() - 100, getY() - 100);
      this.setIgnoreRepaint(true);
      this.setResizable(false);
      
      this.addKeyListener(new Input());
      
      this.setVisible(true);
      
      this.createBufferStrategy(3);
      bs = this.getBufferStrategy();
      g = (Graphics2D)bs.getDrawGraphics();
    }
    
    private void initGame()
    {
      game = new GameStart();
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)
    {
      SwingUtilities.invokeLater
      (
          new Runnable()
          {
            public void run()
            {
                instance = new Main();
            }
          }
      );
      
      instance.initGame();
      
      long cTime, eTime;

      while(true)
      {
          if( instance.isFocusOwner() )
          {
            cTime = System.nanoTime();
            //added to limit framerate
            instance.pause();
            //limiter

            instance.loop();

            eTime = System.nanoTime() - cTime;
            instance.fps = (int)(1000000000/eTime);
          }

          instance.pause();
      }
    }
    
    private void pause()
    {
      try
      {
          Thread.sleep(10);
      }catch(InterruptedException e)
      {
          e.printStackTrace();
      }
    }
    
    
    private class Input implements KeyListener
    {
      public void keyPressed(KeyEvent e)
      {
          switch( e.getKeyCode() )
          {
            case KeyEvent.VK_ESCAPE:
                System.exit(0);
                break;
          }
      }
      
      public void keyTyped(KeyEvent ee)
      {
      }
      
      public void keyReleased(KeyEvent eeee)
      {
      }
    }
    
    public static int getResWidth()
    {
      if( instance == null )
          return 0;
      return instance.getWidth();
    }
    
    public static int getResHeight()
    {
      if( instance == null )
          return 0;
      return instance.getHeight();
    }

Hm, doesn’t that block the swing-thread and force it into a loop?

I wouldn’t have a clue.

I can barely find any information about that method.
All I know is that I have a framerate jump by doing it this way.

Basically I’d feel that blocking the swing thread is not a particularly good idea.

Isn’t is possible that you did something before that brought you in concflict with the swing thread (e.g. you painting AND swing painting) that is now is longer possible because you KILLED the enemy instead of making peace?

SwingUtilities.invokeLater() posts an event on the AWT event queue and returns immediately. Shouldn’t affect your FPS in any way. Your code looks really dangerous since you set Main.instance inside the event and use it without checking that it has been created.

You also draw graphics outside of the AWT event thread which looks dangerous. I would advise you to post events to the AWT event thread instead of looping in the main thread. Look at javax.swing.Timer for example.

[quote]SwingUtilities.invokeLater() posts an event on the AWT event queue and returns immediately.
[/quote]
Thats not the point. The problem is that run() will be performed in the Swing thread but never ends! Means the event pump will actually stop!

Normally that mechanism is used to perform short actions in the Swing-Thread (set a new model, extend a list, …).

ASFAICS he’s not blocking the AWT event thread. The loop is outside of the invokeLater().

oh yes, I’m sorry!!!

Missed one closing curley :slight_smile:

So everything I said is pointless.

this.setIgnoreRepaint(true) … does that make a difference?

What about these multithreading things with threads owning monitors to objects created … does wait()/notify() come into play somewhere?