简体   繁体   中英

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. 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. 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. 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. Instead of doing that, I suggest you display the sheep and dog inside your SheepDog class.

Also instead of using Graphics, you should use Graphics2D. 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. Once you do that, what I would do is override the update() method and do this

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. Towards the top of the class, you should declare

Image image;
Graphics graphics;

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