简体   繁体   English

通过双缓冲Java Applet停止applet闪烁

[英]stop applet flickering with double buffering Java Applet

sorry to keep asking questions about my program but i think i'm nearly there and i'm teaching myself java so please bear with me. 很抱歉继续询问有关我的程序的问题,但是我想我已经快到了,而且我正在自学Java,所以请多多包涵。 I'm creating an applet that moves sheep object across the screen in a random direction when a dog object moves close to the sheep. 我正在创建一个applet,当狗对象靠近绵羊时,它将绵羊对象在屏幕上随机移动。 Getting the sheep to move in a random direction took some work and with the help of you guys on here it now works (sort of) but what I'm trying to do now is stop it from flickering when i drag objects across the screen. 让绵羊沿随机方向移动需要一些工作,并且在你们的帮助下,它现在可以工作了(但有些),但是我现在要做的是阻止我在屏幕上拖动对象时闪烁。 I've read about double buffering, I can get it to work for items drawn in the paint method of a main class but cant get it to work for my sheep and dog objects which are defined as separate objects in separate classes. 我已经读过有关双重缓冲的知识,我可以使它适用于在主类的paint方法中绘制的项目,但不能使其适用于在不同类中定义为单独对象的绵羊和狗对象。 Any help will be much appreciated. 任何帮助都感激不尽。 Here is my code: 这是我的代码:

    package mandAndDog;

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;


public class SheepDog extends Applet implements ActionListener, MouseListener, MouseMotionListener
{
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    /**
     * 
     */

    Dog dog;
    Sheep sheep;
    int[] directionNumbersLeft = {0, 1, 3};
    int[] directionNumbersUp = {0, 1, 2};
    int x;
    int selection;
    int xposR;
    int yposR;
    int sheepx;
    int sheepy;
    int sheepBoundsx;
    int sheepBoundsy;
    int MAX_DISTANCE = 50;
    int direction;
    int distance;
    Boolean sheepisclosetodog;


    public void init()
    {
        addMouseListener(this);
        addMouseMotionListener(this);
        dog = new Dog(10, 10);
        sheepx = 175;
        sheepy = 75;
        sheep = new Sheep(sheepx, sheepy);
        sheepBoundsx = 30;
        sheepBoundsy = 30;
        direction = (int)(Math.random()*4); 
        distance = (int) (Math.random() * MAX_DISTANCE) % MAX_DISTANCE;
        sheepisclosetodog = false;
        Random rand = new Random();
        x = rand.nextInt(3);
        selection = directionNumbersLeft[x];

    }
    public void paint(Graphics g)
    {
        dog.display(g);
        sheep.display(g);
        g.drawString(Integer.toString(distance), 85, 100);
        g.drawString(Integer.toString(direction), 85, 125);
        g.drawString(Integer.toString(selection), 85, 140);

    }
    public void actionPerformed(ActionEvent ev)
    {}
    public void mousePressed(MouseEvent e)
    {}
    public void mouseReleased(MouseEvent e)
    {}
    public void mouseEntered(MouseEvent e)
    {}
    public void mouseExited(MouseEvent e)
    {}
    public void mouseMoved(MouseEvent e)
    {
    }
    public void mouseClicked(MouseEvent e)
    {}
    public void mouseDragged(MouseEvent e)
    {
        dog.setLocation(xposR, yposR);
        sheep.setLocation(sheepx, sheepy);
        if (xposR > (sheepx - 20)&& xposR < (sheepx - 20)+(sheepBoundsx - 20) && yposR > (sheepy - 20)
                && yposR < (sheepy - 20)+(sheepBoundsy - 20) && direction == 0){
            sheepx = sheepx + 50;
            direction = (int)(Math.random()*4); 
        }
        if (xposR > (sheepx - 20)&& xposR < (sheepx - 20)+(sheepBoundsx - 20) && yposR > (sheepy - 20)
                && yposR < (sheepy - 20)+(sheepBoundsy - 20) && direction == 1){
            sheepy = sheepy + 50;
            direction = (int)(Math.random()*4); 
        }

        if (xposR > (sheepx - 20)&& xposR < (sheepx - 20)+(sheepBoundsx - 20) && yposR > (sheepy - 20)
                && yposR < (sheepy - 20)+(sheepBoundsy - 20) && direction == 2){
            sheepx = sheepx - 50;
            direction = (int)(Math.random()*4); 
        }
        if (sheepx <= 5){
            direction = directionNumbersLeft[x];
        }


        if (xposR > (sheepx - 20)&& xposR < (sheepx - 20)+(sheepBoundsx - 20) && yposR > (sheepy - 20)
                && yposR < (sheepy - 20)+(sheepBoundsy - 20) && direction == 3){
            sheepy = sheepy - 50;
            direction = (int)(Math.random()*4); 
        }
        if (sheepy <=5){
            direction = directionNumbersUp[x];
        }

        xposR = e.getX();
        yposR = e.getY();
        repaint();

    }
}

class Dog 
{
    int xpos;
    int ypos;
    int circleWidth = 30;
    int circleHeight = 30;

    public Dog(int x, int y)
    {
        xpos = x;
        ypos = y;

    }

    public void setLocation(int lx, int ly)
    {
        xpos = lx;
        ypos = ly;
    }

    public void display(Graphics g)
    {
        g.setColor(Color.blue);
        g.fillOval(xpos, ypos, circleWidth, circleHeight);
    }       
}
class Sheep
{
    int xpos;
    int ypos;
    int circleWidth = 10;
    int circleHeight = 10;

    public Sheep(int x, int y)
    {
        xpos = x;
        ypos = y;

    }

    public void setLocation(int lx, int ly)
    {
        xpos = lx;
        ypos = ly;
    }

    public void display(Graphics g)
    {
        g.setColor(Color.green);
        g.fillOval(xpos , ypos, circleWidth, circleHeight);
        g.drawOval(xpos - 20, ypos - 20, 50, 50);
    }


}

First of all, I dont exactly understand why you have a display method inside your Sheep and Dog class. 首先,我不完全理解为什么在Sheep and Dog类中有显示方法。 Instead of doing that, I suggest you display the sheep and dog inside your SheepDog class. 与其相反,我建议您在SheepDog类中显示绵羊和狗。

Also instead of using Graphics, you should use Graphics2D. 另外,应该使用Graphics2D而不是Graphics。 In order to use this simply do 为了使用这个简单地做

public void paint(Graphics g) {
    Graphics2D g2 = (Graphics2D) g;
}

This is possible because Graphics2D is a subclass of Graphics. 这是可能的,因为Graphics2D是Graphics的子类。 Once you do that, what I would do is override the update() method and do this 完成此操作后,我要做的就是覆盖update()方法并执行此操作

public void update(Graphics g) {
    if (image == null) {
        image = createImage(this.getWidth(), this.getHeight());
        graphics = image.getGraphics();
    }
    graphics.setColor(getBackground());
    graphics.fillRect(0,  0,  this.getWidth(),  this.getHeight());
    graphics.setColor(getForeground());
    paint(graphics);
    g.drawImage(image, 0, 0, this);
}

When you call repaint(), it actually first calls the update() method, which in turn calls the paint() method. 当您调用repaint()时,它实际上首先调用了update()方法,该方法又调用了paint()方法。 Towards the top of the class, you should declare 在课堂上,您应该声明

Image image;
Graphics graphics;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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