Blog

I write code, this blog is a dream.

2014.11.11Old openfl project, one year later, will it blend?

Two months ago I wanted to do a small update to my old game Miliworlds but I failed to install a working openfl environment and had no time to fight the system.

Tonight I decided to fix the problem.

After installing and uninstalling things and searching the web it turned out the problem came from a bad combination of haxe and hxcpp versions (Thank you IRC log):

  • haxe 3.2.0
  • hxcpp 3.1.39

I had to install github's version of hxcpp and recompile a few platforms:

haxelib git hxcpp http://github.com/HaxeFoundation/hxcpp
cd `haxelib config`
cd hxcpp/git/project
neko build.n clean
neko build.n
neko build.n android
neko build.n ios

I also had to add a -Dlime-legacy flag at the end of each command call so lime wouldn't complain about missing haxelib/lime/2,0,0-alpha,8/ndll/IPhone/liblime.iphoneos.a (I am pretty sure I can find a way to compile that but adding the -Dlime-legacy just worked so why bother:).

lime test project.xml ios -simulator -ipad -Dlime-legacy

Since the problem was due to my non-standard setup, it looks like openfl grew stabler during the year. That's good news.

2014.10.06Edukymoz 2014.10 aftershock

My vigorous education project "Edukymoz" had a huge success this week-end at the Animasia event, on the FrenchCows stand of course.

Sadly I did not count how many slaps where exactly given. I estimate (and that's a conservative estimation) that at least 130 persons tried the game during the 2 days. Hence, probably more than 5 130 3 = 1950 slaps where distributed (each error gives 3 quick slaps).

Thanks goes to all the glorious people who had the guts to try the game. They were kind and cheerful, they were fun, we all laughed a lot and so did the people who where watching them been slapped! The Animasia public was really great and I spend two fantastic hilarious days.

I may work on a V2 when FrenchCows will be invited to the next event. Two paddles, faster servo motors, more questions, customizable slap power. That would be really epic :)

2014.09.14Moving Arduino with Haxe/JS

I recently created a small Arduino prototype, controlled by a simple Quiz game, itself controlled by a Leap motion controller.

Leap -> Game -> Arduino

I really like coding games using HTML5 and CSS. I regularly create comissionned HTML5 games and nothing beat the web platform to iterate fast. The game had to be in Haxe (Javascript target).

Using the Leap javascript API is as simple as including the right script in the HTML and running Leap.loop().

Javascript then uses a Websocket to talk to the local Leap server, connected to the LEAP device.

As far as Arduino is concerned, there is a great javascript library out there to communicate with the board using the Firmata protocol : Johnny-five.

Using the Arduino IDE, install the Examples > Firmata > StandardFirmata sketch on your Arduino board and you will then been able to communicate with your board from Node.js using the serial connection.

Firmata is great : you control your board from your computer and receive sensor's values too. Moreover the Johnny-five library have quite a few helper classes to work with Led, Motor, gyro, joystick, lcd, etc.

Using some elbow grease you can even make it work with node-webkit (it requires a few fixes to make it work as expected).

Another really convenient option is to create a Google Chrome Application instead of a node-webkit one. The main difference is that you have access to the browser' Serial API and can switch to This version of Johnny five to communicate directly with the Arduino Board.

npm install browser-serialport
npm install garrows/johnny-five

Note: I had to use Browserify to merge dependencies.

The initial setup is easier and the iteration is faster, you can start your application from the command line.

google-chrome --load-and-launch-app=`pwd`

You can refresh the app with right click / Reload App.

And of course you have access to the regular Chrome developer tools.

To break the Google Chrome dependency and create universal web pages connected to physical stuff we could create a Firmata proxy program. People could install this program on their computer, connect something to their computer and then surf to a dedicated webpage to run a physical JS app. Very much like the LEAP does.

My little prototype won't be available on the web so it doesn't matter but it's a good thing to know that it would be easy to engineer :)

If you need more input or maybe a tutorial to do this kind of job drop me a word.

(And some useless photos just because you cannot talk about Arduino without showing yours:)

Circuit Circuit

2014.07.14How to use libgdx with haxe (part 2)

Follow up of previous post.

I did a few more tests and it looks like Haxe/Java doesn't support a specific feature. Using libgdx skins breaks haxe compilation. The haxe/java team is working on this and it should be fixed soon.

In the meantime, I modified libgdx code to make haxe happy. It wasn't too hard, only renaming a field in gdx/src/com/badlogic/gdx/utils/ObjectMap.java (hasNext) and recompiling the jar.

Using the modified jar as the -java-lib is all is required to generate working java code. The official libgdx/gradle project do the rest.

If you want to give it a try, you can download my modified jar on dropbox.

Just put it somewhere on your system and use it as the -java-lib jar as seen previously.

