Applet templates

I didn’t use this on either of my entries because I didn’t realize that it’s smaller than the method I was using until too late, but here’s a template that maintains a relatively steady frame rate and goes easier on your CPU.

import java.applet.Applet;
import java.awt.Event;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;

public class G extends Applet implements Runnable {

	public void start() {
		new Thread(this).start();
	}

	public void run() {
		setSize(800, 600); // For AppletViewer, remove later.

		// Set up the graphics stuff, double-buffering.
		BufferedImage screen = new BufferedImage(800, 600, BufferedImage.TYPE_INT_RGB);
		Graphics g = screen.getGraphics();
		Graphics appletGraphics = getGraphics();

		// Game loop.
		while (true) {
			long lastTime = System.nanoTime();

			// Update
			// TODO add some update logic here.

			// Render
			g.setColor(Color.black);
			g.fillRect(0, 0, 800, 600);
			g.setColor(Color.white);
			g.drawString("FPS " + String.valueOf(fps), 20, 30);

			// Draw the entire results on the screen.
			appletGraphics.drawImage(screen, 0, 0, null);

			//Lock the frame rate
			long delta = System.nanoTime() - lastTime;
			if(delta < 20000000L)
			{
				try
				{
					Thread.sleep((20000000L - delta) / 1000000L);
				}
				catch(Exception e)
				{
					//It's an interrupted exception, and nobody cares
				}
			}

			if (!isActive()) {
				return;
			}
		}
	}

        public boolean handleEvent(Event e) {
            switch (e.id) {
                  case Event.KEY_PRESS:
                  case Event.KEY_ACTION:
                      // key pressed
                      break;
                  case Event.KEY_RELEASE:
                      // key released
                      break;
                  case Event.MOUSE_DOWN:
                      // mouse button pressed
                      break;
                  case Event.MOUSE_UP:
                      // mouse button released
                      break;
                  case Event.MOUSE_MOVE:
                      break;
                  case Event.MOUSE_DRAG:
                      break;
             }
             return false;
	}
}

Replace the 20000000L with your desired frame delay.

Any reason to use the deprecated public boolean handleEvent(Event e) function instead of protected void processEvent(AWTEvent e)?

It’s smaller, and not removed yet.

And is there a reason to run it in its own thread?

I.e what’s the difference between:

public void start() {
	new Thread(this).start();
}

and:

public void start() {
	run();
}

If you tried that, you’d find it wouldn’t work. For a reason called the Java Event Dispatching Thread (EDT). The loop in the run method would block any user input, drawing, etc, that the EDT needs to do.

Does anyone have a good method for passing mouse input to the main function?

For key input there’s the giant array of booleans that we al know and love, but passing mouse events over is hard.

What I’ve been doing is maintaining a LinkedList of Events and using it as a queue. HandleEvent adds them, your input loop does while(!events.isEmpty()) {Event e = events.removeFirst(); [Input Code]}

That requires you to wrap your entire event handler in an exception handler though, or you’ll get concurrent modification issues that don’t make any sense. On the bright side, wrapping something in an exception handler is free if you’re doing anything else that requires exception handling, such as the Thread.sleep() in my version of the template.

But requiring a LinkedList is kinda crappy. You could also do it with an array and an index, which might be smaller, but I haven’t checked.

I detect mouse presses and releases and write them into an boolean array (dimension needs to be 5 iirc). I also read the current mouse position and store that in mouseX and mouseY. Bear in mind that other mouse events may update mouseX & mouseY. Thus it works very much like the keyboard boolean array. To action a mouse click, the main loop does something like:


if (mouse[1]) { // 1 is left button
mouse[1] = false; // leave out if you want to do this repeatedly while the mouse button is down
// do something with mouseX and mouseY
// the assumption is the main loop runs faster than the user can click the mouse buttons
}

Mouse drag events are not supported, but could be faked in the main game loop by maintaining a second array of mouse button states and copying current state into last state on every loop.

Incidentally I only have one event handler which does both keyboard and mouse.

Cheat and use the keyboard array. There are plenty of unused codes, especially if you size your array using a larger int which is already in the constant pool (although IIRC I use 0-3).

For the current versions of Mac Java, the run() method needs to include a wait at the beginning to ensure that the applet is ready before running:
public void run() { while (! isActive()) { // Wait technique, such as Thread.yield() or Thread.sleep() } // rest of the code }

[quote]For the current versions of Mac Java, the run() method needs to include a wait at the beginning to ensure that the applet is ready before running:

public void run() {
while (! isActive()) {
// Wait technique, such as Thread.yield() or Thread.sleep()
}
// rest of the code
}
[/quote]
Which method calls fail if we do not do this?

I don’t know about what failure your code is encountering, but I’m guessing it’s a NullPointerException when trying to access the applet Graphics. For me, it looked like my code was stopping when it encountered the applet not being ready, so nothing was rendered other than the default update() routine.

hey, I know this is an old thread, but it might be a good idea to copy the agreed upon best template to the OP for ease of access.

I agree with that. There were lots of discussions of what is the best template and I couldn’t realise which was the final product.

Also, we have several 4k resources spread in different sites, like programming tips, compressor tools, it’d be great if we have everything in the same place. I’d suggest to have everything in java4k.com site. Not sure if it’d be too much work to set a wiki section where we could contribute with documentation.

We could have sections like: Templates (both applets and app (last competitions)), Programming tips, Compressor, Tutorial (could add stuff from http://www.ahristov.com/tutorial/java4k-tips/Visual-effects-index.html), Games (this one we already have) - also in this section we can have a link of the source code of the games whose authors allowed it to be published)

Any other thoughts?

I think it would be good to have a template shoot-out - not just putting up code, but putting up a basic applet using them too - so that we can get a handle on which templates work for OS X, and on other possible issues.

Mine is at http://www.cheddarmonk.org/java4k/skeleton/
It seems to have an inconsistent bug with IcedTea / Firefox / Linux, but there doesn’t seem to be a way to get a console and see whether there’s a stack trace. Grr.

Very good point. I think the templates on this page aren’t even Mac OS X - compatible, so 90% of the games are unplayable. It would be good to get these tested and figure out what actually works for everyone.