Understand BufferStrategy
Asked Answered
L

1

14

I'm kind of new to java. I want to make a game. After a lot of research, I can't understand how bufferstrategy works.. I know the basics.. it creates an off-screen image that you can later put into your windows object.. I got this

public class Marco extends JFrame {
    private static final long serialVersionUID = 1L;
    BufferStrategy bs; //create an strategy for multi-buffering.

    public Marco() {
       basicFunctions(); //just the clasics setSize,setVisible,etc
       createBufferStrategy(2);//jframe extends windows so i can call this method 
       bs = this.getBufferStrategy();//returns the buffer strategy used by this component
    }

   @Override
   public void paint(Graphics g){
      g.drawString("My game",20,40);//some string that I don't know why it does not show
      //guess is 'couse g2 overwrittes all the frame..
      Graphics2D g2=null;//create a child object of Graphics
      try{
         g2 = (Graphics2D) bs.getDrawGraphics();//this new object g2,will get the
         //buffer of this jframe?
         drawWhatEver(g2);//whatever I draw in this method will show in jframe,
         //but why??
      }finally{
         g2.dispose();//clean memory,but how? it cleans the buffer after
         //being copied to the jframe?? when did I copy to the jframe??
      }
      bs.show();//I never put anything on bs, so, why do I need to show its content??
      //I think it's a reference to g2, but when did I do this reference??
   }

   private void drawWhatEver(Graphics2D g2){
       g2.fillRect(20, 50, 20, 20);//now.. this I can show..
   }
  }

I don't know.. I've been studying this for a long time now.. and with no luck at all.. I don't know.. maybe it's all there, and it's really clear and simple, and I'm just too stupid to see it..

Thanks for all the help.. :)

Lustre answered 27/11, 2012 at 17:43 Comment(0)
B
29

Here's how it works:

  1. The JFrame constructs a BufferStrategy when you call createBufferStrategy(2);. The BufferStrategy knows that it belongs to that specific instance of JFrame. You are retrieving it and storing it in the bs field.
  2. When it comes time to draw your stuff, you are retrieving a Graphics2D from bs. This Graphics2D object is tied to one of the internal buffers owned by bs. As you draw, everything goes into that buffer.
  3. When you finally call bs.show(), bs will cause the buffer that you just drew to become the current buffer for the JFrame. It knows how to do this because (see point 1) it knows what JFrame it is in service to.

That's all that's going on.

By way of comment to your code...you should change your drawing routine a bit. Instead of this:

try{
    g2 = (Graphics2D) bs.getDrawGraphics();
    drawWhatEver(g2);
} finally {
       g2.dispose();
}
bs.show();

you should have a loop like this:

do {
    try{
        g2 = (Graphics2D) bs.getDrawGraphics();
        drawWhatEver(g2);
    } finally {
           g2.dispose();
    }
    bs.show();
} while (bs.contentsLost());

That will safeguard against lost buffer frames, which, according to the docs, can happen occasionally.

Boydboyden answered 27/11, 2012 at 17:56 Comment(2)
Why do we need to dispose() before we have show() the buffer? I assume the graphic object is there only to have graphics functionality, but when it's not needed we "release it's tools and resources" and than show our buffered image?Durr
@someFolk - It doesn't have to be done in that order; the call to bs.show() could be moved inside the try block. But there's no particular reason to do so and it's good practice to release system resources as soon as they are not needed.Boydboyden

© 2022 - 2024 — McMap. All rights reserved.