Computer Science Canada

Double buffer problems

Author:  freeridin101 [ Thu Mar 09, 2006 10:22 pm ]
Post subject:  Double buffer problems

im having problems with my double buffer. i have have read through many other posts and have come up with nothing. im getting pretty desprite so any pointer as to why this wont work or a more efficient way of doing this would be great.



code:
import java.applet.*;
import java.awt.event.*;
import java.awt.*;

public class DoubleBuffering extends Applet
{
    int y, score, direction;
    Graphics bufferGraphics;
    Image offscreen;
    Dimension dim;
    static void delay (int del)
    {
        try
        {
            Thread.sleep (del * 1000);
        }
        catch (InterruptedException e)
        {
        }
    }
    public static void delay (int del)
    {
        for (int d = 1 ; d < del ; d++)
        {
            for (int x = 1 ; x < 30000 ; x++)
            {
           }
        }
    }


    public void eraseship (int x, int y)
    {
        Graphics g = getGraphics ();
        g.setColor (Color.white);
        g.fillOval (x, y, 10, 20);
        g.fillOval (x - 10, y + 10, 30, 10);
        g.fillOval (x + 3, y + 4, 4, 4);
    }


    public void init ()
    {
        dim = getSize ();
        offscreen = createImage (dim.width, dim.height);
        direction = 1;
        y = 10;
        score = 0;

        resize (800, 600);
        while (score < 10)
        {
            y = y + direction;
            drawship (10, y);
            delay (2);
            eraseship (10, y);
            if (y > 590)
                direction = -1;
            if (y < 0)
                direction = 1;
        }
        bufferGraphics = offscreen.getGraphics ();
    }


    public void paint (Graphics g)
    {
        bufferGraphics.clearRect (0, 0, dim.width, dim.width);
        g.drawImage (offscreen, 0, 0, this);
    }


    public void update (Graphics g)
    {
        paint (g);
    }


    public void drawship (int x, int y)
    {
        Graphics g = getGraphics ();
        g.setColor (Color.green);
        g.fillOval (x, y, 10, 20);
        g.setColor (Color.red);
        g.fillOval (x - 10, y + 10, 30, 10);
        g.setColor (Color.black);
        g.fillOval (x + 3, y + 4, 4, 4);
    }
}

Author:  freeridin101 [ Thu Mar 09, 2006 10:40 pm ]
Post subject: 

sorry frogot to delete this part


public static void delay (int del)
{
for (int d = 1 ; d < del ; d++)
{
for (int x = 1 ; x < 30000 ; x++)
{
}
}
}

Author:  freeridin101 [ Fri Mar 10, 2006 8:58 am ]
Post subject: 

anyone abile tofigure this out. i need help please. just give me a point to start fixing at. it is most likly all wrong so anything at this point would be great

Author:  freeridin101 [ Fri Mar 10, 2006 6:10 pm ]
Post subject: 

Come on guys. i no someone on here knows how to do this.im still trying and its still not working. help me. post something. atleast tell me if its all wrong. so i can start again. tell me something

Author:  freeridin101 [ Fri Mar 10, 2006 7:22 pm ]
Post subject: 

Moderator help maybe

Author:  [Gandalf] [ Fri Mar 10, 2006 7:28 pm ]
Post subject: 

Please avoid quintuple-posting, or else you will not get a positive response from users here. The chances of you getting a helpful response will go below 0%.

Use the search button next time, this has been brought up multiple times.

Here you will find a useful example:
http://compsci.ca/v2/viewtopic.php?t=3740

Author:  freeridin101 [ Fri Mar 10, 2006 7:57 pm ]
Post subject: 

I have already ready through that post(4times)and cannot figure out how to apply that to my program which is why i then quintuple-posted trying to get help. if u can explain how to apply this to my program (not do it for me) that would be great.

Author:  McKenzie [ Sat Mar 11, 2006 12:27 pm ]
Post subject: 

So many errors. The two biggest ones; You are not using your double buffer correctly. You are trying to treat it like it's Turing and are trying to erase by drawing in white when in fact you should be repainting the entire scene on the offscreen buffer then copying onscreen. Second: Your main game loop does not work because the applet is not fully constructed and you are trying to draw on it. Take a look here:
http://javaboutique.internet.com/tutorials/Java_Game_Programming/
It's a great site for the basics. To find a great site for advanced stuff Google "Killer Game Java" and check the first hit.

Author:  freeridin101 [ Mon Mar 13, 2006 10:00 pm ]
Post subject: 

okay i think im getting closer but i now need help getting this to run

code:

