如何在Java Swing中为三角形设置动画以向前移动

时间:2015-04-13 11:57:55

标签: java multithreading swing animation graphics2d

我正在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()吗?

0 个答案:

没有答案