I thought I would try to get the Lightweight Java Game Library (LWJGL) running in Scala as both are really hip nowadays. Turns out that there is not much available on teh internets that works. Most of them use the “Simple Build Tool” (sbt) which I did not find simple at all. Also they have a new version 0.10.x which is incompatible to the Scala+LWJGL examples which use sbt version 0.7.x. Yay!
Anyhow, I used the Scala code from http://lwjgl.org/forum/index.php?topic=3416.0 and finally managed to get it run without any “simple” tools or other dependencies. Here is how:
- Download the current LWJGL release (as of writing: 2.7.1). This should give you a zip file with a few jars, dlls and so files.
- Download and install Scala from http://www.scala-lang.org/ (as of writing: 2.9.1)
- Create the folders “lwjglproject/lib” and “lwjglproject/src”
- Extract all .jars to “lwjglproject/lib”. When using Windows do so with the dlls, on Linux put the .so files there and Mac users probably don’t have to do anything (that’s what I’m always being told)
- Create a source file “lwjglproject/src/lwjgl.scala” with contents from the example (also available further down)
- Compile the code with
scalac -classpath ./lib/lwjgl.jar src/lwjgl.scala
this should give you some .class files
- Run the example by executing
scala -classpath lib/lwjgl.jar -Djava.library.path=./lib Main
- Enjoy
Oh, and if you want to run the program directly with java to have to specify the path to scala-library.jar and add the (current) “lwjglproject” path to the classpath:
java -classpath .:lib/lwjgl.jar:/lib/scala-library.jar -Djava.library.path=./lib Main
Here is the code for the example:
import org.lwjgl._ import opengl.{Display,GL11,DisplayMode} import GL11._ import input._ import math._ object Main{ val GAME_TITLE = "My Game" val FRAMERATE = 60 val width = 640 val height = 480 val player = new Player(0,0,0); var finished = false var angle = 0.0f var rotation = 0.0f def main(args:Array[String]){ var fullscreen = false for(arg <- args){ arg match{ case "-fullscreen" => fullscreen = true } } init(fullscreen) run } def init(fullscreen:Boolean){ println("init Display") Display.setTitle(GAME_TITLE) Display.setFullscreen(fullscreen) Display.setVSyncEnabled(true) Display.setDisplayMode(new DisplayMode(width,height)) Display.create println("init gl") glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) adjustcam } def adjustcam(){ val v = Display.getDisplayMode.getWidth.toFloat/Display.getDisplayMode.getHeight.toFloat printf("v:%f",v) glMatrixMode(GL_PROJECTION) glLoadIdentity glFrustum(-v,v,-1,1,1,100) glMatrixMode(GL_MODELVIEW) } def cleanup(){ Display.destroy } def run(){ while(!finished){ Display.update logic render Display.sync(FRAMERATE) } } def logic(){ // in scala we can locally import all methods from Keyboard. import Keyboard._ if(isKeyDown(KEY_ESCAPE)) finished = true if(Display.isCloseRequested) finished = true // rx and rx store our keyboard input as direction var ry = 0 var rx = 0 // keys are IKJL for up down left right if(isKeyDown(KEY_I)) ry += 1 if(isKeyDown(KEY_K)) ry -= 1 if(isKeyDown(KEY_J)) rx -= 1 if(isKeyDown(KEY_L)) rx += 1 // this makes the direction relative to the camera position // it is a simple rotation matrix you may know from linear algebra val ax = rx*cos(-rotation.toRadians)-ry*sin(-rotation.toRadians) val ay = rx*sin(-rotation.toRadians)+ry*cos(-rotation.toRadians) player.x += 0.1f*ax.toFloat player.y += 0.1f*ay.toFloat // this rotates our camera around the center angle += 2.0f % 360 rotation += 0.2f } def renderGrid(size : Int){ // this creates the nice looking background. glDisable(GL_LIGHTING) glBegin(GL_LINES) for(i <- -size to size){ glVertex2i(i,-size) glVertex2i(i, size) glVertex2i(-size,i) glVertex2i( size,i) } glEnd glEnable(GL_LIGHTING) } def render(){ glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity glTranslatef(0,0,-20) glRotatef(-70,1,0,0) glRotatef(rotation,0,0,1) glPushMatrix player.applyPos //rotate the player just for fun glRotatef(angle, 0, 0, 1.0f) player.draw glPopMatrix //without background, motion is not visible // a green grid is nice and retro glColor3f(0,1,0) renderGrid(10000) } } class Player(nx:Float,ny:Float,nz:Float){ var x:Float = nx var y:Float = ny var z:Float = nz def applyPos { glTranslatef(x,y,z) } def draw = { glColor3f(1, 0, 0) glBegin(GL_TRIANGLE_FAN) glNormal3d( 0, 0, 1); glVertex3d(0,0,0.5) glNormal3d(-1,-1, 1); glVertex2d(-0.5, -0.5) glNormal3d( 1,-1, 1); glVertex2d(0.5, -0.5) glNormal3d( 1, 1, 1); glVertex2d(0.5, 0.5) glNormal3d(-1, 1, 1); glVertex2d(-0.5, 0.5) glNormal3d(-1,-1, 1); glVertex2d(-0.5, -0.5) glEnd } }
Comments are closed.