Links, tips and goodies

Good site on 4K game design:
http://wiki.java.net/bin/view/Games/4KGamesDesign

Kevglass’s site containing 4K games + SOURCE:
http://games.cokeandcode.com/index.php?page=source

moogie’s tool:

[quote]I have made a tool in previous competitions to output the smallest jar from different obsfucators and zip programs.

see http://www.java-gaming.org/index.php/topic,18085.0.html

description and command line options here http://www.java-gaming.org/index.php/topic,15497.0.html
[/quote]

I don’t know if it’s of any use, but here’s the template I use for my 4k games:
Template4k

The strategy for handling events was originally taken from the Miners4k source that Markus_Persson was kind enough to provide, and the timing code was provided by oNyx a few contests ago.

EDIT: Oops, made a mistake. Reuploading shortly.
EDIT2: Fixed. I made a few changes to my original template, but I think it’ll be fine.

Nice template. However you’ll save a bunch of bytes if you just use the nano timer instead of the rolling average implementation. I think oNyx used the rolling average because Java 1.5 was not allowed at that time.

I’m not sure I understand what you mean. Using nanoTime would give me more exact time, but if one removed the rolling average, the framerate would be more jumpy in either case. The advantage to having a sleep that varies in length, of course, that it’ll stay around your desired FPS (in the case of the template, 62), while giving your calculations some freedom (they might not take the same amount of time each frame). Calculating the sleep time based on an average over the last few frames smooths it out.

I believe the rolling average was made to hide the inacuracy of currentTimeMillis. You don’t have to do that with nanoTime. As long as you’ve got cycles to spare you can cap the framerate perfectly. Here is the code to cap the framerate to 60 fps:


		    // wait 16 milliseconds to cap frame rate to 60 fps
	    	while (System.nanoTime() < lastFrame + 16000000) {
	    		Thread.yield();
	    	}
	    	lastFrame = System.nanoTime();


Edit: I saved 49 bytes when I rewrote Pinball4K from rolling averate to nanoTime

Changing it to a “do{…}while” should save you 2 or 3 more bytes, as it gets rid of the unconditional branch instruction (goto) at the end of the while :wink:

And the behavioural side-effect might even be considered beneficial!

Alright - so let me know if you’ll be aiming for 1.4.2 or 1.5. If there’s a clear majority for 1.5, I’ll change it :slight_smile:

Ye, the old timing code is pure voodoo. It even works reasonable well with a timer resolution of 250msec if the time per frame is pretty consistent (~changes slowly).

I think oNyx used the rolling average because Java 1.5 was not allowed at that time.

I invented it because nanoTime didn’t work on my old machine anymore after I installed an ATI graphics card. It caused a different bus load than the Nvidia card which in turn triggered QPC leaping. I really wish there were some 1msec timer (TGT) in Java. LWJGL for example uses TGT on Windows and currentMillis elsewhere (=1msec - except for Windows, of course).

With 1.5+ I’d use (now that I got a better machine haha) a simple min-cap loop such as the one tom posted. Just with sleep instead of yield. The RADYTT (rolling average damped yield throttling thingy ;D) only uses yield, because there can be so many of them. If 1% of them take 100 times longer than usual you won’t notice it, because it would be averaged out in that gigantic pile of yield calls.

Sleep, however, is a different thing. There are only a few calls. If one takes a tad too long you gotta quit the loop right away, but with imprecise timing you wouldn’t know and there is a fixed amount of iterations. So, that wasn’t an option.

Would be great if sleeps for longer durations than 0 or 1 msec would be as accurate as calling 0 or 1 msec sleeps in a loop, but even that isn’t the case. Otherwise sleeping the full amount in one go would have been a good solution.

edit: What’s really bad about RADYTT is that the over-/under-steering effects get pretty big if two instances of it are running at the same time (e.g. having 2 games running which use this timing method).

The source for my games is also online, here:

http://ulf.ofahrt.de/4kgames/

I just updated the template some as suggested by oNyx on irc; it no longer reuses the graphics object, as that’s supposedly troublesome on certain macs. Thanks oNyx :slight_smile:

The source code for my last two submissions are located:

SupPar (space shooter)
Rally4k (rally racing game)

Here is my page a bit outdated (doesn’t include my j4k2007 entries) for the 4k games from years past…

Juegos en 4K

The Webstart links may not work, the jar and source links are working.

For the non spanish:
Baja el juego -> Download the game
Baja el source -> Download the source.

Here’s an optimized processEvent:

    public void processEvent(AWTEvent e)
    {
        boolean down = false;
        switch (e.getID())
        {
            case KeyEvent.KEY_PRESSED:
                down = true;
            case KeyEvent.KEY_RELEASED:
                k[((KeyEvent) e).getKeyCode()] = down;
                break;
            case MouseEvent.MOUSE_PRESSED:
                down = true;
            case MouseEvent.MOUSE_RELEASED:
                k[((MouseEvent) e).getButton()] = down;
            case MouseEvent.MOUSE_MOVED:
            case MouseEvent.MOUSE_DRAGGED:
                x = ((MouseEvent) e).getX();
                y = ((MouseEvent) e).getY();
        }
    }

Mouse buttons states are in low k[]-values, keys in higher. This has some side effects, but it shouldn’t be too bad (some obscure keys might act as mouse buttons).

If you have an image of, let’s say a top down view of a car, then you can split that image in HALF, saving 50% of the bytes!

You simply cut it from the top-center and down through the bottom-center, throw away either half. Then you load up your half image and then you can recreate the full image by mirroring the half you kept!

http://www.java4k.com/temp/mirroring.png

What’s the best algorithm/object to use for loading images/mirroring them? BufferedImage? ImageIcon? drawImage? Change the Graphics2D transform? Also, what about image rotations?

It would be nice if you could show a little tiny code snippet.

These are sort of combo 4k questions and Java2D questions, I know, but I haven’t had much success with Java2D’s speed so I usually use LWJGL.

I think the smallest way would be to draw the image twice (with appropriately modified parameters) using:


public abstract boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer)

Storing the image + flip would require accessing many different api calls, which will bloat up the constants pool with lots of class & method signatures - something you should always be aware of when trying to keep code size to a minimum.

Yeah, I should have said smallest, not best.

So like:


g.drawImage(img,x,y,x+width,y+height,x+width,y,x,y+height,null);

Basically is it width/height based or coordinate based?

Coordinate,
so what you have above will draw the image in the same location as g.drawImage(img, x, y, null), but flipped.

There are several ways to make an applet run.
How does your Applet look like? Which methods have you written?
I never used the destroy method, but Applet needs more overhead than Frame, but maybe I am wrong?

I have overridden the init, destroy, processKeyEvent, and paint, methods. I have also implemented the run method from the Runnable interface. The init method starts my game loop thread. The destroy method sets a boolean flag to tell the run method to stop. It is a lot of overhead, and I am hoping there is a more efficient way?

I think you are correct. With a Frame you can have everything in the constructor, and update your screen like this:


this.createBufferStrategy(2);
BufferStrategy bufStrat = this.getBufferStrategy();
do {
    ... do stuff ...
    bufStrat.show();
} while (isVisible());

In an Applet, the createBufferStrategy and getBufferStrategy are not accessible. :’( I’m hoping there is an alternative. Anyone know of one? ???