Categories
computer games games design java tutorials programming

Writing games in Korean – part 2

Using a custom font renderer that lets me position text exactly where I want it, I put together a simple game that teaches you to count from 1 to 10 in Korean characters.

Screenshot of numbers test

First, you HAVE to manually download the Korean font I’m using (because I don’t think I can legally include it in the executable file :( )

http://www.i18nl10n.com/fonts/UnBatang.ttf

NOTE: you MUST (windows is rubbish) do “Save to” and select C:\Windows\Fonts (this causes windows to automagically “install” the font) – I can’t remember how to install new fonts on Linux or OS-X, but it should work fine with both of those OS’s too.

Then just stick the two attached files in a directory somewhere, and double-click on the one called korean-numbercounter-all.jar

Essential library (download this)
Main file (download this to same directory as the library file, and run this file)

NB: this is mainly just a proof of concept to test my rendering code, I’ve got a couple of other simple “games” like this I’ve knocked up as tests.

Categories
computer games dev-process java tutorials programming

Writing games in Korean – part 1

First, check whether I can actually render Korean characters. I know that Unicode supports nearly all of the glyphs (or, more correctly it seems, “ideographs”) needed for Chinese, Japanese, Korean (typically abbreviated as “CJK”) – but I also know that MS Windows fonts are infamous for missing some/most/all of the unicode characters (there are tens of thousands of them, so this is not all that surprising – except that Microsoft has been shipping OS’s localized to those countries for many years now, so I’d hoped maybe they would include at least ONE “CJK + Latin” font on all machines by now, no? No; they don’t).

Quick test program using Java (NB: java one of the easier languages for this because it was invented late enough that Unicode had settled down, and so it has extremely good Unicode support built-in to the core libraries, unlike C++ et al. By default, Java uses unicode almost everywhere, so I don’t need to debug unicode support, yay!):

NB: …but then when I tried it I quickly discovered a problem. I quickly gave up on the obvious route, so might have missed a workaround, but… I could have done this using Java’s built-in GUI toolkit (Swing), which supports using any font as a text label. However, it seems there’s a design flaw in Swing that’s been around since 1997 (yes, folks, 11 years and counting): the only component that can have the font changed – JLabel – which is a “general-purpose” label for any GUI component (good idea!) … is incompatible with the only component capable of being a button – JButton – which is a “general-purpose” button. Crap. If I’m not missing something here, with one small piece of poor API design, Sun have made their *almost* international-friendly GUI system almost completely useless for multi-language GUIs. Just to be clear: it’s not specifically internationalization they’ve broken here: its a general issue – any forms of customized rendering cannot use the JButton / JLabel combo. Why? Why, why, why would you do such a stupid thing, after going to the effort of making these generic widgets? Oh, well. Custom rendering it is…

/**
 * Simple test program that renders Unicode characters from a particular font of
 * your choice, a couple of thousand at a time, automatically wrapping them based on
 * render width on screen.
 * 
 * You need to manually change the font name and the start/end co-ordinates of where
 * in the unicode constellation to render.
 */

import java.awt.*;
import javax.swing.*;

public class PaintSomeUnicodeChars extends JFrame
{
	void setup()
	{
		getContentPane().add( new charPane() );
	}
	
	public static void main( String[] args )
	{
		PaintSomeUnicodeChars window = new PaintSomeUnicodeChars();
		window.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		window.setup();
		window.pack();
		window.setSize( 600, 500 );
		
		window.setVisible( true );
	}
}

class charPane extends JPanel
{
	public void paint( Graphics g )
	{
		int si = 44032;
		int ei = 46000;
		g.setColor( Color.red );
		g.setFont( new Font( "Verdana", 10, 40 ) );
		g.drawString( "Chars from " + si + " to " + ei, 30, 30 );
		
		g.setColor( Color.black );
		g.setFont( new Font( "Lucida Sans Unicode", 10, 20 ) );
		
		int accumulator = 0;
		int height = 20;
		int xwidth = getWidth();
		for( int i = si; i < ei; i++ )
		{
			char[] chars = Character.toChars( i );
			String drawString = String.copyValueOf( chars );
			int advance = g.getFontMetrics().charsWidth( chars, 0, chars.length );
			
			if( accumulator + advance > xwidth )
			{
				accumulator = 0;
				height += g.getFontMetrics().getHeight();
			}
			
			g.drawString( drawString, accumulator, height );
			
			accumulator += advance;
		}
	}
}

Why choose Lucida Sans Unicode?

Apart from the fact that it’s present on all modern Windows machines automatically, I cheated a bit and used Character Map (Start > Programs > Accessories > System Tools > Character Map) to quickly inspect each of the fonts already installed and find out which ones had lots of unicode in them. Character Map has a neat feature where it completely ignores missing characters, automatically skipping over them, so you can very quickly see if a font has lots of unicode, some, or very little.

Stepping through in the java app, I fairly quickly found lots of Unicode characters. success – I can correctly render arbitrary Unicode characters in java.

NB: important because it took a lot more lines of source than I expected; java’s built-in “char” datatype is incapable of being used to render Unicode, because it’s too small a range of values. That also means you can’t use ANY methods that take a char as argument (this is documented in the Java API docs for Character). I’d never really used the methods that take int’s as argument before…

Fonts…

Not really happy with the font, though, and it’s clearly missing a whole bunch of characters. Some googling for free CJK fonts found me that allegedly Arial Unicode MS would work – which comes free with Microsoft Office (which I have on one of my machines).

NB: the way font licensing works, it’s probably illegal to copy a font you have on one machine to another machine you own. Unless you can obtain the font from the original source (e.g. in this case by buying a second copy of MS Office).

Arial Unicode MS has lots of characters, but … they’re wrong. At least, one third of the ranges of Korean characters are completely useless, as far as I can tell, because whoever made this font (whoever Microsoft licensed it from?) didn’t read the spec carefully and stuck the wrong characters in from U+1100-U+11FF. More on this later…

Giving up on that font, I went looking for others. The first four or five I tried that didn’t look ugly were all from download sites in Japan or Korea and kept crashing on the download. I found a couple of places hosting UnBatang (“UnBatangOdal.ttf”) and claiming it was free, but the first I found where the download didn’t crash was on http://www.i18nl10n.com/fonts

UnBatang (the name you have to use in Windows / Java from inside an application in order to load it) seems to work very well. It has nicely painted ideographs for the main range of Hangul characters/syllables, and it has *correct* glyphs for the other two ranges (although they’re a bit ugly).

Unicode Hangul

Specifications for official standards tend to be big. Really big.

Specifications for anything to do with internationalization tend to be huge.

Add in localization and data-transfer between different cultures, and you can expect something gargantuan.

So, I was really really happy to find a downloadable copy of only the CJK Chapter of the Unicode 5.0 specification (it’s still a big document!). This contains a full explanation of what Hangul is in Unicode, where to find it (yay!), and why there are not one but three separate sets of Hangul glyphs.

Here’s the preface to the Chapter 12 PDF I downloaded, in case you want to find the spec / electronic version yourself:

Electronic Edition

This file is part of the electronic edition of The Unicode Standard, Version 5.0, provided for online
access, content searching, and accessibility. It may not be printed. Bookmarks linking to specific
chapters or sections of the whole Unicode Standard are available at

http://www.unicode.org/versions/Unicode5.0.0/bookmarks.html

Purchasing the Book

For convenient access to the full text of the standard as a useful reference book, we recommend purchasing
the printed version. The book is available from the Unicode Consortium, the publisher, and
booksellers. Purchase of the standard in book format contributes to the ongoing work of the Unicode
Consortium. Details about the book publication and ordering information may be found at

http://www.unicode.org/book/aboutbook.html

Unicode 5, Hangul, and Arial Unicode MS

So, armed with the offical spec, I read up on Hangul. What did I find?

The Unicode Standard contains both the complete set of precomposed modern Hangul syllable
blocks and the set of conjoining Hangul jamo. This set of conjoining Hangul jamo can
be used to encode all modern and ancient syllable blocks.

(this is the glyphs at U+1100–U+11FF)

“conjoining Hangul jamo” means “these glyphs have been positioned inside their spaces in the font so that if you need to make one ideograph out of, say, four Korean letters, you just pick the top-left version of the first letter, the top-right version of the second, etc, and OVERLAY all the glyphs, and what comes out will autamatically be correctly spaced out etc”.

What did the author of Arial Unicode MS do?

Made all those glyphs take up the full available space, and centre them horizontally and vertically.

Why? Seriously, why? Because any application that tries to render those characters is going to render them on top of each other (according to the specification, this is the ONLY point of having those characters), and you won’t be able to read at all what the letters say.

If you want to render just individual letters from the Korean alphabet, there’s a different range of Unicode where you can find them all centred etc (which Arial Unicode MS also has … so it seems to be just copy/pasting internally).

I guess the font author just didn’t read the spec. Or I’m completely misunderstanding the spec. But the fact that UnBatang spaces the conjoining jamos out in such a way that this works as I expected it to suggests to me that it’s the Arial Unicode that’s broken…

The joy of Conjoining

I couldn’t get hold of the Unicode spec section on how to conjoin, because of some mimetype problems between their server and my PDA’s web browser. I figured I could probably work it out by trial and error fairly quickly.

I can’t remember how to spell my name in Korean yet – I know the letters, I’m just a bit flaky on what the placement of them is. So, a quick experiment, to see how easy it is to position characters using the Conjoining Jamo from UnBatang:

	... constants used later - the Unicode values for the letters of my name: ...
	
	int a = 0x1161; // jungseong vowel
	int d = 0x1103; // choseong consonant
	int d2 = 0x11ae; // jongseong consonant
	int m = 0x1106; // choseong consonant
	int m2 = 0x11b7; // jongseong consonant
	int blank = 0x110b; // silent char you place at front if first letter is a vowel
	
	... the body of the paint method: ...
	
	g.setColor( Color.black );
	g.setFont( new Font( "UnBatang", 10, 30 ) );
		
	int w = 0;
	int lead = 0;
	w += renderIdeograph( g, blank, lead, 40  );
	w += renderIdeograph( g, a, lead+w, 40  );
	w += renderIdeograph( g, d2, lead+w, 40  );

	lead+=30; w = 0;
	w += renderIdeograph( g, blank, lead+w, 40  );
	w += renderIdeograph( g, a, lead+w, 40  );
	w += renderIdeograph( g, m2, lead+w, 40  );
		
	lead=0; w = 0;
	w += renderIdeograph( g, blank, lead+w, 80  );
	w += renderIdeograph( g, a, lead+w, 80  );
		
	lead+=30; w = 0;
	w += renderIdeograph( g, d, lead+w, 80  );
	w += renderIdeograph( g, a, lead+w, 80  );
	w += renderIdeograph( g, m2, lead+w, 80  );
	
	... and then this method to do the paint of each part of an ideograph: ...
	
	/** Doesn't really render an ideograph, renders a single glyph from the Font */
	public int renderIdeograph( Graphics g, int i, int x, int y )
	{
		char[] chars = Character.toChars( i );
		String drawString = String.copyValueOf( chars );
		int advance = g.getFontMetrics().charsWidth( chars, 0, chars.length );
		
		g.drawString( drawString, x, y );
		
		return advance;
	}

Which renders exactly like this:

hangul-adam-unbatang.PNG

Which makes me want to point out the nice thing about properly specified fonts: in the source code, I simply did “the natural thing”, as if I were outputting characters in an arbitrary conjoined language:

  1. Render the first part of the first ideograph at (x,y)
  2. Ask the font to tell you how many pixels wide (w) it just rendered that part
  3. Render the next part of the first ideograph at (x+w,y)
  4. …repeat until first ideograph is complete, increasing w more and more each time…
  5. Choose a value for how much you want the ideographs separated from start to start (ideograph_width)
  6. Render the first part of the second ideograph at (x + ideograph_width, y)
  7. …repeat as for first ideograph

And it worked. First time. I didn’t expect it to – I expected to have to do something strange like manually “reset” the (w) value each time I went from the first line of the ideograph to the second (Korean orders letters top-left, top-right, bottom-left, bottom-right, (repeat) … as opposed to Latin which is just left, right, more right, even more right, etc).

For this to have worked, it means the font is deliberately rendering the lower letters (e.g. d2 and m2 in my constants) a long way to the left of the origin that you tell it to render them at. This would be very, very confusing if you just tried to render these letters individually (well, duh).

Of course, if you try to run that code using Microsoft’s Arial Unicode MS font, you get a complete mess instead, because that font is FUBAR, as mentioned before. You get this:

hangul-adam-arial-unicode.PNG

…which is completely incomprehensible.

Categories
java tutorials programming

Java considered harmful as first programming language…

Today, I was pointed at an article suggesting that java is responsible for the decline in the quality of Computer Science graduates.

Specifically if you want to be a Computer Scientist, I’d say that the initial claim that “java is bad as a first language” is true, just as “C++ is bad as a first language” is true. What disappoints me is that they go on to suggest that C++ is good as a first language (disclaimer: my uni course taught ML as first language, ARM assembler as second).

Categories
java tutorials networking programming

Java NIO Server Example

I’ve made a small simple but complete java NIO server (with full source included) that is free for anyone to use for anything. At the moment, it only deals with sending and receiving strings, and isn’t optimized, but if anyone wants to improve it and send me the changes then I’ll post up an improved version here.

Download, documentation, license details, tutorial etc after the jump…

Categories
facebook java tutorials

Ten tips and tricks for writing Facebook Apps

(Only a couple of these are java-specific, but this is a.k.a.: “How to make Facebook Apps using Java – part 3”)

(I assume you’ve already had a look at part 1 and part 2? They’re more beginner-oriented)

Bugs, Misconceptions, and Subtle Features

Interfacing with Facebook’s servers is pretty hard, considering how seemingly trivial the interface is. Obviously the almost total lack of documentation is mostly to blame for this, but some of it is just common bugs that have yet to be fixed.

So, here’s ten things I’ve found whilst fiddling with the API, and some of the nicer features that may not be immediately obvious even if you do read the docs provided by FB (you should go read all of them, but … there’s some bad organization and layout, so it can be a chore reading the mega-long HTML pages, with many of the API features having just blanks for description fields :( ).

Categories
facebook java tutorials

How to Make Facebook Apps Using Java – part 2

In the first part, I covered a very high-level, idiot-guide to getting started with writing a Facebook app in java. This part will cover the details of how to architect your own code for basic Facebook authentication, and include code samples you can use to get up and running more quickly. It will also explain in more detail precisely how Facebook’s servers interact with your code, and what you can expect (and what their servers expect of you!).

NB: if the quoted source code is unreadable because it disappears off the edge of the screen, select it and copy/paste (or view source of the page to see it). The most useful stuff is put together into one class you can download here – source code for FacebookLoginServlet.java.

Categories
facebook java tutorials

How to Make Facebook Apps Using Java – part 1

I wrote a game last weekend, for Facebook. Writing the entire multiplayer persistent game took a day and a half; getting it to integrate with Facebook is taking several days. Mostly, the problem is that Facebook hasn’t – yet – provided user-guide documentation, and there are plenty of bugs in their system. Without docs, you have to guess whether a “nothing happens” is due to your mistaken guesswork, a bug in FB, or … a bug in your own code. That’s fine, but it takes time, lots of time.

Google kept giving me zero hits for any of the problems, or even any java-focussed docs (just one link to a FAQ on an issue that seems to be a bug that was fixed a while ago. That’s all). So, as I solve the various problems that come up, I’m writing about them.

Platform

First thing to be clear about: if you want to write FB apps using java, you’ll be using Enterprise Edition (J2EE). The way FB works *requires* you to provide a webserver for your app. Whilst its true that java can run in the web browser, that’s a completely different way of using java – for this, you’re going to have to find a server, and install J2EE (it’s the same as standard java, just has lots of extra libraries, only a few of which you’ll need to use).

Facebook Apps: how they work

This diagram shows a very simplistic summary of the different URL’s you are asked for when registering a Facebook application, or are used when serving an App. Note that FBML is served entirely internally in the FB server, it does NOT make a request to your web server.

NB: this image got deleted in the server crash last month; WordPress is rather badly designed with images, and doesnt save them. But it’s been stolen and copied widely all over the web, so you can probably find it relatively easily
Basic explanation of facebook servers

First step: Registering your Facebook Application

Assuming you can find yourself a webserver/J2EE server to run your app on, and have a domain name for it (or the hosting provider gives you a default domain-name – you don’t HAVE to buy one just for your app), the first thing to do is register the app with Facebook. This just reserves the name of your app, and gets you the login details you’ll need before you can do ANY testing or development.

This process is actually nicely documented (and is also very simple – although the huge scary forms they ask you to fill in are very poorly explained, there’s a only a few fields you actually *need* to fill in). Don’t follow the list of things on that page literally, see the differences below that you want to make.

For the URL’s you need to fill-in, you’ll be making a servlet for each. So, work out the URL for each of the servlets (depends on how you setup your J2EE server), and have them ready to give to FB.

So, to summarise:

  1. Create a Facebook account if you don’t have one, and login
  2. Add the “Developer” app to your account (link is here)
  3. Go to your Home page on FB
  4. Click on the Developer app in the sidebar to go to the main centre for all your Developer activity
  5. Make a new application, and fill in the form it presents you with (make sure you do at least:
    1. App name
    2. Callback URL (see the example app)
    3. Canvas page (see the example app)
    4. iFrame (not FBML)
    5. Post-add URL (see the example app)
  6. Save the api-key and the session-key that it now displays for the newly-created app – you’ll need them to do any coding

First test: Can Facebook display your Application?

Create the various servlets on your server (callback, postadd, and canvas) and make each of them return basic HTML that just says “callback servlet”, “postadd servlet”, or “canvas servlet”).

Open a new browser window, and type in the canvas page URL from FB, something like: http://apps.facebook.com/yourApplicationName

You might be asked some security stuff by FB, but once you’ve got past that you should then see a Facebook page with the navbars etc, but just a big empty space in the middle with the test “callback servlet”. If so, congratulations, you’ve got your app basically working. Now comes all the hard stuff…

If not, first check that your servlet is even working, by copy/pasting the callback URL from your FB application setttings (click Edit Settings to re-load the form you submitted) into a browser window, and seeing if you can get the page. You’ve probably got a typo in the URL you gave FB. If the “callback servlet” text doesn’t come up on its own, without all the FB stuff, then your J2EE server is misconfigured or broken. Time for you to go find some Tomcat / jBoss / etc tutorials and get your J2EE working…

Part two…

Now you can move on to part 2 of this series, covering the details of how to authenticate with Facebook and start doing interesting work, including sample source code.