I would use gage, but I can't because this is for applets and I don't want the user to have to grant permission to use my program.
It's a common misconception that GAGE can't be used without the DLL. It can, in fact, be used without difficulty. The only thing you need to be aware of is that you're only getting 100 ticks per second, EXACTLY. Time your framerate accordingly! Good values include 25fps, 50fps, and 100fps. Also, make sure you calculate these framerates. If you assume 100 ticks per second, you're going to get into trouble if someone uses Java 1.5 (which runs with nanosecond precision).
If I use gage, that will solve the fps problem but the problem with animation will persist. I know this because I was using gage with the engine until just recently. The problem is that the sprites are shaking while they move, this seems obvious to me that it is being caused by rounding off the x,y positions before drawing. I'll continue to look through david brackeen's source becuase I don't think I've ever seen a java2D game that runs that smooth.
That's because of the way that interpolation works on a 2D screen. Interpolation works well in 3D, because 3D coordinates are virtual. i.e. They don't correspond to any given element. In 2D, your objects correspond to pixels. The eye is VERY sharp and will notice the "jitter" caused by moving 1 pixel, then 2, then 1 again. The only real solution to this is to do sub-pixel rendering, which is really too slow for a video game.
The next best solution is to work your objects so that their movement coresponds to the framerate. e.g. I have a framerate of 50fps. Thus a character that moves 25 pixels per second will look better than a character that moves 30. In the case of the former, the character will move a smooth one pixel every other frame. In the case of the later, it will move an extra pixel every few frames.
Before I disappear, here's an explanation I once gave on interpolating movement. I'm not sure if it will help you solve your problem, but it may give you a few ideas:
As to decoupling from the frame-rate, it's very easy to do. All you
need is a good timer (GAGETimer would probably meet your needs) and a
few calculations to "map" movement to the frame rate. The core idea is
that the characters will work inside their own timeframe. For example,
let's say I have a character who moves 100 pixels every second. We can
then use that number in each loop to interpolate the amount to move:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| int movepixels = 100;
double actualpixels;
while(true) { actual += (timer.getClockTicks()-lasttime)/timer.getTicksPerSecond() * movepixels; lasttime = timer.getClockTicks();
character.x += (int)actual; actual -= Math.floor(actual); } |
What the above code does is that it defines how many pixels a
character moves per second. An "actual" variable is then set up to
keep track of the interpolation. You'll note that the "actual"
variable is a double. This is so we can keep track of "partial pixels"
so that the animation doesn't look jerky due to rounding errors.
From there, we calculate the number of pixels to move since the last
frame, update the lasttime variable, add the integral part of the
number to the character's position, then subtract the integral portion
of the number from the "actual" number.
At 60 frames per second, the above should produce about 1.6 pixels of
movement per frame. Given the rounding involved, this means that the
character will tend to move 1 pixel, then 2 pixels, then 1 pixel, then
2 pixels, etc. Here's what the "actual" variable will calculate to
each time:
actual = 1.6 (remainder .6)
actual = 2.2 (remainder .2)
actual = 1.8 (remainder .

actual = 2.4 (remainder .4)
actual = 2.0 (remainder .0)
actual = 1.6 (remainder .6)
The exact formula that was used for interpolation is:
Let s = ticks per second
Let t = ticks since last movement
Let m = pixels to move per second
Let x = interpolated number of pixels to move
We then solve for 'x' as:
x = t/s * m
The only thing that I haven't covered here is moving in a diagonal
fashion. That's really not that difficult as you can use the
"distances" calculated with this formula in a line drawing formula
like Bresenham.