остановить мерцание апплета с двойной буферизацией Java Applet

извините, что продолжаю задавать вопросы о моей программе, но я думаю, что почти закончил, и я учу себя Java, поэтому, пожалуйста, потерпите меня. Я создаю апплет, который перемещает объект овцы по экрану в случайном направлении, когда объект собаки приближается к овце. Чтобы заставить овцу двигаться в случайном направлении, потребовалась некоторая работа, и с помощью вас, ребята, она теперь работает (вроде как), но сейчас я пытаюсь остановить ее мерцание, когда я перетаскиваю объекты по экрану. Я читал о двойной буферизации, я могу заставить ее работать для элементов, нарисованных в методе рисования основного класса, но не могу заставить ее работать для моих объектов овец и собак, которые определены как отдельные объекты в отдельных классах. Любая помощь будет высоко ценится. Вот мой код:

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


}

person Will    schedule 02.09.2012    source источник
comment
Самый простой способ: смените свой апплет на Swing JApplet, нарисуйте метод paintComponent(...) JPanel и воспользуйтесь преимуществами автоматической двойной буферизации Swing.   -  person Hovercraft Full Of Eels    schedule 02.09.2012
comment
См. также Начальные потоки.   -  person trashgod    schedule 02.09.2012


Ответы (1)


Прежде всего, я не совсем понимаю, почему у вас есть метод отображения внутри вашего класса Sheep and Dog. Вместо этого я предлагаю отображать овцу и собаку внутри класса SheepDog.

Также вместо использования Graphics вы должны использовать Graphics2D. Чтобы использовать это, просто выполните

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

Это возможно, потому что Graphics2D является подклассом Graphics. Как только вы это сделаете, я бы переопределил метод 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);
}

Когда вы вызываете метод repaint(), он сначала вызывает метод update(), который, в свою очередь, вызывает метод paint(). В верхней части класса вы должны объявить

Image image;
Graphics graphics;
person kikiotsuka    schedule 28.01.2013