Help! I R n00b

2,255 bytes. That’s how big my 4K entry is so far and all it does is open a double buffered window and listen for mouse and keyboard input.

How the hell do you guys get so much into 4K???

Cas :slight_smile:


import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;

/**
 * 4k entry
 */

/**
 * @author foo
 */
public class G implements MouseMotionListener, MouseListener, KeyListener, WindowListener{

	static Frame w;
	static G g;
	static BufferStrategy s;

	public static void main(String[] a) {

		g = new G();
		
		// Create our frame
		w = new Frame("4k");
		w.addWindowListener(g);
		w.addKeyListener(g);
		w.addMouseListener(g);
		w.addMouseMotionListener(g);

		Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
		w.setBounds((d.width - 320) / 2, (d.height - 320) / 2, 320, 320);
		w.setCursor(Toolkit.getDefaultToolkit().createCustomCursor(new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB), new Point(0, 0), ""));

		// Show our window
		w.setVisible(true);

		// Create a general double-buffering strategy
		w.createBufferStrategy(2);
		s = w.getBufferStrategy();

		// Main loop
		for (;;) {
			long t = System.nanoTime();

			// Render single frame
			do {
				do {
					// Get a new graphics context every time through the loop
					// to make sure the strategy is validated
					Graphics g = s.getDrawGraphics();

					// Draw background
					g.setColor(Color.black);
					g.fillRect(0, 0, 320, 320);

					// Dispose the graphics
					g.dispose();

					// Repeat the rendering if the drawing buffer contents
					// were restored
				} while (s.contentsRestored());

				// Display the buffer
				s.show();

				// Repeat the rendering if the drawing buffer was lost
			} while (s.contentsLost());

			// Sync to frame rate, always sleep at least 1ms
			long n = t + 1;
			while (n > t && (n - t) < 2000000) {
				try {
					Thread.sleep(1);
				} catch (InterruptedException e) {
				}
				n = System.nanoTime();
			}
		}
	}

	public void mouseDragged(MouseEvent e) {
	}

	public void mouseMoved(MouseEvent e) {
		mouseDragged(e);
	}

	public void mouseClicked(MouseEvent e) {
	}

	public void mousePressed(MouseEvent e) {
	}

	public void mouseReleased(MouseEvent e) {
	}

	public void mouseEntered(MouseEvent e) {
	}

	public void mouseExited(MouseEvent e) {
	}

	public void keyTyped(KeyEvent e) {
	}

	public void keyPressed(KeyEvent e) {
	}

	public void keyReleased(KeyEvent e) {
	}

	public void windowOpened(WindowEvent e) {
	}

	public void windowClosing(WindowEvent e) {
		System.exit(0);
	}

	public void windowClosed(WindowEvent e) {
	}

	public void windowIconified(WindowEvent e) {
	}

	public void windowDeiconified(WindowEvent e) {
	}

	public void windowActivated(WindowEvent e) {
	}

	public void windowDeactivated(WindowEvent e) {
	}

}


Is that in a compressed JAR? My final class sizes are around 10-11k. Then you jar it up. Then run it through Proguard. This will shrink to the final 4k size.

Also, did you check out the WiKi: http://wiki.java.net/bin/view/Games/4KGamesDesign

One thing I can point out right away. Don’t use WindowListener to exit. Use setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); instead. Every method you create puts a method signature in the class file. With WindowListener, that is 7 signatures. The other way has none, just a call.

Class level variables take more space than instance variables.

This should be smaller.

I learn fast :wink:
1,853 bytes to achieve the same results:


import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.WindowConstants;

/**
 * 4k entry
 */

/**
 * @author foo
 */
@SuppressWarnings("serial")
public class G extends JFrame {

	BufferStrategy s;
	
	public static void main(String[] a) {
		new G();
	}
	
	G() {
		super("4k");

		Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
		setBounds((d.width - 320) / 2, (d.height - 320) / 2, 320, 320);
		setCursor(Toolkit.getDefaultToolkit().createCustomCursor(new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB), new Point(0, 0), ""));

		// Show our window
		setVisible(true);

		// Create a general double-buffering strategy
		createBufferStrategy(2);
		s = getBufferStrategy();
		
