Haxe(ヘックス)という独特な世界観を持つ言語があります。その最大の特徴は、Haxeでプログラムを書くと、JavaScript、C#、Java、Python、PHPなど様々なプログラミング言語のソースコードやバイトコードに変換できるという点にあります。まさに怪盗100面相のように、その姿を変える不思議系の言語なのです。Flash由来のHaxeはその特徴を活かしてゲーム開発やいろいろな場面で使われています。今回は、Haxeの魅力に迫ってみます。

  • Flash由来で複数言語に変換できるHaxeのWebサイト

    Flash由来で複数言語に変換できるHaxeのWebサイト

Haxeとは?

HaxeはAdobe Flashのスクリプト言語だったActionScript 3によく似たプログラミング言語です。オープンソースで開発されており、作成したプログラムを、さまざまなプラットフォームで動かすことができます。最新版では、iOS、Android、Webブラウザ、Neko、Node.js、C++、Python、C#、PHP、Java、Luaなど様々な環境に対応しています。

なお、Flashとは残念ながら2020年にサポートが終了したWebアニメの実行環境で、2010年まではWebアニメの実行環境として幅広く使われていました。ちなみに、なぜFlashの話をしたのかと言えば、HaxeがFlash由来の技術なのです。

そもそも、Haxeを開発したのは、Shiro Gamesというフランスのゲーム会社のCEOをしているNicolas Cannasse氏です。Haxeを公開する前には、MTASCと言うFlashファイルを生成するActionScriptのコンパイラを開発していたことでも有名です。本家Flashよりも高速にFlashファイルを生成できたので筆者も使っていました。そして、彼がMTASCの次に開発したのがHaxeです。

Haxeも当初のバージョンでは、Flashの生成が主なターゲットでした。それでも、当時からFlashファイルの生成だけでなく、独自のNeko仮想マシン上でプログラムを動かせる仕組みを提供していました。その後、JavaScript、C++、PHPなど、次々と変換対象となるプログラミング言語を増やしていきました。Haxeで記述したプログラムは、さまざまなOS、さまざまな言語で動かせるのがメリットです。

また、このように、HaxeはFlash由来の言語であるため、Flashが終了してしまった現在でも、そこで培ったさまざまなWebアニメの技術を活かすことができます。かつて、Flashを使って多くのゲームやWebアニメが作成されましたので、そうした資産を活用したいという場合にHaxeが役立ちます。なお、その場合、OpenFLというライブラリを使うと、Flashと互換性のあるAPIを利用してアプリを作成できるようになっています。

  • HaxeとOpenFLを使うとFlashと互換性のあるAPIが利用可能

    HaxeとOpenFLを使うとFlashと互換性のあるAPIが利用可能

Haxeで書いたプログラムをいろいろな言語に変換してみよう

それでは、実際にHaxeを使ってみましょう。今回は、今年2022年3月にリリースされたバージョン4.2.5を利用してみます。Haxeのインストールをインストールするには、まず、Haxeのダウンロードページを開きます。そして、OSごとにインストーラーをダウンロードします。

なお、この時、Binariesを選ぶと、Haxeのバイナリが入ったZIPファイルがダウンロードされますが、この場合には別途NekoVMのインストールも必要になるため、Installerを使うのがお勧めです。

インストールが完了したら、一番簡単なプログラムを記述して実行してみましょう。以下のプログラムを「Hello.hx」という名前で保存します。

class Hello {
    static public function main() {
        trace("Hello World");
    }
}

そして、コマンドライン(Windowsならコマンドプロンプト、macOSならターミナル.app)で「haxe --main Hello --interp」とコマンドを実行すると、Haxeのインタプリタでプログラムが実行されます。

  • Haxeのインタプリタ上で実行したところ

    Haxeのインタプリタ上で実行したところ

次に、JavaScriptやPythonに変換してみたいと思います。この場合、以下のようなコマンドを実行します。するとJavaScriptファイル「Hello.js」、Pythonファイル「Hello.py」が生成されます。

# JavaSctiptに変換
haxe --main Hello --js Hello.js
# Pythonに変換
haxe --main Hello --python Hello.py

なお、JavaScriptに変換した後、JavaScriptの実行環境のNode.jsで実行してみました。すると、先ほど同じように実行されました。プログラムを何も変えることなく、JavaScriptのコードが生成されて同じように実行できました。

  • JavaScriptに変換してから実行してみたところ

    JavaScriptに変換してから実行してみたところ

FizzBuzz問題を解いてみよう

さて、本コラムでは、毎回、さまざまなプログラミング言語を利用してFizzBuzz問題を解いています。今回も、Haxeを使って問題を解いてみましょう。FizzBuzz問題とは次のようなプログラムです。

1から100までの数を出力するプログラムを書いてください。ただし、3の倍数のときは数の代わりに「Fizz」と、5の倍数のときは「Buzz」と表示してください。3と5の倍数の時は「FizzBuzz」と表示してください。

