To port my game I ported a game engine to android (Part II)

March 9, 2014

tl;dr: In the first part of this article I wrote about the motivations and the first steps I made to port the LÖVE engine to Android. Here I write about some technical difficulties that were solved and a few very interesting features the port now has. Also I created a small incomplete list of people who have contributed to this port.

Running a Real Game

I was really stoked when I saw the nogame screen the first time on my phone. A big helper for this was the GLES port of @slime73. There was almost no change required to get this far. The next thing up was to load an actual game. For this I had to somehow load the game. Undearneath LÖVE use physfs and comes with a custom wrapper for it. After some experiments I figured out that the Android NDK supports standard file I/O to the sd-card if you give the App write permissions to external storage (i.e android.permission.WRITE_EXTERNAL_STORAGE). With this knowledge in hand I implemented loading of the game found in /mnt/sd-card/lovegame. This allowed me to start my game on the phone without having to change a single line of the original Ludum Dare submission:

Running the game unveiled a bug in the GLES code when pushing new transformations but the fix was simple. From that on the game “just worked”. Including audio for which I did not have to change a single line of code!

Make it Work

Packaging Games

Now the port seemed it a very capable state. Something essential that was missing was creating a game Android package of the LÖVE engine + game into a proper Android package. I could already load games that were placed to /mnt/sdcard however LÖVE games are usually distributed either with the LÖVE binaries as OS specific packages or as .love files which is simply the game project folder packed into a zip file. Also LÖVE can directly load .zip files to run the games contained in them.

On Android on the other hand Apps can only open files that are stored in the assets/ folder. Luckily SDL2 allows accessing files in the assets folder without much hassle using the SDL_RWops. To create a packaged I simply added the game.love file to the assets and when starting the App it would open the file using SDL_RWops and copy it to the internal storage and then load it using the standard LÖVE code. While this worked well this has the huge drawback that games would consume twice the memory: in the package’s asset/ folder and then in the internal storage. I could have tried to delete the latter when exiting the app but this didn’t work reliably enough.

Instead inspired by a hint of @slime73 I switched to the inofficial 2.1 code of physfs (which can be obtained using the official physfs merurial repository). Physfs 2.1 comes with PHYSFS_mountMemory that allows to load archives from memory instead of actual files, which works perfectly. I still have to copy the game from the assets/ directory into a memory buffer but it is much nicer and also uses less overall memory in the app statistics. (Physfs unfortunately introduced a bug but that is avoided in my port using a small hack).

LuaJIT instead of Lua

Another improvement that I wanted to do was to use LuaJIT instead of stock Lua. I had started with the latter as I wanted to first get things work and clean up things later. LuaJIT (which is also the now default in LÖVE) has quite a performance advantage in many cases over standard Lua — even on ARM. Setting up LuaJIT for the LÖVE port was quite a hassle. It comes with its own build system that I did not manage to integrate into Android’s NDK build system unfortunately. Eventually I resorted to adding the LuaJIT binaries to the repository along with a small script that builds it using the LuaJIT build system and the required Android specific parameters.

When testing LuaJIT with the LÖVE code unfortunately I had worse performance than using standard Lua. It took me a long time to figure out what might be the cause for it. To be honest I am still not entirely sure what exactly, however when reading this thread I tried the older 2.0.1 version and I could finally enjoy the performance gains. One nice thing about Android is that the JIT part of LuaJIT actually works.