import java.applet.*;
import java.awt.event.*;
import java.awt.*;
import java.lang.Object.*;
import java.awt.Image.*;


public class DoubleBuffering extends Applet
{
    int y, score, direction;
    Graphics bufferg;
    BufferedImage buffer;

    static void delay (int del)
    {
        try
        {
            Thread.sleep (del * 1000);
        }
        catch (InterruptedException e)
        {
        }
    }


    public void eraseship (int x, int y)
    {
        Graphics g = getGraphics ();
        g.setColor (Color.white);
        g.fillOval (x, y, 10, 20);
        g.fillOval (x - 10, y + 10, 30, 10);
        g.fillOval (x + 3, y + 4, 4, 4);
    }


    public void init ()
    {
        direction = 1;
        y = 10;
        score = 0;
        resize (800, 600);
        while (score < 10)
        {
            y = y + direction;
            drawship (10, y);
            delay (30);
            eraseship (10, y);
            if (y > 590)
                direction = -1;
            if (y < 0)
                direction = 1;
        }
        gameLoop ();
    }


    public void drawship (int x, int y)
    {
        bufferg.setColor (Color.green);
        bufferg.fillOval (x, y, 10, 20);
        bufferg.setColor (Color.red);
        bufferg.fillOval (x - 10, y + 10, 30, 10);
        bufferg.setColor (Color.black);
        bufferg.fillOval (x + 3, y + 4, 4, 4);
    }


    public void gameLoop ()
    {
       // drawship (1,y);
        drawBufferToScreen ();
    }


    public void drawBufferToScreen ()
    {
        Graphics g = getGraphics ();
        g.drawImage (buffer, 0, 0, null);
    }


    public void paint (Graphics g)
    {
    }
}

Author:  rizzix [ Mon Mar 13, 2006 10:43 pm ]
Post subject: 

here's a BIG hint: do NOT put your game-loop in the init method.

Author:  McKenzie [ Tue Mar 14, 2006 9:11 am ]
Post subject: 

Still has many errors. Lets look at the one that Rizzix is talking about. Your main game loop (the while you have in init, not the method you call gameLoop) can not be in init because the Applet is not fully constructed. Try
code:
System.out.println(this.getHeight());
anywhere you are thinking of drawing to your applet and if you get 0 you know it's not there yet.
It looks like you are trying to avoid using threads here because you don't understand them. It is wise to avoid using things you don't understand. You have two choices. Learn threads (well, enough to use them here) or have the user click some button or press a key to start the action.

Author:  freeridin101 [ Tue Mar 14, 2006 1:44 pm ]
Post subject: 

i must be getting closer here is another attempt at this after the help you guys have given me (thanks by the way):

code:

import java.applet.*;
import java.awt.*;

public class doublebufferball extends Applet implements Runnable
{
    int y, score, direction;
    private Image dbImage;
    private Graphics dbg;
    static Graphics g;
    static void delay (int del)
    {
        try
        {
            Thread.sleep (del * 10);
        }
        catch (InterruptedException e)
        {
        }
    }


    public void init ()
    {
        {
            direction = 1;
            y = 10;
            score = 0;
            resize (800, 600);
            while (score < 10)
            {
                y = y + direction;
                drawship (10, y);
                delay (1);
                eraseship (10, y);
                if (y > 590)
                    direction = -1;
                if (y < 0)
                    direction = 1;
            }

        }

    }


    public void start ()
    {

        Thread th = new Thread (this);

        th.start ();
    }


    public void stop ()
    {

    }


    public void destroy ()
    {

    }


    public void run ()
    {

        Thread.currentThread ().setPriority (Thread.MIN_PRIORITY);


        while (true)
        {
            repaint ();
            // try
            // {
            //     Thread.sleep (30);
            // }
            // catch (InterruptedException ex)
            // {
            //
            // }
            Thread.currentThread ().setPriority (Thread.MAX_PRIORITY);
        }
    }


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

        dbg.setColor (getBackground ());
        dbg.fillRect (0, 0, this.getSize ().width, this.getSize ().height);

        dbg.setColor (getForeground ());
        paint (dbg);

        g.drawImage (dbImage, 0, 0, this);
    }


    public void drawship (int x, int y)
    {
        g = getGraphics ();
        g.setColor (Color.green);
        g.fillOval (x, y, 10, 20);
        g.setColor (Color.red);
        g.fillOval (x - 10, y + 10, 30, 10);
        g.setColor (Color.black);
        g.fillOval (x + 3, y + 4, 4, 4);
    }


    public void eraseship (int x, int y)
    {
        Graphics g = getGraphics ();
        g.setColor (Color.white);
        g.fillOval (x, y, 10, 20);
        g.fillOval (x - 10, y + 10, 30, 10);
        g.fillOval (x + 3, y + 4, 4, 4);
    }


    public void paint (Graphics g)
    {

    }
}


