Monday, July 29, 2013

Haxe 3, OpenFL, Native extensions

It's been a while since I wrote anything and a lot has happened since the last post, to recap, I went from C# to AS3 to Haxe.

Haxe is a cross platform language that allows you to create mobile/desktop/web applications (Games!) from a single code base. The premise of writing once play everywhere has been pushed a lot in the latest years, we have Unity (paid), Xamarin (paid), Stencyl (paid/free), Adobe Air(free but meh), Cocos2dx (free), etc.

They all have their ups and downs, but then we have Haxe. It is completely free and very easy to use if you have experience with Java/AS3/C#.

Haxe is great, just like C# is great but C# wouldn't have been that good to me if it wasn't for the right SDK, back in the day XNA was the most amazing tool for programmers like me that were just getting into game development, it handled all the complicated stuff and left us with the only task to make a game, Haxe has its own XNA and it is called OpenFL (before that there was NME, by the same creator).

OpenFL simulates the Flash API and more. Besides having all the necessary elements to create a game with OpenFL it also allows for extensions to native libraries, this is extremely important when targeting mobile platforms since we need to access to these native libraries to implement things such as in app purchases, ads, social media, etc. Without those elements we could not monetize our works.

The biggest problem I have encountered is the lack of documentation or examples online on how to implement things, there are some but sometimes they tend to be outdated (maybe this will be outdated when you read it) or are overly complicated to follow, in any case you must look for the answers a lot in order to find something (also a lot of trial and error, don't get discouraged!)

I would like to give you an example based on this blog about chartboost

That blog post put me in the right direction to figure out how to add a native extension to android, and this is what I came up with.

First we create a new OpenFL project (I am going to assume you have installed FlashDevelop, the latest Haxe 3, and the latest OpenFL, if you havent take a look at this: FlashDevelop and this Haxe/OpenFL )

To create an openfl project you are going to need to open the command prompt, navigate to a destination folder you want to use (I created my project in the desktop so I went to cd desktop) and finally type openfl create project "project name" hit enter and you created an openFL project. If you open the project in FlashDevelop and hit run you will be greeted with an empty window.

The next step would be to acquire the native library, head over to Here and download the SDK for android, also register for an account to obtain your "App id" and "App signature", save this information somewhere, we are going to use it later on. Now we need to create a folder in your project that will contain all your libraries, you can create it anywhere within the project but for the purpose of clarity we are going to create a new folder in the Assets folder, name it "libs" (lower case) and add the charboost.jar file to it.

so now you should have:

|Test
. . |Assets
. . . . |nme.svg
. . . . |libs
. . . . . . |chartboost.jar
. . |Source
. . . . |Main.hx
. . |project.xml


Great so, the next step would be to tell your project that you have an external jar you want to compile for android. For this you are going to need to open the "project.xml" file, in there you can see some information that defines your project, think of it has the manager that holds the entire thing together.

add the following to it:

<template path="Assets/libs/chartboost.jar" rename="libs/chartboost.jar" if="android"/>

Let me explain what that will do, first it will locate the chartboost.jar file in your project, then when compiling for android only, it will add the charboost.jar file to your libs folder (created by the compiler when building for android), this is all you need in order to successfully add a library to android, next step would be how to use it.

To be able to use the library we first need to modify the MainActivity template that gets created when you build for android. But first in order to be able to build for android you are going to need a device or an emulator, setting this up is not that complicated but that is beyond the scope of this tutorial, after you have your emulator/device ready go ahead and build for android, there are 2 ways of doing this, either by selecting android in FlashDevelop as the target or by using the command prompt, navigate to your project folder where the project.xml is and type openfl test android -debug this will build the project for android.

once this is done building it would have created a bunch of files and folders, you should now have

|Test
. . |Assets
. . . . |nme.svg
. . . . |libs
. . . . . . |chartboost.jar
. . |Export
. . . . |android
. . . . . . |bin
. . . . . . . . |bin +
. . . . . . . . |gen +
. . . . . . . . |libs
. . . . . . . . . . |armeabi +
. . . . . . . . . . |chartboost.jar
. . . . . . . . |res +
. . . . . . . . |src
. . . . . . . . . . |com
. . . . . . . . . . . . |example
. . . . . . . . . . . . . . |test
. . . . . . . . . . . . . . . . |MainActivity.java
. . . . . . . . |AndroidManifest.xml
. . . . . . . . |build.xml
. . . . . . . . |default.properties
. . . . . . |haxe +
. . |Source
. . . . |Main.hx
. . |project.xml

notice that your charboost.jar file was added to the android libs and that's exactly what we wanted. Now we are going to need to create a folder for our java code, do this directly in the main project folder "Test", call it "java" so you will have

|Test
. . |Assets +
. . |Export +
. . |Source +
. . |java
. . |project.xml

go to the Export/android/bin/src/com/example/test and copy the MainActivity.java, paste it into your new java folder so we now have:

|Test
. . |Assets +
. . |Export +
. . |Source +
. . |java
. . . . |MainActivity.java
. . |project.xml

Double click the main activity in your java folder to open it, we are going to edit it now, add the following code (straight from the blog I quoted earlier):

package ::APP_PACKAGE::;

import android.os.Bundle;
import com.chartboost.sdk.*;

public class MainActivity extends org.haxe.nme.GameActivity
{
 private Chartboost cb;
 
 @Override
  protected void onCreate(Bundle state)
 {
        super.onCreate(state);   
  
        // Configure Chartboost
  this.cb = Chartboost.sharedChartboost();
  String appId = "YOUR_APP_ID";
  String appSignature = "YOUR_APP_SIGNATURE";
  this.cb.onCreate(this, appId, appSignature, null);
 
  // Notify the beginning of a user session
  this.cb.startSession();

  // Show an interstitial
  this.cb.showInterstitial();

  }
 
 @Override
 protected void onStart() {
  super.onStart();

  this.cb.onStart(this);
 }

 @Override
 protected void onStop() {
  super.onStop();

  this.cb.onStop(this);
 }

 @Override
 protected void onDestroy() {
  super.onDestroy();

  this.cb.onDestroy(this);
 }

 @Override
 public void onBackPressed() {

  // If an interstitial is on screen, close it. Otherwise continue as normal.
  if (this.cb.onBackPressed())
   return;
  else
   super.onBackPressed();
 }
}


Remember to change the APP_ID and the APP_SIGNATURE for the correct information you obtained when creating your charboost account.

Okay so now we have our own MainActivity, but the compiler doesn't know that it has to use this one instead of the one that gets created by default (the template one), so to fix this we need to go to the project.xml once again and tell it to override the template with our own one.

Open project.xml and add the following:

<template path="java/MainActivity.java" rename="src/com/example/test/MainActivity.java" />

So what we doing here is telling the project that it is going to be looking for a file inside the folder "java" and going to replace the file src/com/example/test/MainActivity.java with it (this is the path relative to the android folder in the export, you can always check the folder name by building the android template or by checking your package name in the project.xml description at the top)

If build that and run you will see charboost working in your emulator or device.

I hope this helped you, if you have question don't hesitate in emailing or replying to this post. Best of luck in your development!

3 comments:

  1. Quite informative! Big thanks for your great post on the topic, specially with lack of examples, would you write another post about windows extensions for openfl? I really need to access a native dll that would read hard disk serial number, your way of writing is very easy to follow, any help for using dlls in windows with openfl?

    Big thanks:)

    ReplyDelete
    Replies
    1. wow, I am very sorry for getting back at you so late! I actually stopped doing this kind of development, plus I am also not familiar with how to do what you need to do, but if you have some way of doing it with c++ then it should be pretty straightforward to implement them using the haxe to c++ interface.

      best of luck.

      Delete
  2. Wonderful! Thank you! Precious information!

    ReplyDelete