We Love IT > Magazine > Inhoud - 2009 uitgave 1 > Java Game Development
Tags: Applicatieontwikkeling | Java

Java Game Development

Java Game Development - Spel: Peacemaker

Computerspellen geschreven in Java zijn lastig te vinden. Dat is eigenlijk raar gegeven het feit dat er al jaren uitstekende ontwikkelomgevingen voor Java beschikbaar zijn en er nu ook middleware is die het maken van spellen sterk vereenvoudigt. Kortom de tijd is rijp om spel software in Java te gaan schrijven. Naast het tonen van een aantal commerciële voorbeelden van succesvolle spellen geschreven in Java vertelt dit artikel hoe je aan de slag kunt om zelf een spel te maken.

Waarom spellen maken in Java?

Op het ogenblik worden de meeste spellen in C++ geprogrammeerd. Java heeft een aantal voordelen ten opzichte van deze taal. Java kent een hogere productiviteit door een uitgebreide standaardbibliotheek en door het gebruik van een virtual machine die zorgen over platform specifieke zaken weg houdt bij de programmeur. Daarnaast zijn er veel programmeurs die Java beheersen en maakt de taal op bijna iedere Hogeschool of Universiteit deel uit van het lespakket. Qua performance doen de recente versies van Java niet meer onder voor programma's geschreven in C++. Naast deze voordelen zijn er uiteraard ook een paar nadelen. Om te beginnen hebben computer spelen toegang nodig tot de (door hardware geaccelereerde) scherm drivers, wat alleen mogelijk is via de Java Native Interface (JNI). Dit probleem is opgelost door de komst van middleware. Een tweede en wat subtieler probleem wordt veroorzaakt door het automatisch geheugen management dat periodiek kostbare processor cycli consumeert en tot een merkbare hik in de spel ervaring kan leiden. Met een beetje aandacht valt ook hier aan te ontkomen.

Commerciële spellen gemaakt in Java

De commerciële spellen die gemaakt worden in Java worden over het algemeen alleen als download of als online spel aangeboden. Voorbeelden zijn: Nord, een multiplayer rollenspel bedoeld voor de Scandinavische markt. Daarnaast zijn er actie spellen gemaakt door Puppy Games zoals Droid Assault, Tribal Trouble en Titan Attacks. PeaceMaker is een serieus simulatie spel en heeft als doel het Israëlisch-Palestijns conflict op te lossen. Het spel heeft een aantal prijzen gewonnen op het gebied van diplomatie en vrede. Helaas is het om te spelen nogal één dimensionaal.

Hoe kan je in Java spellen ontwikkelen?

De standaardbibliotheek van Java biedt alles wat nodig is om een leuk 2D schiet- of platform spel te maken. Er is heel veel mogelijk met heel weinig code. Om een idee te krijgen van de mogelijkheden is de website van de jaarlijkse Java4K wedstrijd aan te raden: www.java4k.com. Hier staan allerlei games geschreven in standaard Java die maximaal 4096 bytes groot zijn. Weinig code, veel plezier. Van sommigen is ook de source code beschikbaar.

De standaardbibliotheek is heel uitgebreid, maar gelukkig zitten de essentiële onderdelen in slechts enkele packages. Om te beginnen is dit de java.awt package waarin alles zit om de spelwereld te visualiseren en te kunnen reageren op de invoer van de speler. De andere essentiële package is de javax.sound package voor geluidseffecten.

In zijn algemeenheid bestaat een spel uit 4 opeenvolgende stappen die telkens opnieuw worden uitgevoerd. De eerste stap is het tekenen van de spel wereld op het scherm en het laten horen van eventuele geluidseffecten. Dit dient als invoer voor de speler die vervolgens reageert via de muis of het toetsenbord. Deze invoer wordt verwerkt door het spel en het interne model van de spel wereld word aan de hand hiervan ververst. Daarna begint de cyclus opnieuw. Dit is wat men de 'game loop' noemt.

Deze 'game loop' is goed te implementeren met de standaardbibliotheek, bijvoorbeeld zoals geïllustreerd in de volgende code dat een vierkant de muis laat volgen over het scherm:

