I am making a animation with java graphics 2D, based on a game loop(tick and render). I want to make a ball walk along a curved line, so I am using a FatteningPathIterator to obtain the points from the Curved line and save them in a ArrayList.
Than I reference this group of points to a "Ball" Object
My original idea is o use the tick method in "Ball" to set a new value for the variables x and y, but when I do this the render() method seems to not synchronize with the current values of X and Y. Would it be because of Thread synchronization?
If I try to update the x and Y positions inside the render() method in "Ball", the ball moves along the path but the program starts to get slower and slower.
The following code are the classes:
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);
}}