Since many people still ask for how to do a small game loop I thought I would start a thread to compare how different people are doing there game loop.Here is the source for minimal game loop. If any one has a better method feel free to post improvments.

I'm curious as to what you mean by this? the Runnable interface does not define any such method.

Also, depending on your definition of exactly what your stop() method should do - your implementation maybe incorrect.If you want your game thread to be terminated before stop() returns, you should do something like :-

ofcourse, the lack of synchronization also mandates that there is no way of restarting the game thread. (otherwise you are again introducing the potencial for bugs)However, this is all irrelevant as there is no need for storing the game Thread as a member variable - it is unnecessarily bloating.

The only function of member variables in an optimal 4K app. is for communication between the event dispatch thread, and the game thread.As such, you should need only *one* member variable.This will typically be either an int[], or a boolean[] - depending on preference, and exactly what you are doing with your user input.

No problem I guess I did not specify the problem very clearly. I will restate the challenge.

Produce smallest compiled game loop that does the following.display window or frame.handles key board eventsdoes a double buffered clear of the screenexits cleanly on either window close or escape or both.

If you do post an alternative please show the compiled class size and compressed jar size as in my example.

Sorry your loop is larger you removed one method but then had to create an instance and dereference it to make the calls. You came out 40 bytes larger before jaring.

I do not understand the comment about recycling the graphics object. I get a reference to an object and use it as long as I wish. There should be no need to recreate one every time. There also should be no need to dispose of it as when I am done with it the program exits.

I do not understand the comment about recycling the graphics object. I get a reference to an object and use it as long as I wish. There should be no need to recreate one every time. There also should be no need to dispose of it as when I am done with it the program exits.

* jbanes slaps Rick on the wrist for being naughty

Every time the buffer is flipped, the graphics context changes. The only reason I can think of why it works at all is that you're in double buffered mode instead of page flipping mode. Since you're always writing to the secondary buffer, you're getting away with not changing your Graphics object instance. Unfortunately, if ANYTHING changes, your code will blow up with a very exciting and disasterous [size=14pt]BOOM![/size]

Since you're not forcing the BufferStrategy into any particular mode, this change could happen just because someone else's PC is different. Or the user might minimize and restore the window, and the OS decides to release and recreate its graphics context. Or the OS could decide to provide a mapped area of page flipping memory that it's using (apparently Mac OS X is now VSynced) causing the context to change every frame.

In short: What you're doing is BAD. It's almost guaranteed to cause problems, even if it works on your machine. All you need to do to fix it is to move the "g = (Graphics2D)b.getDrawGraphics();" into the loop. It shouldn't cause any new overhead in the file size, and your code will be much more compatible and portable.

Thanks for the lesson on graphics object I will change that. oNyx is also correct about the use of Color It save 22 bytes if a new is done in the loop and 15 is a color variable is created outside the loop. Markus loop was larger both before and after jaring. I have edited the original post to reflect the comments received.

setSize(640,480);setResizable(false);show(); // depricated but less bytes than setVisible(true);createBufferStrategy(2);BufferStrategyb = getBufferStrategy();Graphics2Dg;

do {g=(Graphics2D)b.getDrawGraphics();g.setColor(newColor(0x000000));g.fillRect(0,0,640,480);// do game here

b.show();try {longtimeNow = System.currentTimeMillis();//rolling average for the last 10 time inputsframeAverage = (frameAverage * 10 + (timeNow - lastFrame)) / 11;lastFrame=timeNow;//16f = for 16msec//0.1f = damping value//and that +0.05f bit is for ensuring that it can grow faster after it ran flat out for a whileyield+=yield*((16f/frameAverage)-1)*0.1f+0.05f;

So will be this code correct and small enough or it's better to change the way Markus_Persson said ? I wonder if the 'extras' "m." could penalize what's gained from keeping all in the main method.

The extra m. references do cost more.

I did not include the code to do the fixed frame rate as I thought the resolution of the timer is too low. That is it is normally only good to 10 to 20 millsec. I just wait 10 millsec so that on fast machines the game does not go to fast. On slow machines sure it would be good to take into account how long it took in the loop and only wait 10 - time taken. But can we actually measure the time taken to less than 10 millisec accuracy? I guess by using the rolling average as suggested we can get a better idea of the time taken but I think the extra bytes are not worth it. Slow machines will just run a little slow.

I don't think it makes a blind bit of difference whether your game code is in the constructor, or in main(...).

The default constructor exists whether or not you define it, so there is no saving by moving stuff to your main.Equally, referencing methods declared in the class is no more expensive with either approach."this.methodName()" evaluates to exactly the same bytecode as "m.methodName()"(push a local variable containing the JFrame's objectReference onto the stack, push any method parameters onto the stack, and then the invoke instruction)

The only difference I can think of, is when placing your game code in the JFrames constructor, you get a reference to 'this' stored in local variable 0 'for free'.Now, if this is where you want 'this' to be located, then all is well - and you have saved yourself 1 byte.However, typically you will want 'this' to be stored in a high index local variable, as you rarely make sufficient references to it for it to be worth-while occupying one of the quick access local variables.Therefor, you end up inserting 3 extra bytecodes to push it back onto the stack, and pop it into a high order local variable.This reverses your benefit, making main() the best place to put your game code!

To summarize, in some very limited circumstances putting your game code in the constructor will save you *one* byte, but generally it is best to place it in main.

It realy is irrelevant though, the alteration to the compressability of your code, by re-ordering your bytecode will make a far bigger difference.Hence, any bytecode optimisation that saves you less than 50 bytes is generally not worth even thinking about.

No, it runs *very* slow and thats despise the fact that the machine is good enough to run the game just fine.

Say you sleep for 20msec and it takes only 1msec to draw everything... so you end up with 21msec per frame, which results in ~48 fps. And now imagine there is some machine which needs 20msec per frame - it could run it at the same speed, but instead you end up with 40msec per frame, which means the framerate is halved for no reason.

This rolling average adaptive yield thingy works pretty well, if the time per frame doesnt fluctuate too much. In fuzetsu the difference between maximum and minimum is pretty huge (from zero bullets to 1500 bullets + 300 particles), but the changes from one frame to the next are pretty small (dont be misleaded by the speedup after killing... thats intentionally for clearing the screen quickly).

It works pretty well. Even if you cripple the resolution of the timer to the win9x level (50-55msec). Thanks to averaging of the last 10 frames we get a pretty good idea how much time we spend per frame... well, on average that is. So, you get some delay on adjustments and it will over/understeer if the difference from the current yield count to the desired yield count is... how should I put it... extreme. Like if you have a very slow machine and start with a gigantic yield count of 50k it will be too slow for a second, then too fast for another second and finally it will run at the right speed with say 400 yields. Since the adjusting is proportional (with damping) it draws near a good value quickly.

I used linear (+/-1) adjusting before without any damping. That worked sorta alright and the adjusting on slow machines was also pretty quick (since the yield values were pretty small), but it wasnt that smooth and it didnt cope that well with game-typical time-per-frame-changes.

You can also use delta timing, but that effectively means ~20 (different) fps on win9x and it makes everything unnecessarily complicated.

Using the Main method is smaller if you need to throw an exception. If you use the constructor, you have two separate methods throwing the exception. (Or one method throwing the exception, and the other one trapping it.) With just the main method you only have one method throwing the exception.

Good point I tried it out and here are the results. Note the code in constructor is still smaller by the same 13 bytes. But while the throw is larger than the catch uncompressed the throw saves an additional 10 bytes once compressed over the try catch.

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