This is my frog class which is being called by a GUI class.
这是我的青蛙类,由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();
}
}
}
}
I have created this class to move a frog object randomly but when I call the move
method nothing is happening. I want the frog on a JPanel to randomly move around the screen. I have another class which uses the frog object.
我创建了这个类来随机移动一个青蛙对象,但是当我调用移动方法时,没有任何事情发生。我希望JPanel上的青蛙在屏幕上随机移动。我有另一个使用青蛙对象的类。
It is used from a main class containing the following:
它用于包含以下内容的主类:
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 个解决方案
#1
1
For an example of timer based animation, have a look at http://www.java2s.com/Code/Java/2D-Graphics-GUI/Timerbasedanimation.htm
有关基于计时器的动画示例,请查看http://www.java2s.com/Code/Java/2D-Graphics-GUI/Timerbasedanimation.htm
Another example of timer based animation, where Swing components are used to draw images on a JPanel was given Jérôme's comment: Randomly moving images on a JPanel
另一个基于计时器的动画示例,其中使用Swing组件在JPanel上绘制图像Jérôme的评论:在JPanel上随机移动图像
If you require having multiple frogs with their own threads of control, then you will need to handle synchronization. Otherwise I would simply call move from the timer before repainting the panel. And then change move:
如果你需要有多个具有自己控制线程的青蛙,那么你需要处理同步。否则我只需在重新绘制面板之前调用计时器移动。然后改变行动:
public void move() {
if (!hungry) {
return;
}
...
}
Set the timer's interval appropriately based on the framerate you are looking to achieve. The below is based on the answer from the question Jérôme linked to:
根据您要实现的帧速率适当设置计时器的间隔。以下内容基于Jérôme与以下问题相关的答案:
Timer t = new Timer(1000 / DESIRED_FRAMERATE, (event) -> {
frogs.forEach(Frog::move);
panel.repaint();
});
Note that this is Java 8 using lambdas.
请注意,这是使用lambdas的Java 8。
The above in pre-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();
}
});
You should create the Timer in the initialization code of your JFrame or JPanel. If you have a class extending JPanel, you don't need to reference panel when calling repaint if the Timer is inside that class. Also, here I am guessing you have a collection of Frog objects, typically a list, called frogs
. If there's only ever one frog, you don't need the loop. Frog's display method needs to be called from the JPanel's paint method, so I am guessing you have a class extending JPanel.
您应该在JFrame或JPanel的初始化代码中创建Timer。如果你有一个扩展JPanel的类,如果Timer在该类中,则在调用repaint时不需要引用面板。另外,在这里我猜你有一个Frog对象的集合,通常是一个名为frogs的列表。如果只有一只青蛙,你就不需要循环了。需要从JPanel的paint方法调用Frog的显示方法,所以我猜你有一个扩展JPanel的类。
#1
1
For an example of timer based animation, have a look at http://www.java2s.com/Code/Java/2D-Graphics-GUI/Timerbasedanimation.htm
有关基于计时器的动画示例,请查看http://www.java2s.com/Code/Java/2D-Graphics-GUI/Timerbasedanimation.htm
Another example of timer based animation, where Swing components are used to draw images on a JPanel was given Jérôme's comment: Randomly moving images on a JPanel
另一个基于计时器的动画示例,其中使用Swing组件在JPanel上绘制图像Jérôme的评论:在JPanel上随机移动图像
If you require having multiple frogs with their own threads of control, then you will need to handle synchronization. Otherwise I would simply call move from the timer before repainting the panel. And then change move:
如果你需要有多个具有自己控制线程的青蛙,那么你需要处理同步。否则我只需在重新绘制面板之前调用计时器移动。然后改变行动:
public void move() {
if (!hungry) {
return;
}
...
}
Set the timer's interval appropriately based on the framerate you are looking to achieve. The below is based on the answer from the question Jérôme linked to:
根据您要实现的帧速率适当设置计时器的间隔。以下内容基于Jérôme与以下问题相关的答案:
Timer t = new Timer(1000 / DESIRED_FRAMERATE, (event) -> {
frogs.forEach(Frog::move);
panel.repaint();
});
Note that this is Java 8 using lambdas.
请注意,这是使用lambdas的Java 8。
The above in pre-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();
}
});
You should create the Timer in the initialization code of your JFrame or JPanel. If you have a class extending JPanel, you don't need to reference panel when calling repaint if the Timer is inside that class. Also, here I am guessing you have a collection of Frog objects, typically a list, called frogs
. If there's only ever one frog, you don't need the loop. Frog's display method needs to be called from the JPanel's paint method, so I am guessing you have a class extending JPanel.
您应该在JFrame或JPanel的初始化代码中创建Timer。如果你有一个扩展JPanel的类,如果Timer在该类中,则在调用repaint时不需要引用面板。另外,在这里我猜你有一个Frog对象的集合,通常是一个名为frogs的列表。如果只有一只青蛙,你就不需要循环了。需要从JPanel的paint方法调用Frog的显示方法,所以我猜你有一个扩展JPanel的类。