せっかくなので、HaxeとOpenFLを使って、Flash風にFizzBuzzを表示させようと思います。OpenFLをインストールするには、Haxeをインストールした状態で以下のコマンドを実行します。

haxelib install openfl
haxelib run openfl setup

すると、openflというコマンドが利用できるようになるので、以下のコマンドを実行して、ひな形となるプロジェクトを生成します。

openfl create project FizzBuzz

すると、Source/Main.hxというファイルが生成されているので、このファイルを以下のように書き換えましょう。

package;
import openfl.display.Sprite;
import openfl.text.TextField;
import openfl.text.TextFormat;
class Main extends Sprite
{
    var tiles:Array<TextField> = [];
    public function new()
    {
        super();
        // 100回繰り返す --- (*1)
        var i:Int;
        for (i in 0...100) {
            // TextFieldの配置位置を計算
            var col = Math.floor(i / 20);
            var row = i % 20;
            // FizzBuzzを求める --- (*2)
            var v = getFizzBuzz(i + 1);
            // TextFieldを生成して配置 --- (*3)
            var tf:TextField = new TextField();
            tf.defaultTextFormat = new TextFormat("Arial", 20);
            tf.x = col * 150 + 10;
            tf.y = row * 24 + 10;
            tf.text = v;
            tf.textColor = (v.length > 3) ? 0xFF0000 : 0xFF;
            tiles[i] = tf;
            addChild(tf);
        }
    }
    // FizzBuzzを求める --- (*4)
    private function getFizzBuzz(i:Int):String {
        if (i % 3 == 0 && i % 5 == 0) return "FizzBuzz";
        if (i % 3 == 0) return "Fizz";
        if (i % 5 == 0) return "Buzz";
        return Std.string(i);
    }
}

そして、以下のコマンドを実行します。

openfl test neko

すると、Neko仮想マシンを使ってFizzBuzzの結果が表示されます。

  • FizzBuzzを実行したところ

    FizzBuzzを実行したところ

なお、『openfl test html5』というコマンドを実行すると、JavaScriptが生成されてブラウザで実行されます。ローカルサーバーも一緒に起動するので便利です。

  • ブラウザでFizzBuzzが実行されたところ

    ブラウザでFizzBuzzが実行されたところ

プログラムを確認してみましょう。このプログラムでは、単に画面にテキストを表示するのではなく、TextFieldと呼ばれるテキスト表示オブジェクトを作成し、それを適当な位置に配置するようにしてみました。

(*1)の部分で100回繰り返しを記述します。(*2)でFizzBuzzの結果を求めます。そして、(*3)以降の部分でTextFieldを作成して、適当な位置に配置します。それから、(*4)のgetFizzBuzz関数でFizzBuzz問題を解いて答えを返します。

プログラムを見てすぐ気付くことですが、変数宣言を行うのに『var 変数名:型名』の書式で記述します。Haxeは静的型付け言語であり、変数を利用する際は明示的な型の指定が必要です。それでも型推論の機能もあるため、明らかに整数型(Int)である場合など指定の省略が可能です。

なお、静的型付けを持つ言語なので、統合開発環境(IDE)を導入することで、強力なコード補完を活用できます。今回、Visual Studio CodeにHaxeの拡張をインストールしてみましたが、サクサク補完できて気持ちよくプログラムを書くことができました。

Neko仮想マシンについて

ところで面白いのが、Haxeのプログラムを実行する独自の仮想マシンはNekoと呼ばれています。これはHaxeが生成するバイトコードを実行できる仮想マシンです。Haxeのライブラリを管理するHaxelibを動かすのにもNekoが利用されています。

なお、Haxeとは独立したWebサイトがあり、Nekoのロゴマークには猫の絵が描かれており、日本語から取られていると思われます。

  • Haxeを実行する仮想マシンNekoのWebサイト

    Haxeを実行する仮想マシンNekoのWebサイト

まとめ

以上、今回はさまざまなプログラミング言語のソースコードやバイトコードを生成するHaxeについて紹介しました。Flash由来の技術なので、マルチプラットフォーム向けのゲーム開発などで威力を発揮することでしょう。

また、複数言語のソースコードを出力できるという利点があるため、異なる環境で動作するアプリを作る場合に、アプリの中で使うアルゴリズムやメソッドを統一したい場面でも役立つでしょう。

自由型プログラマー。くじらはんどにて、プログラミングの楽しさを伝える活動をしている。代表作に、日本語プログラミング言語「なでしこ」 、テキスト音楽「サクラ」など。2001年オンラインソフト大賞入賞、2004年度未踏ユース スーパークリエータ認定、2010年 OSS貢献者章受賞。技術書も多く執筆している。直近では、「シゴトがはかどる Python自動処理の教科書(マイナビ出版)」「すぐに使える!業務で実践できる! PythonによるAI・機械学習・深層学習アプリのつくり方 TensorFlow2対応(ソシム)」「マンガでざっくり学ぶPython(マイナビ出版)」など。