ClassicGameLoop.java

Classic Game Loop Java

De code werkt als volgt: In de main methode wordt een nieuwe instantie gemaakt van ClassicGameLoop, wat een venster is op het scherm. In de constructor wordt het venster zichtbaar gezet nadat de grootte en het standaard sluit gedrag is ingesteld. Vervolgens wordt een MouseMotionListener gebruikt om bij iedere muisbeweging de nieuwe positie van de muis door te krijgen. Wanneer het ClassicGameLoop venster is geconstrueerd wordt de run() methode uitgevoerd die de eigenlijke implementatie van de 'game loop' bevat. Als eerste wordt op asynchrone wijze gevraagd om het scherm te verversen, wat na verloop van tijd resulteert in een aanroep van de paint(..) methode. Vervolgens wordt het spel model bijgewerkt en na een korte pauze begint de cyclus overnieuw.

Een nadeel van het asynchrone updaten van het scherm via de repaint() methode is dat deze nog wel eens wil hikken. Dit komt omdat het achterliggend mechanisme probeert zo efficiënt mogelijk om te gaan met scherm verversingen en daarom er nog wel eens één of meerdere wil overslaan. Dit mechanisme is bedoeld voor gewone gebruikerinterfaces en niet voor spellen. Een oplossing hiervoor is om het heft in eigen hand te nemen en actief te gaan renderen. Dit is eenvoudig te doen door gebruik te maken van het BufferStrategy object dat in ieder venster zit ingebouwd. Door het in de constructor te initialiseren met createBufferStrategy(2) en vervolgens de 'game loop' aan te passen wordt de ClassicGameLoop een ActiveGameLoop:

ActiveGameLoop.java

Active Game Loop Java

Nu dat het scherm actief ververst wordt en daardoor geen hikken kunnen optreden is er nog een ander gemeen detail. De duur van 1 iteratie van de game loop is afhankelijk van de snelheid van de hardware. Door nu de ingebouwde vertraging van 10ms aan te passen naar een dynamische vertraging die compenseert voor de duur van het renderen en het updaten van het model kan ook dit probleem opgelost worden. System.currentTimeMillis() en System.nanoTime()_ maken dit mogelijk.

Andere belangrijke onderdelen van een spel zijn muziek en geluidseffecten. Hiervoor heeft Java ook een standaard api, de javax.sound api. Helaas zit ondersteuning voor het mp3 of ogg formaat er niet standaard in, maar door gebruik te maken van 3rd party uitbreidingen via de Service Provider Interface (SPI) zijn deze eenvoudig en transparant (geen extra code, enkel een jar file) toe te voegen aan het spel. Javazoom.net heeft bijvoorbeeld een mooie LGPL mp3 en ogg vorbis library.

De Java Scene Graph API en JavaFX

Met de komst van JavaFX is er nu ook een Java 2D Scene Graph framework. Een Scene Graph is een boomstructuur die de inhoud van het scherm representeert. Een vierkant is nu bijvoorbeeld een apart object in de boom en kan buiten de teken methode om gemanipuleerd worden. Het voordeel is dat op deze manier een beter beheersbare structuur ontstaat (in plaats van een enorme lijst van opeenvolgende teken operaties) waarin makkelijker wijzigingen kunnen worden aangebracht.

Hoe kan ik 3D spellen maken?

De standaardbibliotheek in Java is niet geschikt om zonder meer 3D spellen te maken. Uiteraard is het mogelijk om een eigen 3D software renderer maken (en daar zijn hele interessante boeken over te lezen) maar dan nog mist het spel de performance van hardware acceleratie. De enige manier om dat voor elkaar te krijgen is met native code te communiceren. Gelukkig is er de Light Weight Java Game Library (LWJGL) die het mogelijk maakt om via Open GL hardware geaccelereerde 3D graphics te tekenen, inclusief alle special effects die daarbij horen. Nu is LWJGL toch wel wat bewerkelijk aangezien je vrij direct bezig bent met Open GL instructies. Daarom is het prettig dat er nog één abstractie laag boven komt, een Scenegraph laag net zoals bij de 2D renderers. In Java heb je daar verschillende smaken van:

