Applet code...

Anyone got a source code for a 4k game as an applet?

I’m wondering what you really need, and how you set up the double buffering. Going to put it in some sort of “getting started” page.

bare-bones 4K applet with double buffering (untested, uncompiled):


import java.applet.*;
import java.awt.*;
public class Game extends Applet implements Runnable {
	Image buffer; // faster than BufferedImage, I've experienced
	public void init() {
		buffer = createImage(getWidth(),getHeight());
		new Thread(this).start();
	}
	public void run() {
		while (true) {
			// game logic here
			paint(getGraphics());
			try {
				Thread.sleep(10);
			}
			catch (InterruptedException e) {}
		}
	}
	public void paint(Graphics g) {
		Graphics gfx = buffer.getGraphics();
		// work your drawing magic here
		g.drawImage(buffer,0,0,null);
	}
}

You’ll really really want to implement and support stop() as well to avoid hanging browsers, which is not very popular.

lack of stop() has never been an issue for me in the past, but if you have the extra bytes, you might as well use it.

however, a cheaper way to avoid any potential hanging would be to replace:


while (true) {

with


while (me.isAlive()) { // where 'me' is your Thread

so, revision:


import java.applet.*;
import java.awt.*;
public class Game extends Applet implements Runnable {
	Image buffer; // faster than BufferedImage, I've experienced
	Thread me;
	public void init() {
		buffer = createImage(getWidth(),getHeight());
		me = new Thread(this);
		me.start();
	}
	public void run() {
		while (me.isAlive()) {
			// game logic here
			if (getGraphics() != null) paint(getGraphics());
			try {
				Thread.sleep(10);
			}
			catch (InterruptedException e) {}
		}
	}
	public void paint(Graphics g) {
		Graphics gfx = buffer.getGraphics();
		// work your drawing magic here
		g.drawImage(buffer,0,0,null);
	}
}

this clocks in at 915b/708b (uncompressed/compressed)

adding a stop() function clocks it to 995b uncompressed, which isn’t bad, but if you’re looking for 90 extra bytes towards the end of your game, this is one area to slash.
this is the stop() function i used:


	public void stop() {
		try {
			me.join(1000);
		}
		catch (InterruptedException e) {}
	}

enable your applet console, and try this applet (which doesn’t have stop()) to see if it works for you: http://woogley.net/misc/Applet4K/ (source). you should notice in the console it will stop printing “still running” after you navigate away from the page, with no ugly exceptions

Thread.currentThread().isAlive() will always return true, so that’s a noop.

I guess this means I know where to shave off another bunch of bytes from t4kns =D

hmm, after testing in the console, it seems you’re right o_O. mystery of life solved. at this rate, does it even need to implement Runnable? can it just run on the Applet’s pre-existing currentThread() I wonder?

edit: nevermind, that was a bad idea. I successfully murdered firefox when trying that :slight_smile:

Yeah, not returning from init()/the contructor is a really bad idea. :wink:

There-in lies the reason Applets never took off :wink:

a short way may be as the following , no ?


public void run()
{
   try
   {
     while(true) 
     {
      gamelogic();
      gamedraw();
      Thread.sleep(10);
    }
   }
   catch(InterruptedException ie)
   {
    //End of game
   }
}

or


public void run()
{
     while(me!=null) 
     {
      gamelogic();
      gamedraw();
    }
}

public void stop()
{
 Thread t=me;
 me=null;
 t.join();
}


public void stop()
{
 me=null;
 me.join();
}

You know I think that might blow up. ;D

Kev

hehe i saw and edit my post but you was faster than me :wink:

I always wondered why everybody was null-ing their Thread-references… it certainly doesn’t make them stop.

Any special applet-context magic? :-[

it remove reference on thread, and exiting the run method kill thread , so no reference and thread not running (run method ended) anymore implied that it is freed.

some infomrmations on applet methods: init/start/stop/destroy

correct me if I said something wrong

start/stop method in an applet doesn’t mean starting en stopping the applet as start and stop method can be called more than once.

init method means: nothing visible yet, applet panel not connected to screen, but you can initialise some stuff.
start method means: start the applet (the first time) or resume from pause(for next call)
stop method means: pause the applet
destroy method means: destroy the applet (the code to free and exit thread should be there)

so
init/destroy methods works together as constructor & destructor of applet
start/stop methods works together as resume/pause applet

usually/normally way is: stop method is called when browser is minimised and start when browser is restored or after applet init for first call

Oh. That sounds likely. And explains a lot. :wink:

stop is also called if you navigate away from the page running the applet.
start is also called after navigation away, then returning to the page.

note: If the browser is not destroyed, the init method will not be called again. This where you can have trouble when testing an applet since the new jar will not be reloaded unless you close your browser or clear the classloader cache in the console.

[quote=“DzzD,post:13,topic:31077”]
Threads are freed after they terminate. You don’t need to worry about having a circular reference. The JVM will automatically detect that both the dead thread and the Applet are ready for garbage collection.

I am just working on a bug I have with Firefox JRE 1.6.0.2… using severals Applets without closing browser, and believe me, unfortunatly Applets are “not freed” on FireFox… releasing all reference in destroy method make the heap grow slower but doesn’t resolve all problemes on FF, IE just works fine…

this is bunch of the code (maybe there is some stupids things in it as it is experimental, I am still working on it) I am working on to make applet released on FF:

public void destroy()
{
		/*	
		Container c=this.getParent();
		Container f=this;
		while(c!=null)
		{
			c.remove(f);
			f=c;
			c=c.getParent();			
		}
		*/
		
		ThreadGroup tg=Thread.currentThread().getThreadGroup();
		while(tg!=null)
		{
			System.out.println(" threadgroug " + tg);
			Thread[] list=new Thread[100];
			int nb=tg.enumerate(list);
			for(int n=0;n<nb;n++)
			{
				System.out.println(" stop thread " + n);
				list[n].stop();
			}
			tg.destroy();
			tg.list();
			
			tg=tg.getParent();
		}
}

Using the above code I am able to open 5/6 times more applets, but there is still sometime an OutOfMemory exception that happen…