In order to program something interesting with 2-d motion, I figured that I should start with the absolute basics… linear motion. I typed up this program today to try it out, and it doesn’t completely work. All the calculations it performs at run time turn out slightly differently from what it should be. I noticed that this error margin decreases when I up the fps, but it only does that, decreases it. Does anyone know what I should change to make the game displacement equal to the one it gets from the equation: x=x0 + v0t + (1/2)at^2?
my source code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
import java.applet.*;
public class LinearMotion extends Applet implements MouseMotionListener
{
Graphics g;
Image offscreen;
Dimension dim;
int mouseX, mouseY;
int mouseDX, mouseDY;
double initialVelocity=45;// m/s
double velocity=initialVelocity;
double acceleration=-6;// m/s^2
double startingPosition=20.0;
double position =startingPosition;// m
int meterLength=5;// m/10*pixel
boolean backwards=true;//can velocity become negative? false if friction, etc
boolean finished=false;//if backwards = true, and velocity becomes negative
int fps=100;
int frames = 0;//incremented every screen
ArrayList<Double> oldPositions = new ArrayList<Double>();
Thread t = new Thread();
public void init()
{
dim = getSize();
addMouseMotionListener(this);
setBackground(Color.black);
offscreen = createImage(dim.width,dim.height);
g = offscreen.getGraphics();
t.start();
}
public void paint(Graphics z)
{
try{ t.sleep(1000/fps); }
catch(Exception e){};
g.clearRect(0,0,dim.width,dim.width);
/*Physics Calculations*/
position+=(velocity/(double)fps);
velocity+=(acceleration/(double)fps);
System.out.println(acceleration/fps);
System.out.println(position);
System.out.println(velocity);
if(backwards==false && velocity<0){
velocity=0;
finished=true;
}
frames++;
/*Mark previous displacement positions*/
if(frames%fps==0 && !finished)
oldPositions.add(new Double(position));
/*Draw Grid*/
g.setColor(Color.white);
g.drawLine(0,70,dim.width,70);
for(int x=0;x<dim. width/10;x++){
g.setColor(Color.white);
g.drawLine(x*10,65,x*10,70);
if(x%5==0){
g.drawString(x*meterLength+"",x*10,80);
g.setColor(Color.red);
g.drawLine(x*10,65,x*10,70-1);
}
}
/*Draw moving dot and variables*/
g.setColor(Color.cyan);
int xLoc = (int)(position*10.0/meterLength);
g.drawRect(xLoc,50,1,1);
g.drawLine(xLoc,75,xLoc,65);
g.drawLine(xLoc+1,75,xLoc+1,65);
g.setColor(Color.yellow);
g.drawString("Velocity: "+round(velocity,2)+" m/s",40,100);
g.drawString("Acceleration: "+round(acceleration,2)+" m/s^2",40,120);
g.drawString("Current Position: "+round(position,2)+" m",40,140);
/*Draw previous positions on the grid*/
g.setColor(Color.yellow);
g.drawString("Demo Position",10,170);
g.drawString("Actual Position",130,170);
g.drawString("Difference",250,170);
for(int x=0;x<oldPositions.size();x++){
Double d = oldPositions.get(x);
//draws a box on the grid where the point moves
int drawY=50-1;
g.setColor(Color.yellow);
g.drawRect((int)(d*10.0/meterLength)-1,drawY,2,2);//rect
g.setColor(Color.white);
g.drawString(x+"",(int)(d*10.0/meterLength-3),drawY-10);//#
double demo = round(d,2);
g.drawString("["+x+"]: "+demo,20,200+x*15);//Demo position
int time =x+1;
double actual = (startingPosition+initialVelocity*time+0.5*acceleration*time*time);
g.drawString(""+actual,150,200+x*15);//Actual Position
g.drawString(""+(round(actual-demo,5)),270,200+x*15);//Difference
}
z.drawImage(offscreen,0,0,this);
repaint();
}
public void update(Graphics g)
{
paint(g);
}
public void mouseMoved(MouseEvent evt)
{
mouseX = evt.getX();
mouseY = evt.getY();
repaint();
}
public void mouseDragged(MouseEvent e)
{
mouseDX=e.getX();
mouseDY=e.getY();
repaint();
}
double round(double d, int decimalPlace){
int rounder=1;
for(int x=0;x<decimalPlace;x++)
rounder*=10;
return (double)((int)(d*rounder))/(double)rounder;
}
}