As far as I know Apple sadly prohibits code generation on iOS which makes JIT impossible (see comment about iOS at http://luajit.org/install.html).

Updating of Libraries and Proper Linking

The build system for the external libraries was created using @schattenkindnet‘s older port. Some of the libraries that LÖVE uses have been updated since then and so I went on to update them. For some it was a lot of work to figure out which compiler flags were actually required or parts of the files were created during the build system which then again made me cross compile code using autotools (scary!) and extract files. Openal-soft was also challenging as it used CMake for which a CMake Toolchain script had to be used to create the proper configuration header files.

Eventually I ended up with all the files required such that I could use Android’s ndk-build to build everything (except LuaJIT). In the same time I also made sure that I link against all LGPL libraries dynamically whereas everything else is linked statically to reduce the binary size. Updating the libraries was worth it as also fixed audio performance.

Multi-Touch API

It wouldn’t be a proper mobile game engine if it didn’t have a touch API. I received a patch by piernov which fixed this. Eventually this code was replaced by the love.touch that was introduced to the experimental repository shortly afterwards and aims to be compatible with a future iOS port.

Make it nice

Additionally to the more or less technical things above the LÖVE port has a few very nice additions:

Accelerometer as Joystick: instead of adding a special sensor API read the accelerometer using SDL’s joystick API. This involved fixing a bug in SDL2 which was done by Jairo Luiz

Icon: Seppi (@josefnpat) created a fantastic logo out that mixes the Android with the LÖVE logo: ic_launcher

File Association: Since beta2 the Android LÖVE App adds a (somewhat experimental) file association. At least using Chrome mobile it lets you download .love files from the web such that you can open them from your Downloads activity. Also .love files attached to emails can be opened directly using the LÖVE App. Large parts of this was also made by Jairo Luiz

Game Editing on Device: Since LÖVE uses Lua and the code gets compiled/interpreted on run-time it allows for editing the game on the device itself without a host computer. Heck! It would even be possible to create whole games on the Android device without a PC!

Create Games for OUYA: People have even tried the port on Ouya. And guess what: it works!

Sensible Default Mappings: A touch event is reported as a left mouse button event. The back key maps to the escape key. For simple games this is sufficient to make it work.

Future?

I am currently working on getting my game released on the Google Play Store. It has been approved already and but I at the moment I am cleaning up some edges. But I hope to release it soonish to the public. Follow me on twitter or subscribe to the blog and you’ll get notified.

Also publishing the LÖVE App via the play store would be an idea. Maybe with some kind of launcher to simplify running of different games?

Contributors

This all was only possible due to the fantastic works of others. Even though the risk is extremely high that I will forget valuable contributors I want to list some (let me know if I missed someone or something):

Tags

Löve for Android – Alpha1

December 17, 2013

tracksurfer_android

Over the last few weeks I made attempts to create a native port the awesome 2D game engine Löve to Android. So far it seems to work for relatively simple games. This was mainly possible due to the great GLES port of Alex Szpakowski (@/slime73).

Here are some e if you want to give it a try.

Instructions

  1. Extract a game to /sdcard/lovegame, i.e. i.e. main.lua must be located at /sdcard/lovegame
  2. Download the Löve app from http://fysx.org/~martin/shared/love_android_sdl2_alpha1.apk
  3. Run the app

Notes

This is super early alpha. Not sure yet what works and it’s possible that it may not work as expected.

Custom Types in LuaTables++ Done Right

October 22, 2013

Even though I am qute happy with LuaTables++ I figured storing and retrieval of custom types could be made even nicer. In my previous post I presented how one could add a custom type (i.e. a C++ struct or class) such that it can be assigned to values in Lua. It still required knowledge of the Lua C-API and would furthermore have made assignment of nested values more cumbersome. It now dawned to me that I could re-use facilities in LuaTables++ to circumvent both points.

For a struct of the form:

struct CustomType {
    string name;
    double age;
    bool drunken;
    double position[3];
};

especially setting the values of the double position[3] array would require creation of a new table which can be a bit cumbersome if one is not familiar with Lua’s stack. However this kind of functionality is already included in LuaTables++. Using the new API one can now implement the LuaTableNode::getDefault<CustomType>(const CustomType &value) function as:

template<>
CustomType LuaTableNode::getDefault<CustomType>(const CustomType &default_value) {
    CustomType result = default_value;

    if (exists()) {
        LuaTable custom_table = stackQueryTable();

        result.name = custom_table["name"].get<std::string>();
        result.age = custom_table["age"];
        result.drunken = custom_table["drunken"];
        result.position[0] = custom_table["position"][1];
        result.position[1] = custom_table["position"][2];
        result.position[2] = custom_table["position"][3];
    }

    stackRestore();

    return result;
}

and similarly the LuaTableNode::set<CustomType>(const CustomType &value) as:

template<>
void LuaTableNode::set<CustomType>(const CustomType &value) {
    LuaTable custom_table = stackCreateLuaTable();

    // set the fields of the custom type
    custom_table["name"] = value.name;
    custom_table["age"] = value.age;
    custom_table["drunken"] = value.drunken;
    custom_table["position"][1] = value.position[0];
    custom_table["position"][2] = value.position[1];
    custom_table["position"][3] = value.position[2];

    // restore the stack
    stackRestore();
}

One has to keep in mind that Lua starts its indices at 1 instead of 0. But apart from that I guess it should now be quite easy to add any kind of structs or classes even with complex member variables. If you have a suggestion to make it even simpler, let me know!

Tags

Using Lua Scripts as Config Files from C++

October 16, 2013

tl;dr: LuaTables++ is a library that allows you to access values from Lua scripts in an easy manner. Custom types (i.e. structs or classes) can be easily added so that storing and retrieval to and from Lua is super simple. Serialization to strings is included. Code available here (MIT license). Handling of custom classes / structs is explained here.

Introduction

For my visualization tool MeshUp I am using jsoncpp to store the configurations files. However it dawned to me that it should be easy to implement a library that allows to store and retrieve values from Lua scripts similarly easy as jsoncpp. As Lua has a nicer syntax than JSON this would allow me to store the configuration as Lua scripts and thus getting all the scripting capabilities there as well.

Overview

The last few days I spent some time to pimp the my LuaTables (which I mentioned here) library to make it more intuitive to use from C++ and I ended up something very nice. It even deserves a renaming to LuaTables++. First, an example:

-- agentsettings.lua
person = {
    name = "James Bond",
    age = 42.,
    drunken = true,
    address = {
        country = "United Kingdom"
    }
}

return person

Can be accessed using LuaTables++ using:

LuaTable ltable = LuaTable::fromFile("myfile.lua")

std::string name = ltable["name"];
double age = ltable["age"];
bool drunken = ltable["drunken"];
std::string country = ltable["address"]["country"];

Similarly you can set values:

ltable["drunken"] = false;

And also convert the table back to a string, e.g. to save the configuration back to a file:

std::string config_string = ltable.serialize();

Custom Types

Update: I have found a much better solution on how to handle custom types with LuaTables++.

This was very nice, but it gets better: LuaTables++ uses some templating magic inside which can be used to add reading and writing for structured data. E.g. to add the following custom type:

struct CustomType {
    CustomType() :
        name ("unnamed"),
        age (-1.),
        drunken (false) {}

    string name;
    double age;
    bool drunken;
};

one has to implement two functions:

Here the function for converting from LuaTables++ to the C++ CustomType:

template<> CustomType LuaTableNode::getDefault<CustomType>(const CustomType &default_value) {
    CustomType result = default_value;

    if (stackQueryValue()) {
        lua_getfield (luaTable->L, -1, "name");
        result.name = lua_tostring (luaTable->L, -1);
        lua_pop (luaTable->L, 1);

        lua_getfield (luaTable->L, -1, "age");
        result.age = lua_tonumber (luaTable->L, -1);
        lua_pop (luaTable->L, 1);

        lua_getfield (luaTable->L, -1, "drunken");
        result.drunken = lua_toboolean (luaTable->L, -1);
        lua_pop (luaTable->L, 1);
    }

    stackRestore();

    return result;
}

And here the function to store a C++ CustomType to LuaTables++:

template<> void LuaTableNode::set<CustomType>(const CustomType &value) {
    stackCreateValue();

    // create new table for the CustomType
    lua_newtable(luaTable->L);  // parent, CustomTable

    // set the fields of the custom type
    lua_pushstring (luaTable->L, "name");
    lua_pushstring (luaTable->L, value.name.c_str());
    lua_settable (luaTable->L, -3);

    lua_pushstring (luaTable->L, "age");
    lua_pushnumber (luaTable->L, value.age);
    lua_settable (luaTable->L, -3);

    lua_pushstring (luaTable->L, "drunken");
    lua_pushboolean (luaTable->L, value.drunken);
    lua_settable (luaTable->L, -3);

    // add table of CustomType to the parent
    stackPushKey(); // parent, CustomTable, key
    lua_pushvalue(luaTable->L, -2); // parent, CustomTable, key, CustomTable
    lua_settable(luaTable->L, -4);

    // restore the stack
    stackRestore();
}

Once this is done, one can directly store and retrieve any CustomType to Lua:

// Create a new Custom Type
CustomType agent007;
agent007.name = "James Bond";
agent007.age = 42.;
agent007.drunken = true;

// Store it in LuaTables++
ltable["agents"][123] = agent007;

// Retrieve it from LuaTables++
CustomType other_agent = ltable["agents"][123];

One nice thing about this is, that once you have implemented the set() and getDefault() functions you automatically can serialize and de-serialize CustomTypes. Yeeeehaaaa!

Code

LuaTables++ is available from https://bitbucket.org/MartinFelis/luatables only depends on the STL and Lua, which should be easy to fulfill. It is licensed under the MIT license (same as Lua).

Fun Fact: Around the same time Elias Daler implemented something similar to retrieve values from a Lua script http://eliasdaler.wordpress.com/2013/10/11/lua_cpp_binder/. His article also contains a brief introduction how the internals work.

Tags

Switching between Lua and LuaJIT using CMake

August 26, 2013

The more I work with Lua, the more I get addicted to it. Lua itself is a formidable language and additionally it is (somewhat) fun to write wrappers to C/C++ code.

Lua itself is fast, but it can be made even faster by using LuaJIT, which is one of the fastest scripting language implementations available. The nice thing about LuaJIT is, that it is both API and ABI compatible to the standard Lua 5.1 implementation. This means that you simply need to link against the LuaJIT library instead of the Lua library and you get increased performance for free*!

For most of my C/C++ code I am using CMake as a build tool, which is does its job most of the time, albeit its language and syntax is rather cumbersome (especially compared to Lua). There is premake, a build system using Lua, which looks very interesting, however right now I have too little time to move my stuff over to it.

CMake comes with scripts to find Lua 5.0 and 5.1 but not to find LuaJIT. So I wrote my own FindLua.cmake script that searches for Lua 5.1 or LuaJIT depending on the value of the variable LUA_USE_LUAJIT option. Adjusting this variable allows easy switching between the standard Lua and LuaJIT.

CMake caches most of its variables and therefore you cannot change the type of Lua implementation using the CMake GUI. To alleviate this you can use the following lines, that ensure the invalidation of the cached CMake variables and nice and snappy switching between the implementations from the CMake GUI:

OPTION (LUA_USE_LUAJIT "Use LuaJIT instead of default Lua" OFF)
UNSET(Lua_FOUND CACHE)
UNSET(LUA_INCLUDE_DIR CACHE)
UNSET(LUA_LIBRARY CACHE)
FIND_PACKAGE (Lua REQUIRED)

Here is full FindLua.cmake script:

# Copyright (c) 2013 Martin Felis &lt;martin@fysx.org&gt;
# License: Public Domain (Unlicense: http://unlicense.org/)
#
# Try to find Lua or LuaJIT depending on the variable LUA_USE_LUAJIT.
# Sets the following variables:
#   Lua_FOUND
#   LUA_INCLUDE_DIR
#   LUA_LIBRARY
#
# Use it in a CMakeLists.txt script as:
#
#   OPTION (LUA_USE_LUAJIT "Use LuaJIT instead of default Lua" OFF)
#   UNSET(Lua_FOUND CACHE)
#   UNSET(LUA_INCLUDE_DIR CACHE)
#   UNSET(LUA_LIBRARY CACHE)
#   FIND_PACKAGE (Lua REQUIRED)
 
SET (Lua_FOUND FALSE)
 
SET (LUA_INTERPRETER_TYPE "")
 
IF (LUA_USE_LUAJIT)
    SET (LUA_INTERPRETER_TYPE "LuaJIT")
    SET (LUA_LIBRARY_NAME luajit-5.1)
    SET (LUA_INCLUDE_DIRS /usr/include/luajit-2.0 /usr/local/include/luajit-2.0)
ELSE (LUA_USE_LUAJIT)
    SET (LUA_INTERPRETER_TYPE "Lua")
    SET (LUA_LIBRARY_NAME lua5.1)
    SET (LUA_INCLUDE_DIRS /usr/include/lua5.1 /usr/local/include/lua5.1)
ENDIF(LUA_USE_LUAJIT)
 
FIND_PATH (LUA_INCLUDE_DIR lua.h ${LUA_INCLUDE_DIRS} )
FIND_LIBRARY (LUA_LIBRARY NAMES ${LUA_LIBRARY_NAME} PATHS /usr/lib /usr/local/lib)
 
IF (LUA_INCLUDE_DIR AND LUA_LIBRARY)
    SET (Lua_FOUND TRUE)
ENDIF (LUA_INCLUDE_DIR AND LUA_LIBRARY)
 
IF (Lua_FOUND)
    IF (NOT Lua_FIND_QUIETLY)
        MESSAGE(STATUS "Found ${LUA_INTERPRETER_TYPE} library: ${LUA_LIBRARY}")
    ENDIF (NOT Lua_FIND_QUIETLY)
ELSE (Lua_FOUND)
   IF (Lua_FIND_REQUIRED)
       MESSAGE(FATAL_ERROR "Could not find ${LUA_INTERPRETER_TYPE}")
   ENDIF (Lua_FIND_REQUIRED)
ENDIF (Lua_FOUND)
 
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Lua  DEFAULT_MSG LUA_LIBRARY LUA_INCLUDE_DIR)
 