Java3D

Java 3D bestaat al sinds 1998. Het leidde lange tijd een sluimerend bestaan maar sinds enige tijd is het een open source (GPL) project waaraan weer actief aan wordt ontwikkeld. Java3D biedt alles wat je nodig hebt om een spel te maken. De enige minpunten die ik kan bedenken zijn dat voorbeeld code voor speciale effecten (water, reflectie) schaars is en dat je er geen commerciële spellen kan maken door de licentie.

jMonkeyEngine

Is een alternatief voor Java3D dat wel commercieel gebruikt kan worden. De jMonkeyEngine is gebouwd boven op de Light Weight Java Game Library en biedt naast een aantal standaard 'game loop' implementaties ook een ge&ium;ntegreerde muziek speler en hulpmiddelen om menu's aan het spel toe te voegen zonder dat de render code beïnvloedt. Naast de standaard dingen die van een 3D engine verwacht kan worden, worden er bij de jMonkeyEngine een groot aantal voorbeelden geleverd over hoe je bepaalde special effects kan maken. Reflecterend water, particles, schaduw etc. De jMonkeyEngine is beschikbaar voor Windows, Linux en Mac.

Physics Engines

Natuurlijk is een realistisch uiterlijk belangrijk en met de graphics engines kan dat goed benaderd worden maar realistisch gedrag is net zo belangrijk. Met zogenaamde physics engines is eenvoudig natuurkundig gedrag na te doen. Denk hierbij aan zwaartekracht, realistische botsingen (zoals bijvoorbeeld in snooker) en constructies die kapot kunnen gaan. De jMonkeyEngine heeft een apart project gewijd aan integratie met physics engines, het jME-Physics project. De standaard implementatie maakt gebruik van de Open Dynamics Engine (ODE). Op het ogenblik wordt er ook gewerkt aan integratie met de JBullet Engine dat een port is van een engine die in veel commerciële spellen gebruikt wordt.

Installatie

Een spel maken is een ding, maar het daarna installeren op andermans computer is een tweede. Zeker Java applicaties willen nog wel eens last hebben van bergen met jar files die op een en of andere manier op het classpath gezet moeten worden. Al snel resulteert dit in een .bat of .sh file. Echt gebruikersvriendelijk is anders. Gelukkig is er Java Web Start waarmee dit soort problemen opgelost kunnen worden. Java Web Start is een onderdeel van iedere Java Runtime Environment sinds versie 1.4 en verzorgt de download en installatieprocedure van Java software. Wat er precies gedownload en geïnstalleerd moet worden staat beschreven in de zogenaamde .jnlp file, inclusief eventuele platform specifieke modules.

Conclusie:

Het is op het ogenblik prima mogelijk om zowel 2D als 3D spellen te schrijven in Java. De taal en de bijpassende tooling zijn al geruime tijd volwassen en er zijn ook frameworks beschikbaar waarmee efficiënt spellen ontwikkeld kunnen worden. Voor 2D spellen is de standaardbibliotheek voldoende en voor 3D spellen zijn er interessante frameworks beschikbaar (zoals de jMonkeyEngine) die bewezen hebben dat ze werken. Door het gebruik van Java Web Start is ook installatie van het spel door de eindgebruiker eenvoudig. Het is nu slechts wachten op een ontwikkelaar die een geweldig spel schrijft!

Handige links

www.javagaming.org

Java game development forum.

www.java4k.com

Home page van de jaarlijkse java4k wedstrijd.

www.cokeandcode.com

Blog over Java games.

www.peacemakergame.com

Website van het prijswinnende PeaceMaker spel.

www.puppygames.net

Leuke in java geschreven actie spellen.

www.nordgame.com

Multiplayer rollenspel voor de Scandinavische markt.

www.jmonkeyengine.com

3D Game Engine.

Erik Hooijmeijer is senior developer bij 42 B.V. alwaar hij zich bezighoudt met maatwerk applicaties en integratie oplossingen. In zijn vrije tijd sleutelt hij enthousiast aan computer spellen.

Lees meer over 42 BV
Ga terug naar We Love IT uitgave 1 - 2009