может использовать вашу домашнюю домашнюю работу с участием таймеров качания, слушателей действий и нескольких объектов. Я не знаю, разрешена ли публикация вопроса, но у меня проблемы с анимацией, вот что я до сих пор
Создайте класс Particle, который имеет два двойных поля x и y, конструктор, который инициализирует эти поля случайными значениями от 0 до 500, методы getX и getY, которые возвращают свои значения, и метод void move(), который случайным образом добавляет или вычитает один из каждое из значений x и y. (Величины, добавленные к x и y, представляют собой два отдельных случайных числа.) Затем создайте класс ParticleFieldWithTimer, который расширяет JPanel. Этот класс должен быть размером 500 * 500 пикселей. Его конструктор должен сначала заполнить поле ArrayList 100 объектами частиц, а затем запустить таймер Swing, который гасит 25 раз в секунду. При каждом тике слушатель действия должен сначала вызвать метод перемещения для каждой частицы, а затем вызвать перерисовку. Метод paintComponent ParticleFieldWithTimer должен рисовать каждую частицу в виде прямоугольника 3 * 3 в ее текущие координаты. Убедитесь, что таймер остановится, когда пользователь закрывает рамку
Это класс ParticleFieldWithTimer
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class ParticleFieldWithTimer extends JPanel{
private ArrayList<Particle> particle = new ArrayList<Particle>();
Timer timer;
boolean b;
public ParticleFieldWithTimer (){
this.setPreferredSize(new Dimension(500,500));
for(int i = 0; i < 100; i++) {
particle.add(new Particle());
timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
// change polygon data
// ...
Particle p = new Particle();
p.move();
repaint();
}
});
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
for (Particle p: particle) {
double temp1 = p.getX();
double temp2 = p.getX();
int tempX = (int) temp1;
int tempY = (int) temp2;
g2.fillRect(tempX, tempY, 3, 3);
}
}
public static void main(String[] args) {
final JFrame f = new JFrame("ParticleField");
final ParticleFieldWithTimer bb = new ParticleFieldWithTimer();
f.setLayout(new FlowLayout());
f.add(bb);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
try {
bb.finalize();
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
f.dispose();
}
});
f.pack();
f.setVisible(true);
}
}
Это класс частиц
import java.util.Random;
public class Particle {
private double x , y ;
Random r = new Random();
public Particle () {
x = r.nextDouble()*500;
y = r.nextDouble()*500;
}
public Double getX() {
return x;
}
public Double getY() {
return y;
}
public void move() {
x = r.nextInt(2) - 1;
y = r.nextInt(2) - 1;
System.out.println(x + " " + y);
}
}
Эта...
for(int i = 0; i < 100; i++) {
particle.add(new Particle());
timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
// change polygon data
// ...
Particle p = new Particle();
p.move();
repaint();
}
});
}
Это неправильный подход, он создает 100 Timer
, что повлияет на производительность вашей системы.
Вы также создаете новый Particle
каждый раз, когда таймер тикает, что не то, что вы действительно хотите сделать, вы хотите повлиять на Particle
вы уже создали...
Вместо этого создайте свои частицы...
for(int i = 0; i < 100; i++) {
particle.add(new Particle());
}
Затем создайте свой Timer
и внутри него, прорежьте частицы, которые вы уже создали...
timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
for (Particle p : particle) {
p.move();
}
repaint();
}
});
Не забудьте запустить таймер...
timer.start();
Или измените цвет контекста Graphics
, который, вероятно, все еще установлен на фоне панели...
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.RED);
for (Particle p : particle) {
Я также отметил, что...
x = r.nextInt(2) - 1;
y = r.nextInt(2) - 1;
Не делает то, что вы хотите. Он всегда будет делать значения между -1 и 1. Вместо этого вы хотите добавить результат к значениям x/y...
x += r.nextInt(2) - 1;
y += r.nextInt(2) - 1;
Теперь этот тип сделал значения "перетаскиванием" по экрану (в основном) единообразным образом...
Вы можете попробовать использовать...
x += r.nextBoolean() ? 1 : - 1;
y += r.nextBoolean() ? 1 : - 1;
Но это в конечном итоге заставило их танцевать на месте (в основном)...
repaint
. На самом деле это не имеет большого значения, так какRepaintManager
может объединять повторяющиеся вызовы дляrepaint
в одно событие рисования, но зачем рисковать. Обновите модель в один шаг, обновите вид в следующий. Поскольку действиеactionPerformed
выполняется в контексте EDT, вызовrepaint
будет иметь никакого эффекта, пока ПОСЛЕ того,actionPerformed
методactionPerformed
любом случаеactionPerformed
(paintComponent
не может быть вызван, покаactionPerformed
существуетactionPerformed
)