Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (106)
games submitted by our members
Games in WIP (533)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Framerate-independent movement  (Read 4340 times)
0 Members and 1 Guest are viewing this topic.
Offline sharpshooter

Senior Newbie




Java games rock!


« Posted 2003-02-11 18:24:56 »

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?  Smiley
Offline Stuart Still

Senior Newbie





« Reply #1 - Posted 2003-02-11 18:56:13 »

The way to do it goes something like this (pseudo-code)

1.  When game is loaded grab and store the time, and render the screen.
2. 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.
3.  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 Smiley

Stu
Offline sharpshooter

Senior Newbie




Java games rock!


« Reply #2 - Posted 2003-02-11 19:29:06 »

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. Smiley
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Stuart Still

Senior Newbie





« Reply #3 - Posted 2003-02-11 19:33:05 »

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
BlackArrow
Guest
« Reply #4 - Posted 2003-02-11 23:08:04 »

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.
Offline princec

JGO Kernel


Medals: 342
Projects: 3
Exp: 16 years


Eh? Who? What? ... Me?


« Reply #5 - Posted 2003-02-12 11:18:56 »

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 Smiley

Offline sharpshooter

Senior Newbie




Java games rock!


« Reply #6 - Posted 2003-02-12 12:11:00 »

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.  Smiley
Offline Orangy Tang

JGO Kernel


Medals: 56
Projects: 11


Monkey for a head


« Reply #7 - Posted 2003-02-12 13:48:41 »

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.

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
kul_th_las
Guest
« Reply #8 - Posted 2003-02-18 23:11:23 »

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... Tongue

[size=3]
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;
    }

}

[/size]


========================
Using threads allow objects that should act independently of other actions in your app / game to do so.
kul_th_las
Guest
« Reply #9 - Posted 2003-02-18 23:27:19 »

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.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
kul_th_las
Guest
« Reply #10 - Posted 2003-02-18 23:42:24 »

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?
kul_th_las
Guest
« Reply #11 - Posted 2003-02-18 23:44:23 »

(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.
Offline sharpshooter

Senior Newbie




Java games rock!


« Reply #12 - Posted 2003-02-19 07:09:51 »

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.  Grin
Offline Abuse

JGO Coder


Medals: 11


falling into the abyss of reality


« Reply #13 - Posted 2003-02-19 16:39:22 »

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.

Make Elite IV:Dangerous happen! Pledge your backing at KICKSTARTER here! https://dl.dropbox.com/u/54785909/EliteIVsmaller.png
Offline Orangy Tang

JGO Kernel


Medals: 56
Projects: 11


Monkey for a head


« Reply #14 - Posted 2003-02-19 17:33:09 »

Ack, not another one Shocked 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...

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
kul_th_las
Guest
« Reply #15 - Posted 2003-02-20 05:40:43 »

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.
Offline cfmdobbie

Senior Member


Medals: 1


Who, me?


« Reply #16 - Posted 2003-02-20 11:50:24 »

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?

Hellomynameis Charlie Dobbie.
Offline java

Senior Newbie




All games rock!


« Reply #17 - Posted 2003-02-20 13:27:59 »

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.
Offline cfmdobbie

Senior Member


Medals: 1


Who, me?


« Reply #18 - Posted 2003-02-20 16:13:36 »

Hey, only trying to help.  I've been stung by using threads before and I wish someone had told *me* how they really work. Sad

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... Grin

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. Lips Sealed

Hellomynameis Charlie Dobbie.
Offline sharpshooter

Senior Newbie




Java games rock!


« Reply #19 - Posted 2003-02-20 17:13:44 »

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. Smiley
Offline GergisKhan

Junior Member




"C8 H10 N4 O2"


« Reply #20 - Posted 2003-02-21 13:10:41 »

*hides from raising Cas's ire*

AFAIK, from everything said threads are a two edged sword.  YES, they have their purposes and YES they are very good at certain things.  However, when it comes to the main animation thread, when dealing with slower computers and older JVMs, I have personally experienced that more threads = worse performance.

Okay, so this causes a nightmare in arranging your programming, but it's not that bad, really.  Besides, there is no WAY you are having exactly ONE thread in a Java based game with sound, music, networking and such that's going to be maintainable.  You might as well write in C if you're going to do that.  Already I'm at four major threads right now: music, sound, animation, network queue.  I think I'm missing one, I may have to have a separate input queue as well, though I don't see why the animation loop can't handle that.

Choose wisely, but I tend to agree that minimizing the number of threads touching animation is a GOOD thing.

Besides that I have a question: most of the games that have problems with frame-capping are ones that use a single-frame animated object, where the animation is the movement across the screen of said object.  I am thinking Arkanoid,  Frogger, MAYBE Pac-Man, etc.  What about a game that has walk movements, say a figure that walks, and you've only developed eight frames?  I have found that if you up the frame rate past a certain point, you are going to experience problems if you try to move that figure LESS pixels as it causes havoc with the distance the leg travels.  What this means is, if the character was built to stride at 4 pixels per frame, and you try to limit it to move 1 pixel per frame it looks pretty silly.  What then?

(D'oh!  Just realized all my image loaders should be in separate threads, since they all load first and there's no reason not to! D'oh!)

gK

"Go.  Teach them not to mess with us."
          -- Cao Cao, Dynasty Warriors 3
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

pw (24 views)
2014-07-24 01:59:36

Riven (24 views)
2014-07-23 21:16:32

Riven (18 views)
2014-07-23 21:07:15

Riven (21 views)
2014-07-23 20:56:16

ctomni231 (50 views)
2014-07-18 06:55:21

Zero Volt (45 views)
2014-07-17 23:47:54

danieldean (36 views)
2014-07-17 23:41:23

MustardPeter (39 views)
2014-07-16 23:30:00

Cero (54 views)
2014-07-16 00:42:17

Riven (55 views)
2014-07-14 18:02:53
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!