		// Enable window, mouse, and keyboard events
		enableEvents
			(
					AWTEvent.MOUSE_EVENT_MASK
				|	AWTEvent.MOUSE_MOTION_EVENT_MASK
				|	AWTEvent.KEY_EVENT_MASK
			);
		
		setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		run();
	}
	
	void run() {
		// Main loop
		for (;;) {
			long t = System.nanoTime();
			
			logic();

			// Render single frame
			do {
				// The following loop ensures that the contents of the drawing
				// buffer
				// are consistent in case the underlying surface was recreated
				do {
					render();
				} while (s.contentsRestored());

				// Display the buffer
				s.show();

				// Repeat the rendering if the drawing buffer was lost
			} while (s.contentsLost());

			// Sync to frame rate, always sleep at least 1ms
			long n = t + 1;
			while (n > t && (n - t) < 2000000) {
				try {
					Thread.sleep(1);
				} catch (InterruptedException e) {
				}
				n = System.nanoTime();
			}
		}
	}

	synchronized void logic() {
	}
	
	void render() {
		// Get a new graphics context every time through the loop
		// to make sure the strategy is validated
		Graphics g = s.getDrawGraphics();

		// Draw background
		g.setColor(Color.black);
		g.fillRect(0, 0, 320, 320);

		// Game rendering here...
		
		// Dispose the graphics
		g.dispose();
	}
	
	@Override
	protected synchronized void processKeyEvent(KeyEvent e) {
	}
	
	@Override
	protected synchronized void processMouseEvent(MouseEvent e) {
	}
	
	@Override
	protected synchronized void processMouseMotionEvent(MouseEvent e) {
	}
	
}

Cas :slight_smile:

Think that’s a decent enough framework for a whole smorgasbord of silly little games. I wonder what I’ll come up with with those lovely 2,200 remaining bytes.

Has anybody any knowledge about sound effects? I’d quite like to do some sounds - notably missing from 4K entries by and large - you know, just simple saws and pulse waves through waveout.

Cas :slight_smile:

You can do all 3 types of events with processEvents… just check the type of the event and do the matching actions.

You can also do everything in the c’tor. That leaves you with: c’tor, main (which calls the c’tor) and processEvents.

You also might want to try different obfuscators (jarg, proguard, joga etc), zippers (7zip, kzip, bjwflate) and if you have more than one file you also should try zipmix (can be also found at the pngout page).

For fuzetsu I used: jarg->joga… once wtih kzip… once with bjwflate -> zipmix.

What oNyx said, and compile with -g:none.

Further, you might change your mind about spending so many bytes only to remove the mouse-pointer!

compile with -g:none

Don’t obfuscators strip all that already?

Further, you might change your mind about spending so many bytes only to remove the mouse-pointer!

Thanks to Java2D’s PLATFORM SPECIFIC way to create images… it needs to be cleared. Otherwise its either filled with opaque gray (Mac) or random bullcrap (Linux).

Also… on Mac you may lose your custom cursor. Whenever you regain focus you have to reset the cursor to the desired one. Gah! (Hadn’t enough room for that rather massive fix.)

I still think that it was really bad that they decided against having a pre defined empty cursor.

So, my (obvious) advice: If your game is fine with the cursor, keep it.

you can also save bytes by just calling setLocation(10,10) rather than centering the window…

also calling show() instead of setVisible(true) will save a few bytes as well.

what about calling setLocationRelativeTo(null)? not sure how it compares to your way, but it’s still smaller than the way he’s doing it and it does what he wants.

Keep 'em coming, you’re only helping me to win 8)

Cas :slight_smile:

Based on the code you’ve shown us, I’m not too worried about that happening ;D

Besides, you’ve still got to come up with a good game idea. Good luck.

titan attacks 4k would be nice :slight_smile:

i have found that sometimes if/else sentences are smaller than ‘?’ inline comparations, specially comparing ints, don’t ask me why ::slight_smile:

On sounds, i’m working a litle one procedural, if i manage to get some more time to play with it (just got my first job as junior java programmer and i have to catch up ;D ) i’ll post something soon.

[quote]2,255 bytes. That’s how big my 4K entry is so far and all it does is open a double buffered window and listen for mouse and keyboard input.

How the hell do you guys get so much into 4K???
[/quote]
LOL! NooB! YOU SUCK!!!11

Check out the previous years threads, some people post source after the contest (miners4k hint hint).