问题
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);
}
}
回答1:
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;
来源:https://stackoverflow.com/questions/12232541/stop-applet-flickering-with-double-buffering-java-applet