[Java]双缓冲无法双缓冲

发布于 2024-10-29 21:15:24 字数 4166 浏览 0 评论 0原文

好吧,正如标题所说,我在双缓冲方面遇到了麻烦。我读过这本 Java 电子书,它没有为您提供他们所教内容的代码 - 至少不完全。所以我必须做很多猜测工作。

目标:在小程序中弹跳球。

球仍然闪烁的方式不起作用。又名双缓冲无法工作。

我使用三个类,球类,双缓冲类和MainApplet类。 MainApplet 扩展了双缓冲,并且 ball 类扩展了 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));
        }
    }
}  

注意:我不太确定此代码将如何出现>。<看起来好像“code:”函数不稳定。

不管怎样,不要太讨厌我的惯例,我还是个新手。提示和答案将不胜感激。谢谢。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

瀟灑尐姊 2024-11-05 21:15:24

不要调用 Thread.Sleep() ,而是尝试使用像这样的 swing 计时器。

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();
}

这至少应该有一点帮助。

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.

只是在用心讲痛 2024-11-05 21:15:24

我假设 DoubleBuffering 类是一些教程类。我猜它源自 Applet 而不是 JApplet。如果您使用 JApplet,默认情况下您将获得双缓冲。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文