如何在动画循环中同步tick()和render()方法?

时间:2016-06-13 17:26:33

标签: java animation game-loop

我正在使用java图形2D制作动画,基于游戏循环(刻度和渲染)。 我想沿着曲线做一个球,所以我使用FatteningPathIterator从Curved线获取点并将它们保存在ArrayList中。

比我将这组点引用到“球”对象

我最初的想法是使用“Ball”中的tick方法为变量x和y设置一个新值,但是当我这样做时,render()方法似乎与X和Y的当前值不同步会不是因为Thread同步?

如果我尝试更新“Ball”中render()方法内的x和Y位置,球会沿着路径移动,但程序开始变得越来越慢。

以下代码是类:

1 - Animation.java

public class Animation extends Canvas implements Runnable {

public static final int WIDTH = 1024, HEIGHT =  WIDTH/12*9 ;
private Thread thread;
private boolean running = false;

private Handler handler;    
private Line line;

public Animation(){
     new Window(WIDTH, HEIGHT,"Test", this);
     handler = new Handler();

     line = new Line();
     handler.addObject(new Ball(500,500,"Bola",handler,10,line.points()));  


}





public void run() {

    this.requestFocus();
    long lastTime = System.nanoTime();
    double  amountOfTicks = 60.0;
    double ns = 250/amountOfTicks;
    double delta = 0;
    long timer = System.currentTimeMillis();
    int frames = 0;

    while(running){

        long now = System.nanoTime(); 
        delta += (now-lastTime) / ns;
        lastTime = now;

        while(delta >= 1){
            tick();

            delta--;
        }
        if(running) 
            render();

        frames++;

        if(System.currentTimeMillis() - timer >1000){

            timer += 1000;
            frames = 0;
        }
    }
    stop();
}

public synchronized void start(){

        thread = new Thread(this);
        thread.start();
        running = true;
    }

public synchronized void stop(){

        try{
            thread.join();
            running = false;

        }catch(Exception e){
            e.printStackTrace();
        }
    }
private void tick(){

    handler.tick();

}

private void render(){
    BufferStrategy bs = this.getBufferStrategy();
    if(bs == null){
        this.createBufferStrategy(3);
        return;
    }

    RenderingHints rh = new RenderingHints(
            RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);

    rh.put(RenderingHints.KEY_RENDERING,
            RenderingHints.VALUE_RENDER_QUALITY);     



    Graphics g = bs.getDrawGraphics();
    Graphics2D g2d = (Graphics2D)g;
    g2d.setRenderingHints(rh);
    g2d.setColor(Color.white);
    g2d.fillRect(0, 0, WIDTH, HEIGHT);

    line.render(g2d);
    handler.render(g);

    g.dispose();
    g2d.dispose();
    bs.show();
}

public static void main(String args[]){
    new Animation(); 
 }}

2 - Window.java

public class Ball extends Object {

ArrayList<Point> points = new ArrayList<Point>();
int index = 0;


private int raius;
public Ball(int x, int y, String id, Handler handler, int raius, ArrayList<Point> points) {
    super(x, y, id,handler);
    this.raius = raius;
    this.points = points;
    System.out.println(points);
    velX = 5;
    x = 0;

    System.out.println("Here");
}

public void tick() {
    index++;
    if (index>=points.size()) {
        index=0;
    }
    x = points.get(index).x;
    y  = points.get(index).y;
}   
public void render(Graphics g) {


    g.setColor(Color.red);

    g.fillOval(x, y, raius, raius);

}}

3 - Object.java

public abstract class Object {

protected int x,y;
protected String id;
protected int velX, velY;
protected Handler handler;

public Object(int x, int y, String id, Handler handler){

        this.x = x;
        this.y = y;
        this.id = id;
        this.handler = handler;
    }

public abstract void tick();
public abstract void render(Graphics g);

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

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

public int getX(){
    return x;
}

public int getY(){
    return y;
}

public void setId(String id){
    this.id = id;       
}

public String getId(){
    return id;
}

public void setVelX(int velX){
    this.velX = velX;
}

public void setVelY( int velY){
    this.velY = velY;
}

public int getVelX(){
    return velX;
}

public int getVelY(){
    return velY;
}}

4 - Line.java

public class Line {

FlatteningPathIterator iter;
Shape shape;
ArrayList<Point> points;
CubicCurve2D cubcurve = new CubicCurve2D.Float(30, 400, 150, 400, 200, 500, 350, 450);

public Line(){
     shape = cubcurve;
     iter = new FlatteningPathIterator( cubcurve.getPathIterator(new AffineTransform()), 0.5);
     points=new ArrayList<Point>();
     float[] coords=new float[6];
     while (!iter.isDone()) {
         iter.currentSegment(coords);
         int x=(int)coords[0];
         int y=(int)coords[1];
         points.add(new Point(x,y));
         iter.next();
     }
     System.out.println(points);
}


public ArrayList<Point> points(){
    return points;
}

public void render(Graphics g){


    Graphics2D g2d = (Graphics2D) g;

    BasicStroke bs3 = new BasicStroke(4, BasicStroke.CAP_ROUND,
            BasicStroke.JOIN_BEVEL);

    g2d.setStroke(bs3);     
    g2d.setColor(Color.blue);       
    g2d.draw(cubcurve);

}}

5- Ball.java

public class Ball extends Object {

ArrayList<Point> points = new ArrayList<Point>();
int index = 0;


private int raius;
public Ball(int x, int y, String id, Handler handler, int raius, ArrayList<Point> points) {
    super(x, y, id,handler);
    this.raius = raius;
    this.points = points;
    System.out.println(points);
    velX = 5;
    x = 0;

    System.out.println("Here");
}

public void tick() {
    index++;
    if (index>=points.size()) {
        index=0;
    }
    x = points.get(index).x;
    y  = points.get(index).y;
}   
public void render(Graphics g) {


    g.setColor(Color.red);

    g.fillOval(x, y, raius, raius);

}}

0 个答案:

没有答案