使绘制的对象在JPanel上随机移动

时间:2017-02-21 15:09:24

标签: java swing java-2d

这是我的青蛙类,由GUI类调用。

import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;

import javax.swing.ImageIcon;
import javax.swing.JLabel;

public class Frog implements Runnable {
    private int x, y, dx, dy;
    private int coordinates[]=new int[2];
    private boolean hungry;
    private JLabel jLabel;
    private ImageIcon image;
    private String name;

    public Frog() {

    }

    public  Frog(String name, boolean hungry) {
        image = new ImageIcon("images/frog.jpeg");
        jLabel = new JLabel(image);
        setName(name);
        setHungry(hungry);
        setCoordinates();
    }

    private void setName(String name) {
        this.name=name;
    }

    public int[] getCoordinates() {
        return coordinates;
    }

    public boolean isHungry() {
        return hungry;
    }

    public void setHungry(boolean hungry) {
        this.hungry = hungry;
    }

    public void display(Graphics paper) {
        paper.setColor(Color.black);
        paper.drawOval(x, y, dx, dx);
    }

    public void setCoordinates() {
        for(int i = 0; i < 2; i++) {
            Random rand = new Random();
            int p = rand.nextInt(100);
            coordinates[i] = p;
        }

        setX(coordinates[0]);
        setY(coordinates[1]);
    }

    public void move() {
        x = (int)Math.random() * 350;
        y = (int)Math.random() * 350;
        dx=20;
        dx=20;
        x += dx;
        y += dy;

        if (x > 800 || x < 0)
            dx=-dx;

        if (y > 600 || y < 0)
             dy=-dy;
    }

    public void setDx(int dx) {
        this.dx = dx;
    }

    public void setDy(int dy) {
        this.dy = dy;
    }

    public void setX(int x){
        this.x = x;
    }

    public void setY(int y){
        this.y = y;
    }

    public void run() {
        while(!hungry) {
            move(); 

            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }   
    }
}

我创建了这个类来随机移动一个青蛙对象,但是当我调用move方法时,没有发生任何事情。我希望JPanel上的青蛙在屏幕上随机移动。我有另一个使用青蛙对象的类。

它来自包含以下内容的主类:

public void actionPerformed(ActionEvent event) {
    if (event.getSource() == MakePet) {
        String petName = namePlace.getText();
        frog = new Frog(petName,false);
        panel.add(pet);
        panel.add(prey);
        frog.move();
        Thread fro = new Thread(frog);
        fro.start();
    }
}

public static void main(String[] args) {
    GUI demo = new GUI();
    demo.setSize(520,720);
    demo.createGUI();
    demo.show();
}

1 个答案:

答案 0 :(得分:1)

有关基于计时器的动画示例,请查看http://www.java2s.com/Code/Java/2D-Graphics-GUI/Timerbasedanimation.htm

基于计时器的动画的另一个例子,其中使用Swing组件在JPanel上绘制图像Jérôme的评论:Randomly moving images on a JPanel

如果你需要有多个具有自己控制线程的青蛙,那么你需要处理同步。否则我只需在重新绘制面板之前调用计时器移动。然后改变举动:

public void move() {
    if (!hungry) {
        return;
    }
    ...
}

根据您要实现的帧率适当设置计时器的间隔。以下内容基于Jérôme与以下问题相关的答案:

Timer t = new Timer(1000 / DESIRED_FRAMERATE, (event) -> {
    frogs.forEach(Frog::move);
    panel.repaint();
});

请注意,这是使用lambdas的Java 8.

以上在Java 8之前的版本:

Timer t = new Timer(1000 / DESIRED_FRAMERATE, new ActionListener() {
    public void actionPerformed(ActionEvent event) {
        for (Frog frog : frogs) {
            frog.move();
        }
        panel.repaint();
    }
});

您应该在JFrame或JPanel的初始化代码中创建Timer。如果你有一个扩展JPanel的类,如果Timer在该类中,则在调用repaint时不需要引用面板。另外,在这里我猜你有一个Frog对象的集合,通常是一个名为frogs的列表。如果只有一只青蛙,你就不需要循环了。需要从JPanel的paint方法调用Frog的显示方法,所以我猜你有一个扩展JPanel的类。