MARK_AS_ADVANCED ( LUA_INCLUDE_DIR LUA_LIBRARY)

* the only “downside” of using LuaJIT instead of Lua that I faced so far is that you have ensure all your wrappers actually return an integer. Otherwise LuaJIT crashes when it calls a wrapped function. But you should return an from a integer function anyways, so it just encourages better code.

Tags

code snippet: luatables simple access to lua tables from C/C++

June 5, 2012

The last two gamejams definitely convinced me that Lua is a very elegant, fast and easy to learn scripting language. Combined with the amazing LÖVE engine really cool things can happen.

When I created on my simple skeletal animation tool MeshUp, I thought that using JSON as a fileformat would be way better than XML as it is not as verbose and therefore easier to read. Also there is a nice C++ library for reading and writing JSON files.

However the syntax of JSON is actually fairly similar to Lua so I thought it would be a nice thing to have scripting powers in the model description files as it empowers you to even … script repetitive tasks!!!

The only problem was that the interface to get values from Lua into C can be a little counter intuitive as one has to interact with Lua through its stack. I do have to not here that the Lua stack is – just as the language itself – a very elegant way for passing data in and out of Lua’s virtual machine. But as said before it is not as intuitive when one wants to do simple things.

For this I hacked together a small set of functions, called luatables, that should simplify using Lua as a fileformat. There are of course various libraries already available, but I wanted a) get to know Lua a bit better and b) have a lightweight solution that does not add bloat or dependencies.

I published it under the (very permissive) zlib open-source license. You can grab it from:

Enjoy!

Tags

MeshUp!

January 11, 2012

Last week I started working on a small, yet powerful visualization tool for animations or more generally spoken for any multi-body simulations. It is based on skeletal animation and magic and is called MeshUp!.

The frames for the skeleton are defined in a JSON file (thanks to jsoncpp this was relatively easy to implement). In the same file meshes can be attached to the frames (e.g. some random monkey head to the “Head” frame, etc.) and are then moved with the head bone.

The meshes themselves are Wavefront OBJ files that can be exported by nearly every 3d content creation package. I wrote the importer in about 2 hours which surprised me. I feared that to be a lot more of a hassle.

Furthermore it finally made me play around with Quaternions a bit more. Turns out that they are not as hard and are actually quite efficient. Before that I used some matrix calculations for the rotations but with the Quaternions I basically have the same usage but about 10% performance gain (not that it would matter, but it surprised me a little). The biggest problems I had, was that in my computer animation reference book a formula for a conversion had a typo. Thanks to test driven development this was easy to debug and will not occur in the future! Yay!

Oh, also it is coordinate system agnostic. Meaning you can use whatever angle convention you like! ZYX Euler? Sure! YZX Euler? Why not? Just define the proper coordinate system and rotation order in the model file and that’s it!