Feature wise, everything I tested seem to work. I had a few hipcups with the haxe/java support with the following things but nothing blocking:

  • importing interfaces static fields is cumbersome, remember that you have to import like this:

import com.badlogic.gdx.graphics.VertexAttributes.VertexAttributes_Usage.*;

If you encounter "is already defined in X", it means you have some extra import which is not required.

  • haxe/java does not seem to support varargs method calls, I had to create a native array to create a Material. I hope the API has alternative methods everywhere varargs are involved:

var attrs = new java.NativeArray<Attribute>(1);
attrs[0] = ColorAttribute.createDiffuse(new Color(0xE50000FF));
var material = new Material(attrs);

  • double means Float, float means Single and long means Int64, type conversion can be boring, even more when bits are involved, cast can help, for instance cast (Position | Normal) will make haxe/java works for you instead of having to call haxe.Int64.ofInt(Position | Normal) for the same result.

I did not inspect the generated java source a lot, nor did I test performances. I just hope an haxe user is not too much penalized for his choice of language compared to a native java developer :)

2014.07.05How to use libgdx with haxe

Forewords

Libgdx is a stable 2D/3D library, quite complete, multiplatform (Desktop PC/Mac/Linux, Android, iOS, HTML, Blackberry?), performant, easy to grasp and it comes with useful tools, a clean documentation and a decent community.

There are two problems: java and… well… java

I don't hate java, it's just that it doesn't reach the top 3 of my favorite languages :)

Haxe can compile to jar and java source code hence replacing java with haxe should be doable. The haxe/java support is quite new so things may break but givin a try doesn't hurt!

With the latests releases libgdx now comes with a new build/dependency system based on gradle. This tool eases many things and provides a nice and simple access to compilation tasks from the command line.

The project structure

I chose to isolate haxe from libgdx projects but you are free to customize to your needs.

mygame/
  gdx/       # libgdx content
  src/       # our haxe source code will go there
  build.hxml # our build script (could be a Makefile)

The workflow:

  • we code in haxe in the src folder
  • haxe compiles the code to java source and send it into gdx/
  • we use gradle to compile the gdx java project

So for now:

$ mkdir -p mygame/src
$ mkdir -p mygame/gdx
$ touch mygame/build.hxml

We will edit build.hxml later.

Create the gdx project

Libgdx has a setup tool which eases the creation of new projects:

Download and run gdx-setup.jar (documentation)

java -jar gdx-setup.jar

Just make sure to choose "mygame/gdx" for the destination and to point to the right path of your android-sdk if you plan to play with Android. (on macosx I downloaded the android-sdk with brewer).

Click Generate and wait a little.

Ensure that the gdx base project works

$ cd mygame/gdx
$ ./gradlew desktop:run

You should see something like that:

GDX organisation

If you are not familiar with libgdx you can take a look at their excellent wiki.

The gdx/ structure looks like this

core/
android/
desktop/
ios/
html/

Plus some project files.

Each folder is a subproject with a java launcher dedicated to one platform. The launcher initiates what's inside "core" : our game.

Note: for some reason games assets must be put into android/assets by default but you can change this editing the files desktop/build.gradle, html/src/me/labe/mygame/GdxDefinition.gwt.xml, html/src/me/labe/mygame/GdxDefinitionSuperdev.gwt.xml, ios/robovm.xml (fgrep -R "android/assets" * is you friend).

Gradle is a dependency/build system, some interesting build tasks:

$ cd gdx
$ ./gradlew desktop:run
$ ./gradlew android:build android:installDebug android:run
$ ./gradlew ios:build ios:launchIPhoneSimulator

And many other things we don't care about right now :)

So now that you have everything running (use libgdx documentation to fix things until the default project works on your system) we can start using haxe.

MyGame.hx file

Gdx-setup created core/src/me/labe/mygame/MyGame.java for us, it looks like this:

package me.labe.mygame;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;

public class MyGame extends ApplicationAdapter {
	SpriteBatch batch;
	Texture img;

	@Override
	public void create () {
		batch = new SpriteBatch();
		img = new Texture("badlogic.jpg");
	}

	@Override
	public void render () {
		Gdx.gl.glClearColor(1, 0, 0, 1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
		batch.begin();
		batch.draw(img, 0, 0);
		batch.end();
	}
}

This is the regular entry point for our game so we want it to be written in haxe.

Here's the haxe equivalent: src/me/labe/MyGame.hx

  package me.labe.mygame;

  import com.badlogic.gdx.ApplicationAdapter;
  import com.badlogic.gdx.Gdx;
  import com.badlogic.gdx.graphics.GL20;
  // this is important, in haxe you cannot access java interfaces' static members,
  // they are hidden inside a subclass CLASSNAME_Statics, must know trick, hope
  // it will be fixed soon if not already fixed.
  import com.badlogic.gdx.graphics.GL20.GL20_Statics.*;
  import com.badlogic.gdx.graphics.Texture;
  import com.badlogic.gdx.graphics.g2d.SpriteBatch;

