I’m writing an Arkanoid/Breakout clone in Java (fullscreen exclusive mode). What’s the best way to make the movement/speed of the ball independent of framerate? Currently I do step() (which moves the ball a certain number of pixels in x and y) once every frame. Obviously, this isn’t what one would like, I just did this for testing purposes. So, is there an optimal way of handling the movement? Suggestions?
The way to do it goes something like this (pseudo-code)
- When game is loaded grab and store the time, and render the screen.
- At the start of the next frame grab the time again and work out the time since the last grab of the time. Store the new time.
- Distance moved = the speed (a constant of your choice for a nice speed) * the time.
For example, you load the game and call System.currentTimeMillis(). You store this in a long variable called lastTime. You render the scene. Get the time again and calculate the difference since the first time, multiplying this time by the speed, say for example the speed is 10 and 0.1secs have passed, you move the paddle 10*0.1 = 1 pixel. You then store the new time into the lastTime variable and repeat?
Hope that is a start, try coding it now
Stu
Yup, thought about doing it like that. I hope the accuracy/resolution of System.currentTimeMillis() is good enough for this. If not, I suppose movement may become less smooth than desired. Well I’ll just have to try it and find out.
Well, I am using this in a game I am writing, and it is not far off from being accurate enough, check the shared code section for information on more accurate timers!
Stu
A slightly more complicated method that, thankfully, removes the need for delta time, is using fixed time steps. The general idea is that each game logic tick represents a constant amount of “real” time. A great article (complete with very usable source code!) can be found at flipCode.
sharpshooter, your original method is in fact the only way to do it right. Cap the frame rate and tune the movement to that framerate such that it runs at the right speed on the slowest machine you wish to support. Or your breakout game will be unplayable.
Cas
Actually, I’m just realizing that. Since the “normal” per-frame movement of the ball is a just few pixels, it will be really difficult to do any kind of adjusting to account for a varying framerate. If just a little more time than that which would represent one “unit step” of the ball has passed, it would instead move twice as fast at 2*“unit step”. Unfortunately(?), the resolution of the movement is too crude to be used for adjusting the speed. If the “normal” step size would be 50 pixels, the situation would be another, one could then tune the speed much better. If you know what I mean.
Ah an easy solution: sub-pixel accuracy.
A long phrase that basically means, store your current position, speed etc. as floats, and only convert to integer pixels when you need to draw to screen.
Why don’t you use a Thread? For example, let’s say I have some sort of projectile moving across the screen (like a baseball or something):
NOTE: My indenting seems to have been lost…
import java.awt.Point;
class Baseball implements Runnable {
Thread ballMovementThread;
int currX; // Current x-axis location of ball
int currY; // Current y-axis location of ball
int xSpeed; // Num pixels per frame along the x-axis
int ySpeed; // " " " " y-axis
int delay; // Delay between movements (milliseconds)
public Baseball(int currX, int currY, int xSpeed, int ySpeed, int delay) {
this.currX = currX;
this.currY = currY;
this.xSpeed = xSpeed;
this.ySpeed = ySpeed;
this.delay = delay;
BallMovementThread = new Thread(this);
BallMovementThread.start();
} // CONSTRUCTOR
public void run() {
while (keepThreadAlive) {
currX += xSpeed;
currY += ySpeed;
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
// Do nothing
}
}
} // method run
// For rendering
public Point getCurrBallLocation() {
return (new Point(currX, currY));
}
// Lets the thread exit nicely, and stops tracking movement of ball
public synchronized void endMovement() {
keepThreadAlive = false;
}
}
========================
Using threads allow objects that should act independently of other actions in your app / game to do so.
Threads use very little resources - they’re quick to create and destroy. The eliminate the need for delta time, AND you don’t have to worry about the framerate. The ball will move the same speed (relative to real-time) regardless of your framerate, or whatever else your game is doing.
Threads also make compact, easy to maintain/debug code. No tweaking…just write the thread, and make it sleep using Thread.sleep(int) to act as the delay between movements of the ball. You could use the logic ‘tick’ idea, but this could raise problems (i.e. the more complicated your code gets, the more stuff needs to be done between each ‘tick’ and you’ve got a code dependence rather than a framerate dependence.
What I mean is, you can’t move the ball each time a frame is rendered, because the timing is hard. For the same reason, you can’t use logic ticks, because ‘ticks’ go by faster on faster machines, and then you’ve got a ball moving at different speeds on the screen depending on the speed of the system running your program.
Using threads eliminates the dependence on outside timing (like the framerate or logical ‘ticks’ - and so long as game is running on a sufficiently fast machine (which is strongly determined by the efficiency of the code you write) then the ball will move the same speed on the screen whether it’s a 200MHz machine, or a 2.5GHz machine.
If you want to know more about the Thread class, and multi-threaded programs (and I promise they’re an incredible tool that you won’t go without once you use them), I recommend “Multithreaded Technology with Java”
It’s down to 27.99 on Amazon - and worth every penny of the $40 bucks I spent on it when it was new.
Also, sub-pixel accuracy isn’t a bad idea. There’s a tradeoff here, however. The smaller the movement an object takes each time it moves, the move steps it has to take to get to where it is going.
More steps = more operations = requires faster machine to acheive same results as larger step.
Now, a smaller step will give you smoother movement / animation, so there’s something to consider.
Personally I like to think in terms of distance over time. If your moving object travels say 10 pixels per second (real time), then the step between each movement should be small enough so that if you’re able to render @60 fps, the movements don’t look jerky.
To further illustrate, let’s say you’ve got an Arkanoid ball that needs to move across the screen at a constant rate of 30 pixels/second. If your game will be running @30 fps or higher, then the ball should appear to be located at each and every pixel location along its path (since @30fps, the ball should travel at 1 pixel/frame). However, if the game is running @15 fps, then the ball should appear to be moving at 2 pixels/second.
The Thread solution above will accomplish this. Just set the delay between movements to say 33 milliseconds, and the pixel speeds to 1 (i.e. 1 pixel movement every 33 milliseconds - or 30 pixels per second). If you need it to work at even higher frame rates, set the delay lower, and the movement speed lower to accomidate higher frame rates. Plan for the highest frame rate needed (probably nothing over 60fps).
Did I blather on enough yet?
(apparently not!)
Correction: @15 fps, the ball should appear to be moving at 2 pixels/frame (NOT per second).
Theoretically, even at 10 Million frames-per-second, the speed of the ball (in the Thread solution) wouldn’t need to be any lower than 1, and the delay between movements lower then 33 to achieve 30 pixels/second movement, because the movement of the ball is independent of the framerate, and it’s pointless to move the ball a fraction of a pixel - there would be no noticable movement on the screen.
I’ve used the Thread class in lots of applications, in fact I used it in a similar game to this one a year or so ago. I found however, that the movement of the ball was still somewhat jerky. That time I didn’t finish the game so I didn’t really bother investigating the problem any further. It seemed it was the JVM or something that was a bit jerky sometimes with half-a-second flickers from time to time.
For my current game I’m currently using frame-based movement (i.e. I move the ball a certain amount each frame) and it works really well so far though I am a bit reluctant to this kind of programming. I might try using a thread and compare the results, after all I’ve taken a number of courses in realtime programming and the beauty of using threads cannot be overstated. ;D
oh dear, the old ‘1 Thread per game object’ technique.
It is far 2 inefficient for anything but trivial examples.
Do yourself and every1 else a favour kul_th_las, stop giving bad advice.
Ack, not another one :o Personally I blame this applet: http://java.sun.com/docs/books/tutorial/essential/threads/deadlock.html i’d swear it give too many people evil ideas…
Give me a break. You don’t have to have one Thread for EVERY moving object. But you could have a single movement Thread (or Threads that group similar objects together).
Beside’s he’s talking about doing Arkanoid. How many moving objects can there be?
Threading is also an easy way to implement frame-skipping. If you want your objects to move independently of your frame rate (which I thought was the point of this post subject), then I answered the question.
When you cap you’re framerate you have to play to the lowest-power machine that you want to support. It’s fine that older machines get less than spectacular performance when compared to newer machines running the same game. But why should someone with a powerful enough machine not be able to run the game at its best framerate? You’re losing some of your scalability, and I don’t see how that can be good advice.
Furthermore, threading deadlocks can be avoided through better program design.
Ah, but Java’s threads aren’t time slices. They don’t work quite the way you’d expect, and you run the risk that when your system gets a little more complicated, or the computer you’re running on is slightly more loaded than normal, you suddenly find that your movement thread is hardly ever getting run-time.
It is possible to monitor the frame rate your application is getting, and modify the per-frame adjustments to your object’s positions accordingly - this allows you to keep everything in one thread. You run the risk of having things speed up or slow down if you’re not keeping quite in step with the frame rate, but it should be acceptable for a computer game.
Does that help?
For some people around here, threads seem to be the Saddam Hussein of programming. Stop this discussion and save your time…it’s fruitless here on threadhaters.org.
Hey, only trying to help. I’ve been stung by using threads before and I wish someone had told me how they really work.
My particular problem was the way that threads on my P200MMX executed totally differently from the P2 233 machine I was supposed to demo on. Naturally, I didn’t get access to the demo box until five minutes before the demo itself, and it nearly ruined everything. A small race condition that hadn’t come up during testing suddenly caused everything to fail… By randomly rebooting the browser I managed to get it to work just as the examiners walked through the door… ;D
But hey, feel free to use threads as much as you like. Be warned however that they don’t operate like time-slices, so develop accordingly. :-X
Sometimes threads are the optimal solution, sometimes they are not, no point in flaming each other arguing that one is always better than the other. Personally, I find that threads are an incredibly convenient way of solving a lot of programming issues as well as making code and design more easy to understand. However, it is not always suitable to use threads. Since I haven’t written an application like this one before (well, not finished one anyway) I’ll try a few different techniques and see what works best in practice, which is what matters.