That runs for me but there is still some flickering what part is wrong?

Author:  rizzix [ Tue Mar 14, 2006 2:29 pm ]
Post subject: 

i'm supprised it worked... you haven't changed what we asked you to change.. =/

move your game-loop aka the "big while loop" out of the init method into, well maybe the paint method.

Oh and please aviod threads, for now. (although this pertty much means you should not use any gui components in your game either. for now anyway)

Author:  freeridin101 [ Tue Mar 14, 2006 2:49 pm ]
Post subject: 

rizzix i tryed to move the main game loop into the paint method but when i do my program runs but freezes and goes crazy try it you'll see what i mean

i just learned threads because McKenzie said i had to learn them to do this. im so confused Confused

Author:  rizzix [ Tue Mar 14, 2006 2:53 pm ]
Post subject: 

McKenzie's intentions are honourable but I believe its too early Razz Threads slove a lot of annoying issues.. but they add a whole new level of complexity.

anyway let me try and fix your code my self.. =/

Author:  freeridin101 [ Tue Mar 14, 2006 2:58 pm ]
Post subject: 

oh well now i no the basics of them fro later

Author:  rizzix [ Tue Mar 14, 2006 6:23 pm ]
Post subject: 

Ah.. this is the first time I've actually attempted to try out this Applet thing. (had to do it sometime anyway).

Apparently, they don't work like normal swing applications. You are required to repaint the component your self. Hence threads are pretty much necessary.

anyway.. here's a fantastic tutorial: http://www.javaworld.com/javaworld/jw-03-1996/jw-03-animation.html


Or you can try out my very cool and simple TimedBufferedApplet:

Java:
import java.awt.*;

public class TestApplet extends TimedBufferedApplet {
   
    public void drawship(Graphics2D g, int x, int y) {
        g.setColor (Color.green);
        g.fillOval (x, y, 10, 20);
        g.setColor (Color.red);
        g.fillOval (x - 10, y + 10, 30, 10);
        g.setColor (Color.black);
        g.fillOval (x + 3, y + 4, 4, 4);
    }
   
    @Override public void offscreenPaint(Graphics2D g, int frame) {
        drawship(g, frame, 0);
    }
}


Attached is the TimedBufferedApplet. What is does is basically "tick" at regular intervals upon which it will repaint the screen. All you are required to do is Override the offscreenPaint method as above.. Smile

Now that method has an extra agrument called "frame" well that basically tells you which frame is being drawn out.

By default the tick_interval is i think 100msec. If you find this too slow or too fast, you can change it by calling setTickInterval(some_int); Oh and there's a very special way you need to set this up:

Java:
@Override public void init() {
    setTickInterval(some_int);
    setBackground(Color.black);
    super.init();
}


Never make it Zero! Not a good idea, we have to give the awt thread a chance to excute, or else you won't see anything on screen. Yes, the ticking occurs in a different thread (this is why I said threads are sort-of necessary). Also, since this version is not thread safe, dont even think of trying to change the tick interval outside the init method.

Author:  freeridin101 [ Tue Mar 14, 2006 9:27 pm ]
Post subject: 

i cant run it i get an error about the ""@Override"" part. It says:

Syntax: Unexpected input discarded

Author:  rizzix [ Tue Mar 14, 2006 9:28 pm ]
Post subject: 

you need java 1.5 ... or u can just take out the @Override part all together.

Author:  freeridin101 [ Tue Mar 14, 2006 9:31 pm ]
Post subject: 

upon futher inspection i am geting all sorts of errors right down to it cant find javax.swing. could this be because i am using ready to program?

Author:  rizzix [ Tue Mar 14, 2006 9:32 pm ]
Post subject: 

do u get these erros after u removed the @Override?

Author:  freeridin101 [ Tue Mar 14, 2006 9:40 pm ]
Post subject: 

then i get a hole bunch more

Author:  rizzix [ Tue Mar 14, 2006 9:42 pm ]
Post subject: 

do it from the command line... and tell me what errors you get.

CommandPrompt:
cd to\current\directory
\path\to\javac.exe -classpath . *.java > errors.txt

Author:  freeridin101 [ Tue Mar 14, 2006 9:45 pm ]
Post subject: 

you've lost me

Author:  rizzix [ Tue Mar 14, 2006 9:47 pm ]
Post subject: 

read the first post of: http://www.compsci.ca/v2/viewtopic.php?t=9576

Basically open ur Command Prompt.. and type the appropriate lines.. in the window.

Author:  rizzix [ Tue Mar 14, 2006 9:50 pm ]
Post subject: 

For example..

if my .java files were in C:\
and my javac was in \Progarm Files\Java\jdk1.5.0_06\bin\

the it would look like this:

CommandPrompt:
cd \
"\Progarm Files\Java\jdk1.5.0_06\bin\javac.exe" -classpath . *.java > errors.txt

Author:  McKenzie [ Tue Mar 14, 2006 11:20 pm ]
Post subject: 

Your code was not far off. Here it is with a bit of nip-and-tuck:
code:
import java.applet.*;
import java.awt.*;

public class doublebufferball extends Applet implements Runnable
{
    int y, score, direction;
    private Image dbImage;
    private Graphics dbg;
    static Graphics g;
    static void delay (int del)
    {
        try
        {
            Thread.sleep (del);
        }
        catch (InterruptedException e)
        {
        }
    }


    public void init ()
    {
            direction = 1;
            y = 10;
            score = 0;
            resize (800, 600);
    }


    public void start ()
    {
        Thread th = new Thread (this);
        th.start ();
    }

    public void run ()
    {
        while (score < 10)
        {
            y = y + direction;
            if (y > 590)
                direction = -1;
            if (y < 0)
                direction = 1;
            repaint ();
            delay(30);
        }
    }


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

        dbg.setColor (getBackground ());
        dbg.fillRect (0, 0, this.getSize ().width, this.getSize ().height);
       
        dbg.setColor (getForeground ());
        drawship(10,y);
        g.drawImage (dbImage, 0, 0, this);

    }


    public void drawship (int x, int y)
    {
        dbg.setColor (Color.green);
        dbg.fillOval (x, y, 10, 20);
        dbg.setColor (Color.red);
        dbg.fillOval (x - 10, y + 10, 30, 10);
        dbg.setColor (Color.black);
        dbg.fillOval (x + 3, y + 4, 4, 4);
    }

    public void paint (Graphics g)
    {
    }
}

Author:  freeridin101 [ Fri Mar 17, 2006 3:37 pm ]
Post subject: 

am i not putting things in the write spot or is this doulbe buffer not working.i tworks for the computer controlled ship but if you move the mouse up and down fast you see doubles any thoughts??
code:


import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class doublebufferworks extends Applet implements Runnable
{
    int y = 0, y2 = 295, x3 = 0, y3 = 0, score = 0, direction = 0;
    private Image dbImage;
    private Graphics dbg;
    static Graphics g;

    static void delay (int del)
    {
        try
        {
            Thread.sleep (del);
        }
        catch (InterruptedException e)
        {
        }
    }


    public void init ()
    {
        direction = 1;
        y = 10;
        score = 0;
        resize (800, 600);
    }


    public void start ()
    {
        Thread th = new Thread (this);
        th.start ();
    }


    public void MoveEnemyShip ()
    {
        while (score < 10)
        {
            y = y + direction;
            if (y > 590)
                direction = -1;
            if (y < 0)
                direction = 1;
            repaint ();
            delay (15);
        }
    }


    // public boolean keyDown (Event e, int key)
    // {
    //     if (key == 1004)
    //     {
    //         y2 = y2 - 2;
    //     }
    //
    //     //System.out.println ("Charakter: " + (char)key + " Integer Value: " + key);
    //     if (key == 1005)
    //     {
    //         y2 = y2 + 2;
    //     }
    //     return true;
    // }

    public boolean mouseMove (Event evt, int x3, int y3)
    {
        this.y2 = y3;
        return true;
    }


    public void run ()
    {
        MoveEnemyShip ();
    }


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

        dbg.setColor (getBackground ());
        dbg.fillRect (0, 0, this.getSize ().width, this.getSize ().height);
        dbg.setColor (getForeground ());
        drawship (10, y);
        drawship (770, y2);
        g.drawImage (dbImage, 0, 0, this);

    }


    public void drawship (int x, int y)
    {
        dbg.setColor (Color.green);
        dbg.fillOval (x, y, 10, 20);
        dbg.setColor (Color.red);
        dbg.fillOval (x - 10, y + 10, 30, 10);
        dbg.setColor (Color.black);
        dbg.fillOval (x + 3, y + 4, 4, 4);
    }


    public void paint (Graphics g)
    {

    }
}

Author:  McKenzie [ Fri Mar 17, 2006 11:25 pm ]
Post subject: 

If I'm not mistaken your code is fine. Looks like an optical illusion. Move your mouse across the screen quickly and you will get the same effect.


: