简体   繁体   中英

[Java]Double buffering failing to double buffer

Well, as the title says, I am having trouble with double buffering. I read this Java Ebook and it doesn't give you code for what they are teaching you - at least not completely. So I have to do a lot of guess work.

Objective : Bouncing ball in an applet.

It's not working in the way that the ball is still flashing. Aka double buffering is failing to work.

I use three classes, ball class, double buffering class, and MainApplet class. MainApplet extends double buffering, and ball class extends MainApplet

import java.applet.Applet;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;

@SuppressWarnings("serial")

public class MainApplet extends DoubleBuffering implements Runnable {

    public Ball ball;
    public Graphics g;

    private Thread ticker;
    public boolean running = false;

    public void init() {

        setSize(100,100);
        ball = new Ball(getWidth() / 5f, getHeight() / 4f, 1.5f,
                2.3f, 12, Color.red);
        moveBall();
    }

    public void run() {
        while(running) {
            try {
                Rectangle bou = new Rectangle(getWidth(), getHeight());
                ball.move(bou);
                ball.update(getGraphics());
                Thread.sleep(1000 / 15);
            } catch (InterruptedException e) {
                System.out.println(e.getMessage());
            }
            repaint();
        }
    }

    public void moveBall() {
        start();
    }

    public synchronized void start() {
        running = true;
        ticker = new Thread(this);
        ticker.setPriority(Thread.MIN_PRIORITY + 1);
        ticker.start();
    }


    public synchronized void stop() {
        running = false;
        ticker.stop();
    }
}


import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Image;

public class DoubleBuffering extends Applet
{
    Image offScreenBuffer;

    @SuppressWarnings("deprecation")
    public void update(Graphics g)
    {
        System.out.println("We are buffing");
        Graphics gr; 
        if (offScreenBuffer==null ||
                (! (offScreenBuffer.getWidth(this) == this.size().width
                        && offScreenBuffer.getHeight(this) == this.size().height)))
        {
            offScreenBuffer = this.createImage(size().width, size().height);
        }
        gr = offScreenBuffer.getGraphics();
        System.out.println("Something else");
        paint(gr); 
        g.drawImage(offScreenBuffer, 0, 0, this);     
    }
}


import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;


public class Ball extends MainApplet{

    int size;
    private Color color;
    public float x, y, dx, dy;

    public Ball ball;
    public int width, height;
    public Image offscreenImage;
    public Graphics offscr;
    private MainApplet ma;


    Ball (float x, float y, float dx, float dy, int size,
            Color color) {
        this.x = x;
        this.y = y;
        this.dy = dx;
        this.dy = dy;
        this.color = color;
        this.size = size;

    }

    public void draw (Graphics g) {
        g.setColor(this.color);
        g.fillOval((int) x, (int) y, size, size);
    }

    public void update(Graphics g)  {

        g.clearRect(0, 0, getWidth(), getHeight());
        draw(g);

    }

    public void move(Rectangle bounds) {
        // Add velocity values dx/dy to position to
        // ball s new position
        x += dx;
        y += dy;

        // Check for collision with left edge
        if (x < bounds.x && dx < 0) {
            dx = -dx;
            x -= 2 * (x - bounds.x);
        } 
        // Check for collision with right edge
        else if (x + size >  bounds.x + bounds.width &&
                dx > 0) {
            dx = -dx;
            x -= 2 * ((x + size) - (bounds.x + bounds.width));
        }
        // Checks for collision with top edge
        else if (y < bounds.y && dy < 0) {
            dy = -dy;
            y -= 2 * (y - bounds.y);
        }
        // Checks for collision with bottom edge
        else if (y + size > bounds.y + bounds.height && dy >0) {
            dy = -dy;
            y -= 2 * ((y + size) - (bounds.y + bounds.width));
        }
    }
}  

Note: I'm not too sure how this code will come out >.< it looks as if it's being choppy with the 'code:' function.

Anyways, don't hate too hard on my conventions, I'm still rather new. Tips and answers would be appreciated. Thanks.

Instead of calling Thread.Sleep() try using the swing Timer like this.

private Timer t;

public void moveBall() {
t = new Timer(1000/15, new ActionListener() {

        public void actionPerformed(ActionEvent e) {
             Rectangle bou = new Rectangle(getWidth(), getHeight());
                ball.move(bou);
                ball.update(getGraphics());
                repaint();
        }
    });
    t.start();
}

public void destroy() {
    if(t!=null) t.stop();
    super.destroy();
}

that should help at least a little bit.

I'm assuming the class DoubleBuffering is some tutorial class. I'm guessing it derives from Applet and not JApplet. If you use JApplet you will get double buffering by default.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM