Results 1 to 8 of 8
  1. #1
    hunterbdb is offline Member
    Join Date
    Oct 2008
    Posts
    48
    Rep Power
    0

    Default Can't DOUBLE BUFFER images

    hi, i'm following a book called "killer game programming in java" by O'REilly and writing a game on my own as I go along with it.

    I'm a noob to game programming but i'm enrolled in a java programming class that doesn't cover game programming so i'm trying to learn and write a fun little game.


    I'm having trouble double buffering.

    I have 2 classes:

    1. A class called "Main" which extends JApplet.
    --------------------------------------------------------------------------
    Below a link to my very very basic gui. The white space is my jpanel that is from the class "gamPanel".

    here's the link:http:/
    i207.photobucket.com/albums/bb274/hunterbdb/gui.gif

    Below is the code I used to set up my applet.

    public void init()
    {
    //make components.
    gamePanel panel= new gamePanel();
    panel.create();


    //Set Applet and properties.
    this.setSize(600,450);
    this.setLayout(new BorderLayout());

    //Add Components and panels to applet.
    Container c=this.getContentPane();
    c.add(panel,BorderLayout.WEST);//adds the game's panel to the applet's content pane.

    }//end init().


    --------------------------------------------------------------------------

    2. A class called "gamePanel" which extends JPanel and implements runnable.

    --------------------------------------------------------------------------
    here is gamePanel's run method.

    Thread runner;
    public void run()
    {
    while(running)
    {
    gameUpdate();//this just updates whether the game is running or not.
    gameRender();
    paintScreen();
    try
    {
    Thread.sleep(20);
    }
    catch(InterruptedException ex)
    {
    System.out.println("interrupted sleep");
    }


    }

    }//end thread runner.



    Below is gamePanel's method

    private void gameRender()
    {
    if(canvas==null)
    {
    canvas = createImage(400,400);

    if(canvas==null)
    {
    System.out.print("Image canvas is null");
    }
    else

    pencil = canvas.getGraphics();
    }

    pencil.setColor(Color.black);
    pencil.fillRect(0,0,400,400);

    }

    Below is my paintScreen method that is supposed to draw the image.

    private void paintScreen()
    {
    Graphics g;
    try
    {
    g = this.getGraphics();//get the panel's graphic context.

    if((g!=null) &&(canvas!=null))
    {
    g.drawImage(canvas, 0,0,null);
    //sync the display--this is something only for linux systems.
    Toolkit.getDefaultToolkit().sync();
    g.dispose();
    }
    }
    catch(Exception e)
    {
    System.out.println("Graphics context error: " + e);
    }
    }

    To start the thread of gamePanel, it overrides the addNotify method, and starts the thread when the jpanel is added to the applet.

    public void addNotify()
    {
    super.addNotify();
    runner.start();

    }
    --------------------------------------------------------------------------




    So, here is my problem: when I run Main's init() method, it's supposed to start the thread instantly when the JPanel is added to the applet.

    well, all I see is the white background of the JPanel.

    so, I assume that either the thread isn't running or i'm not double buffering the image correctly, and I don't know why.

    my main question would be: how do I double buffer?

  2. #2
    Norm's Avatar
    Norm is online now Moderator
    Join Date
    Jun 2008
    Location
    SW Missouri
    Posts
    17,401
    Rep Power
    25

    Default

    To double buffer:
    Create an image, draw on that image, then g.drawImage(theImage) in the paint or paintComponent method.

    Double buffering has nothing to do with gaming. Its a technique used to keep your drawn images from flashing.

    Have you tried searching for code samples. Try searching for BufferedImage.

  3. #3
    hunterbdb is offline Member
    Join Date
    Oct 2008
    Posts
    48
    Rep Power
    0

    Default i did

    well, i did look for stuff.


    I found lots of stuff but i dont understand any of it.



    public void update (Graphics g)
    {
    // initialize buffer
    if (dbImage == null)
    {
    dbImage = createImage (this.getSize().width, this.getSize().height);
    dbg = dbImage.getGraphics ();

    }

    // clear screen in background
    dbg.setColor (getBackground ());
    dbg.fillRect (0, 0, this.getSize().width, this.getSize().height);

    // draw elements in background
    dbg.setColor (getForeground());
    paint (dbg);

    // draw image on the screen
    g.drawImage (dbImage, 0, 0, this);

    }

    I dont understand: what's the point of putting setColor(getBackgroun())? what does this do?

    oh, sure, it gets the background color of the image, but what is a background color and what's it's point of existence? same for the forground.
    what does paint(dbg) do?

    maybe these are better questions.

  4. #4
    hardwired's Avatar
    hardwired is offline Senior Member
    Join Date
    Jul 2007
    Posts
    1,576
    Rep Power
    9

    Default

    If you are drawing in Swing (with light-weight components) you may not need to draw on an offscreen buffer. There are times when this is a good technique in Swing. Swing is double–buffered so you get about the same quality and smoothness as you would with an offscreen buffer.
    Offscreen buffering was especially useful in AWT (heavy-weight components) drawing which is more complex than Swing drawing.

    what's the point of putting setColor(getBackgroun())? what does this do?
    You are setting the background color for the image (using the background color of your component) and filling the image with the color; this effectively erases the image.

    but what is a background color and what's it's point of existence?
    updating the image for the next time it is drawn in the paintComponent method.

    same for the forground.
    Can be the same. Older AWT code often stores a drawing color in the "foreground" property of the parent component (a trick).

    what does paint(dbg) do?
    You hand the graphics context (dbg) to the component and ask it to draw itself into the image.
    Last edited by hardwired; 10-27-2008 at 05:50 AM. Reason: left out some of my reply

  5. #5
    Norm's Avatar
    Norm is online now Moderator
    Join Date
    Jun 2008
    Location
    SW Missouri
    Posts
    17,401
    Rep Power
    25

    Default

    The paint and update methods are for the older AWT components. The AWT engine called update() to clear the component's image and the the update method calls paint() to paint the component.
    By calling paint() with the Graphics object you've created, the paint method will draw on your graphics vs the grapics context passed to the update method(which is the one that will be seen). After paint() has drawn its component's image on your graphics, then you use the graphics (g) passed to update() to draw the whole image with g.drawImage().

  6. #6
    hunterbdb is offline Member
    Join Date
    Oct 2008
    Posts
    48
    Rep Power
    0

    Default

    ah i c. thanks for taking the time out of your day to explain this to me.

    much appreciated

  7. #7
    hardwired's Avatar
    hardwired is offline Senior Member
    Join Date
    Jul 2007
    Posts
    1,576
    Rep Power
    9

    Default

    Java Code:
    // <applet code="AppletRx" width="600" height="450"></applet>
    import java.awt.*;
    import javax.swing.*;
    
    public class AppletRx extends JApplet
    {
        public void init()
        {
            //make components.
            GamePanel panel= new GamePanel();
            panel.create();
    
            //Set Applet and properties.
            this.setSize(600,450);
            this.setLayout(new BorderLayout());
    
            //Add Components and panels to applet.
            Container c=this.getContentPane();
            //adds the game's panel to the applet's content pane.
            // If you're going to add the graphic component here
            // you'll need to provide a size hint so the layout
            // manager will know how much display space it needs.
            // Otherwise, its default size 10,10 will be used and
            // the height will be stretched to fill the height of
            // the contentPane - see BorderLayout comments section.
            c.add(panel,BorderLayout.WEST);
    
        }//end init().
    }
    
    class GamePanel extends JPanel implements Runnable
    {
        Image canvas;
        Graphics pencil;
        int imgWidth = 400;
        int imgHeight = 400;
        int diam = 30;
        int x;
        int y;
        Thread runner;
        boolean running = false;
    
        public void run()
        {
            while(running)
            {
                gameUpdate();
                gameRender();
                repaint();
                try
                {
                    Thread.sleep(120);
                }
                catch(InterruptedException ex)
                {
                    System.out.println("interrupted sleep");
                    running = false;
                }
            }
        }//end thread runner.
    
        private void gameUpdate()
        {
            x += 3;
            y += 2;
            //System.out.printf("x = %d  y = %d%n", x, y);
        }
    
        private void gameRender()
        {
            if(canvas==null)
            {
                canvas = createImage(imgWidth, imgHeight);
    
                if(canvas==null)
                {
                    System.out.print("Image canvas is null");
                }
                else
                {
                    pencil = canvas.getGraphics();
                }
            }
    
            pencil.setColor(Color.black);
            pencil.fillRect(0, 0, imgWidth, imgHeight);
            pencil.setColor(Color.red);
            pencil.fillOval(x-diam/2, y-diam/2, diam, diam);
        }
    
        protected void paintComponent(Graphics g)
        {
            g.drawImage(canvas,0,0,null);
        }
    
        public void addNotify()
        {
            super.addNotify();
            runner.start();
        }
    
        public void create()
        {
            // Initialize animation variables.
            x = 100;
            y = 100;
            // Prepare animation to start.
            running = true;
            runner = new Thread(this);
            // Keep gui responsive to user-input.
            runner.setPriority(Thread.NORM_PRIORITY);
        }
    
        /** Provide size hint for parent container. */
        public Dimension getPreferredSize()
        {
            return new Dimension(imgWidth, imgHeight);
        }
    }

  8. #8
    MrFreeweed is offline Member
    Join Date
    Nov 2008
    Posts
    5
    Rep Power
    0

    Default

    Thanks hardwired for your explanation. It was a lot of help for me switching from canvas to jpanel.

    One question for anyone who knows how does the jpanel know to double buffer without telling it?

Similar Threads

  1. Non Allocating String Buffer
    By chrisdb89 in forum New To Java
    Replies: 5
    Last Post: 10-25-2008, 06:57 AM
  2. Replies: 0
    Last Post: 03-11-2008, 12:25 PM
  3. Trouble with Buffer Sizing
    By Jeff in forum New To Java
    Replies: 3
    Last Post: 02-07-2008, 01:43 PM
  4. Help with String Buffer
    By mathias in forum AWT / Swing
    Replies: 1
    Last Post: 08-07-2007, 06:52 AM
  5. how to set the value of BUFFER SIZE
    By oregon in forum Advanced Java
    Replies: 1
    Last Post: 08-06-2007, 03:16 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •