我正在Swing(Graphics2d库)中创建Boid算法的模拟,所以我想要动画许多形状(三角形)。现在我正在学习如何移动它们并遇到fps和重新绘制的问题。
当我在屏幕上放置两个以上的三角形时(例如,10),fps显着下降,我真的不知道问题出在哪里。这是代码(我省略了库):
public class Program {
/**
* @param args
*/
public static void main(String[] args) {
World world = World.getInstance();
// Initialise and show world
JFrame f = new JFrame();
f.setSize(world.getBoundsX(),world.getBoundsY());
f.setTitle("Boids Alive");
f.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(world);
f.setResizable(false);
f.setVisible(true);
for(int i = 0 ; i < 10; i++)
world.createBoid();
while(true){
//adjust all behaviours
for(Boid b : world.boids){
b.move(0, -2);
}
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
world.refreshAll();
}
}
public final class World extends JPanel {
private static final long serialVersionUID = 1L;
private Random r = new Random();
private static final int boundsX = 800;
private static final int boundsY = 600;
public ArrayList<Boid> boids = new ArrayList<Boid>();
public ArrayList<Obstacle> obstacles = new ArrayList<Obstacle>();
private static World instance = null;
private World() {
this.setBackground(Color.white);
}
public static World getInstance(){
if(instance == null)
instance = new World();
return instance;
}
public int getBoundsX() { return boundsX; }
public int getBoundsY() { return boundsY; }
public void createBoid(){
Boid b = new Boid() ;
b.setX(r.nextInt(790));
b.setY(r.nextInt(590));
boids.add(b);
b.start() ;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
}
public void refreshAll() {
for(Boid b : boids) {
b.graphicEle.refreshLocation();
}
}
}
public class Boid extends WorldObject{
public Boid() {
graphicEle = new GraphicElement(this);
World world = World.getInstance() ;
world.add(graphicEle) ;
world.repaint() ;
world.validate() ;
}
public void move(int x, int y) {
this.x += x;
this.y += y;
checkBounds();
try {
sleep(15);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void checkBounds() {
World world = World.getInstance() ;
if(this.x < 0) x = world.getBoundsX();
if(this.x > world.getBoundsX()) x = 0;
if(this.y < -20) y = world.getBoundsY(); //TODO: get the actual size
if(this.y > world.getBoundsY()) y = 0;
}
}
public class GraphicElement extends JPanel {
private static final long serialVersionUID = 1L;
private WorldObject owner;
public GraphicElement(WorldObject obj) {
owner = obj ;
setPreferredSize(new Dimension(20, 20));
setOpaque(false);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create(); //TODO Move to boid class
g2d.setColor(Color.orange);
Path2D.Double triangle = new Path2D.Double();
triangle.moveTo(0, 20);
triangle.lineTo(10, 0);
triangle.lineTo(20, 20);
triangle.closePath();
g2d.fill(triangle);
g2d.dispose();
}
protected void refreshLocation() {
setLocation(owner.getX(), owner.getY());
}
}
任何想法我做错了什么?我应该使用translate()
代替setLocation()
吗?