Preliminaries (tentative)

Yeah, OK.

Initially i was a little apprehensive about forcing applets as i did not want to run foul of applet security due to the fact that i embed binary data as an attribute in the class file of my game. I have just done a test and it seems to be fine so i am happy enough.

Could someone else see whether my test applet loads? Test

(this test applet is derived from an early version of my 2007 comp entry)

Moogie, it works for me. (Linux, Sun Java 1.6.0_14).

Some very good news here !

Concerning Webstart, I experimented a lot of problems with it - for example I was unable to launch my own 2009 entry on my computer through it… So I don’t mind if we must submit applets for the next contest.

And to answer you about your test applet, moogie, it works rather fine on my computer… However all is not perfect, because your game starts sometimes with some lag. But it stops if I move the ship at least a few seconds. My computer runs under Vista 32 bits SP 2, with Java 6 Update 16.

Message update
Moogie, actually the lag on your test applet disappears once the game screen is activated, I mean once one has clicked on it… So I suppose you don’t have to worry about it !

thanks both for testing. I am much more confident and happy about being forced to use an applet. /me grumbles about not being able to use bufferstrategy cheaply (in bytes).

It’s been quite a few years since i last entered 4k so am rather rusty. However I have an idea, and lots of spare leave in December, due to it being a hectic year at work. There’s always a silver lining.

Back in the dim mists of time, webstart with JFrame and everything in the constructor was pretty much the smallest template. Using an applet means we have start(), stop() and init() and I usually create a new thread to run my game in. Rather more bloat than I want for 4k! Can I stuff the entire game loop in init() and not return until game over? Any good examples of minimal applet code I should look at?

I notice people are saying applets are now better than webstart. Obviously there’s been a change of heart over the last few years. Is this an issue with webstart user experience (nasty warning dialog boxes) or is there a programming related improvement on applets?

Incidentally, looking at previous posts, I’ve always had trouble with window sizing when writing 4k games using just a JFrame, due to decoration sizes. Also pack() and setsize() and windows visibility don’t always play nice.

Alan

Edit: I’m considering something like…


public class Applet4k extends Applet implements Runnable {
	public void init() { (new Thread(this)).start(); }
	public void run() { 
		// Game initialisation
		while(isActive()) {
			Graphics g = getGraphics();
			// Game Loop
			g.dispose(); // Tidy up - probably
		}
	}
}

Any good? - Not sure whether isActive() will be set in time, as JavaDoc says it is set just before start()

IMO applets probably end up to be overall smaller than using a JFrame, since you don’t have to have a main(String[] args) method or setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE), you only extend the methods that are needed. There probably is a way to just use one method for an applet game loop instead of two as in your example.

Applets have been hated for years due to the horrid user experience, but the recent changes (java 1.6.0_10+) have made them pretty nice, almost flash like due to fast startup and the tons of bug fixes (especially the browser locking and crashing ones). IMO they are now better than JWS due to being able to provide jvm parameters and run in a separate jvm without the unfamiliar external windows. Also imagine playing a 100 jws games, thats a 100 extra entries in your add/remove programs list :). Plus applets IMO make the competition more accessible to players.

[quote=“Alan_W,post:26,topic:34414”]
My applets have always ended up smaller than my stand-alone 4k games. You get a free component to paint on just by inheriting from Applet, no need to create it or set up any size or even make it visible.
You can check the source code for Left 4k Dead if you wish: http://www.mojang.com/notch/j4k/l4kd/G.java

I wouldn’t recommend running much logic in start() or init() as those are supposed to return as fast as possible, so you pretty much HAVE to create a Thread. I do this in start() instead of init() to be able to rely on isActive(). This means that the game could in theory stop and restart when someone opens another tab in some obscure browser or something, but in reality I’ve never seen it. (and it’s not a HUGE problem anyway imo, people tend to stay on the game page)

Thanks for sharing all the useful info Markus!

I think this was part of the problem I and some other applet users had last year. With the latest Java release available at the start of the competition you could get away with just having a loop in init(), but the version released near the end of the competition seemed to require init() to finish before doing something important (at a guess, creating the native peer).

@Kapta; Markus,

Thanks for your help, and clarification on why applets have become more popular. I’ll use start() rather than init() in my template and start coding from there. :slight_smile:

Alan

Maybe we should offer some template code so that participants can get easily started with applets. I’m guessing some will have difficulties getting started with Applets, and I surely would like everyones Applets to work well in browsers.

On the todo list :slight_smile:

I don’t think you need to implement any of the Applet signalling methods start(), init(), stop() or destroy().

Spawn the Thread in the constructor.
As you always have a constructor (even if none is declared), you might as well make use of the method signature being in the constants pool.
Then, just use isActive() to control the behaviour of the Thread.

Something like this :-


import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;

public class H extends Applet implements Runnable {

	public H() {
		new Thread(this).start();
	}
	
	public void run() {
		boolean started = false; //this latch prevents the Thread immediately terminating (as isActive() will return false for the period between the constructor call & start() call)
		do {
			if(isActive()) {
				started = true;
				
				Graphics g = getGraphics();
				g.setColor(new Color((int)(Math.random()*0xFFFFFF)));
				g.fillRect(0, 0, getWidth(), getHeight());
				
			}
			else {
				if(started) {
					return;
				}
			}
			
		}
		while(true);
	}
}

The only way I can think of improving upon this would be to eliminate the spawning of the Thread (along with Runnable interface and run() method).

Instead, you use the EDT to perform your animation loop by calling repaint() at the end of your overridden paint(Graphics) method.

It might work… though you’d have to work out a way of throttling the frame time without halting the EDT for too long.
And you might run into problems with outside events interrupting the repaint cycle…
Big downside though is that you have to store all of your state in member variables rather than locals.

Ingenious , although I suspect that if you navigate away from the page and then back again, you might get a blank page, as the ‘run’ thread will have terminated, but the applet may still be loaded. Of course one could just leave the thread running, but I guessing it might not stop until the browser was shut down.

Alan

you could also just use the seperate_jvm parameter so (at least on the new applet plugin) every time you visit the applet it’ll be in a different vm.

You’d have to mark the whole applet as dirty as well, wouldn’t you?

I wouldn’t recommend this, since the applet would only be able to run once.

Ah. hadn’t considered that; I only tested it in the Applet viewer.

Well… leaving the Thread running isn’t that nasty =) (and infact, makes the code even smaller!)

:edit:

Or, instead of spawning the Thread in the constructor, spawn it from the EDT when the first Event is received.
It can then safely be discarded when isActive() begins returning false, and re-animated if the Applet starts receiving Events again.

You, sir, are a genius.