I published MeshUp! at bitbucket account. You can download the source at:

https://bitbucket.org/MartinFelis/meshup

So far I havent’t decided on a license. Any suggestions?

 

Tags

Android Programming – First Try

December 30, 2011

Today I felt a bit daring and thought I’d try programming for android.

Here is the result: the NerdRomanceHelper.apk.

Here is a screenshot:

I’ve tried it, it works!

Tags

Custom Shaders and Material in Horde3D

November 15, 2011

To simplify scene management and visual effects I looked at various open-source graphic engines that I might use. I briefly looked at the usual suspects such as Ogre3D and Irrlicht until I found Horde3D, which convinced me by its simple looking API and the compiled library was much smaller than of the others. It also seemed to feature various capabilities that might be interesting (scene graph, shadow mapping) or nice to have things (picking, blur, hdr, etc.).

However being an old-school OpenGL programmer, that mostly draws simple geometries such as cubes, spheres, and similar, it is not quite the way I am used to do stuff. Furthermore, the shaders in the examples seemed much more advanced than I need for now, so I am currently trying to make things more basic. Eventually I want to use the scene graph to do some procedural animation and that I am going to do with these simple geometries. Using more sophisticated models created with blender should not be too hard once I got it running.

So far I incorporated Horde3D to my code and using assets from the example to get some experience with Horde3D and implemented a simple shader. As I had the OpenGL Superbible laying around I thought it would be nice to implement the good old Ambient-Diffuse-Specular lighting model (so far only on a per-vertex basis).

Here are some screenshots of the different steps I took:

Now I can easily specify the material in the XML-files that Horde3D is using. Also, I learned a great deal about Horde3D.

Hopefully I’ll soon be able to draw simple procedurally generated geometries and can then start to look at the animations.

Tags

Scala + LWJGL = Running Program

September 22, 2011

scala + lwjglI 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:

  1. 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.
  2. Download and install Scala from http://www.scala-lang.org/ (as of writing: 2.9.1)
  3. Create the folders “lwjglproject/lib” and “lwjglproject/src”
  4. 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)
  5. Create a source file “lwjglproject/src/lwjgl.scala” with contents from the example (also available further down)
  6. Compile the code with
    scalac -classpath ./lib/lwjgl.jar src/lwjgl.scala

    this should  give you some .class files

  7. Run the example by executing
    scala -classpath lib/lwjgl.jar -Djava.library.path=./lib Main
  8. 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 &lt;- args){
			arg match{
				case "-fullscreen" =&gt;
					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 &lt;- -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
	}
}

Tags