Smoothness depends on your framerate. If you have enough fps and you update the position of all objects every frame it should be perfectly smooth.
Look at this code.
It’s an example of a simple game loop that tries to achieve a given target fps.
class Sprite {
double posX, posY, speedX, speedY;
public void update(double time) {
posX += time*speedX;
posY += time*speedY;
}
}
class Game extends JPanel {
double targetFPS = 60; // try to achieve 60 fps
double timePerFrame = 1.0/targetFPS;
ArrayList<Sprite> sprites = new ArrayList<Sprite>();
//for double buffering
Image image;
public void start() {
image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
int sleep=(int)(timePerFrame*1000);
double timeOfLastFrame = System.nanoTime()/1e9;
double startTime = timeOfLastFrame;
int frames = 0;
while(true) {
double time = System.nanoTime()/1e9;
double timePassed = time - timeOfLastFrame;
timeOfLastFrame = time;
for(s: sprites) {
s.update(timePassed);
}
Graphics g = image.getGraphics();
g.setColor(backgroundColor);
g.fillRect(0, 0, image.getWidth(null), image.getHeight(null));
for(s: sprites) {
s.paint(g);
}
g.dispose();
g = getGraphics();
g.drawImage(image, 0, 0 ,null);
g.dispose();
try {
if(timePassed>timePerFrame && sleep > 0) sleep--;
else if(timePassed<timePerFrame) sleep++;
Thread.sleep(sleep);
} catch (Exception e) {
}
frames++;
time=timeOfLastFrame-startTime;
if(time >= 1) {
double fps=frames/time;
frames=0;
System.out.println("FPS: "+fps);
startTime = timeOfLastFrame;
}
}
}
public void paint(Graphics g) {
g.drawImage(image, 0, 0, null);
}
}