  class MyGame extends ApplicationAdapter {
    var batch : SpriteBatch;
    var img : Texture;

    @:overload
    public function create() {
      batch = new SpriteBatch();
      img = new Texture("badlogic.jpg");
    }

    @:overload
    public function render() {
      Gdx.gl.glClearColor(1, 0, 0, 1);
      Gdx.gl.glClear(GL_COLOR_BUFFER_BIT);
      batch.begin();
      // we center the image so we know for sure OUR code is in charge
      batch.draw(
        img,
        (Gdx.graphics.getWidth() - img.getWidth()) / 2,
        (Gdx.graphics.getHeight() - img.getHeight()) / 2
      );
      batch.end();
    }
  }

We want haxe to compile this to java and replace the original gdx file. It's quite easy.

build.hxml

Our first iteration looks like this:

-D no-compilation
-cp src
-java gdx/core
me.labe.mygame.MyGame

We don't want to compile jar files, we just want java source. Our haxe code resides in the src folder. We send the result into gdx/core as expected. Our entry point is me.labe.mygame.MyGame.

If you try to run this build script with haxe you will get an error:

src/me/labe/mygame/MyGame.hx:3: characters 7-42 : Class not found : com.badlogic.gdx.ApplicationAdapter

That's because haxe doesn't know about gdx yet, we have to tell it about the .jar files we are using.

Link the libs

Since we compiled the gdx project, the jar files should already be somewhere on our system.

We are looking for gdx.jar, gradle uses ivy for its dependencies. It caches things inside the ~/.ivy2 folder on OSX.

With OSX or linux you can find your libs with a command like this:

$ find ~/ -name "*.jar" | grep gdx.jar
...
/Users/lbedubourg/.ivy2/cache/com.badlogicgames.gdx/gdx/jars/gdx-1.2.0.jar
...

As seen in the above gdx-setup screenshot, 1.2.0 is the right version, we can use this full path, create a symlink, even copy the file, whatever you prefer. I'll use the full path for this tutorial.

We just have to add the reference to the lib to our build.hxml:

-D no-compilation
-cp src
-java gdx/core
-java-lib /Users/lbedubourg/.ivy2/cache/com.badlogicgames.gdx/gdx/jars/gdx-1.2.0.jar
me.labe.mygame.MyGame

And voila, haxe build.hxml will generate your java code.

Enjoy

Running our code using gradle is just a question of going into the gdx folder and running ./gradlew with the right arguments.

$ cd gdx
$ ./gradlew desktop:run

You will certainly want to include the gradlew call into your build.hxml or your Makefile or whatever you are using to manage your build process.

For instance to compile and run the desktop version after each compilation you can edit the build.hxml file:

-D no-compilation
-cp src
-java gdx/core
-java-lib /Users/lbedubourg/.ivy2/cache/com.badlogicgames.gdx/gdx/jars/gdx-1.2.0.jar
me.labe.mygame.MyGame

--next
-cmd cd gdx
-cmd ./gradlew desktop:run

Next

You'll want to learn a little bit about gradle.

  • libgdx uses gradlew (a gradle wrapper) and on my macbook using the wrapper as instructed in this tutorial was slower than using my localy installed gradle (version 1.12).
  • using --offline can save you a few networking roundtrip and one or two seconds while starting gradle
  • libgdx requires old gradle, things may improve when they will switch gradle v2.0, maybe :)

HTML support doesn't work out of the box.

Libgdx relies on GWT to generate javascript code, you will have to edit gdx/core/src/MyGame.gwt.xml to add the following lines (so GWT will find haxe stuff).

<source path="haxe"/>
<source path="haxe/lang"/>
<source path="haxe/root"/>
<source path="_Array"/>

But then gwt will complain about java.lang.reflect.* which is not supported by GWT… This problem might be fixed by this pre-processor but I don't have the time to investigate more.

Replacing platforms launchers with haxe should also possible, you will have to create different targets and add the related jar file as -java-lib.

You can use libgdx extensions, don't forget to add -java-lib to make haxe happy.

I just made it work yesterday and did nothing more than what is written here, moreover haxe/java support is quite new, so bugs may arise if you try to use libgdx with haxe to produce an entire game.

Haxe is great because you can reuse the hard work of others. Of course having a great multiplatform 2d/3d api entirely written in haxe would be awesome but in the meantime, using libgdx could be a great alternative to adobe air. It's up to you to decide, you now have one more choice!

Best regards, Laurent

EDIT: As written, haxe/java support is quite recent and a few bugs needs to be resolved before we can use all of GDX features from haxe. However the bases are there and I am pretty sure the haxe/java team will be happy to clean edge cases.

More in part 2.