Techniques used to get maze4k into 4k

The most important fact to remember is that
not every optimization works for all programs.
It depends on the other techniques used in the
game that benefit from using a technique.
For instance the fact that this game uses a tool
to convert images into procedural graphics meant
that the use of other optimization with Color
statement would not work.


Here are some techniques that worked in Maze4K:

Data Compression
The greatest byte-saver was to convert the data
to Strings and let the compression utilities take
care of the optimization.
I tried different approaches with different data
and even to store two data bits into one byte.
But all the extra coding and loss of duplication of
the data didn't work well with the compression utilities
and in the end the long String could be compressed best.


Avoid methods and use one class

public class a extends Applet implements Runnable

This is eventually used, but you can avoid Runnable
and the accompanied Thread by using an init and
System.currentTimeMillis() in a while loop...
If you do not use a Thread the game isn't running
that smooth and it gaves odd behaviour when you try
to quit.

class a
start
run
handleEvent

Avoid public data

In the end there where only 3 globals:
int x;
int y;
int maction; (mouse action)

The handleEvent stores the x,y coordinates and the mouse
action gets stored.
In the run method there is a test on what kind of
action (click or move) is done.

Check what you can make final!
public final void run(){
final int bla=3;
}

Procedural graphics

SpriteSheet:
A tool was made to convert an image into fillRect
pixels. You can make the rect as big as you want.
The bigger the Rect the greater the pixel-effect.

Expermimentation was done regarding pixel versus color.
The compression used by kzip and others work better
with repetition of data. The more colors you introduce
the weaker the compression was, but ... if you use
more colors you can make small sprites look better by
gradually move one color to another one (light to dark)

In the end the spritesheet was 48x48 resulting in a 12x12
sprite with 30 colors. In the game the 12x12 sprite was
enlarged into 24x24 pixels.

Level data

A tool was made to create the levels and to store
the levels into one large String that could be compressed
best.
String map="AABBAA";
is better compressed than any char, byte series.
Some characters are better compressed than others.
For instance the '#' character was replaced by ' ' (space)
and the result was a binary that was 16 bytes less.

So:
String map="level1data.level2data.level3data";
and
use a level indicator : ((level-1)*256)
grid[i]=map.charAt(i+((level-1)*256));

It was better to convert the string into
seperate grid items than to use substring and
charat to travers to the data. The int array
was easier to program with and resulted in smaller
binary data than to use pure string operations.


Avoid many different method calls

The spritesheet-conversion tool used Color a=new Color(int-value);
and g.setColor(new Color(a));
so optimization could be done to convert all other Color
techniques into the same statement.
final int PLAYER1COLOR=-16711681; // cyan!
g.setColor(new Color(PLAYER1COLOR));
instead of
g.setColor(Color.cyan);

Initially the game used a circle-cursor and by changing the
g.fillOval call into fillRect it saved some more bytes.

As well as omitting drawRect for fillRect . Gives different
behaviour but compresses better...

Avoid if

Changed this:

if(i!=15)object[i].getGraphics().drawImage(SpriteSheet, -((15%4)*TILESIZE), -((15/4)*TILESIZE),null);
object[i].getGraphics().drawImage(SpriteSheet,-((i%4)*TILESIZE), -((i>0?i/4:0)*TILESIZE),null);

into :

object[i].getGraphics().drawImage(SpriteSheet, -((15%4)*TILESIZE), -((15/4)*TILESIZE),null);
object[i].getGraphics().drawImage(SpriteSheet,-((i%4)*TILESIZE), -((i>0?i/4:0)*TILESIZE),null);


Avoid else

Changed this:

if(action == DRAW)sleeptime=1;else sleeptime=160;

into:

sleeptime=1;
if(action != DRAW) sleeptime=160;


Change ifs into switches
Wherever possible!


Proguard

Takes care of optimization with names. So you
can still use a lot of meaningfull names and use of
constants to make the code a BIT better to maintain.

But this is done as well by:
http://www.indiespot.net/app/java-four-kay

AMAZING

Tool that uses different compression utilities
together with pack200.