Haxe+GulpでFlashのコンパイルと動作確認のためのリロードを自動でやっていく。

数年ぶりにFlashでゲームを作っています。(普通のブロック崩しです) http://bb.mmmpa.net/

以前はFlashBuilderで作業していましたので自動でデバッガ起動などをしてくれていましたが、いまはDebian+Haxe+IntelliJで作業しているため、サッと動作確認できるのがChromeしかありません。

そんななかで、保存ごとにコンパイル、新しいウィンドウやタブが次々と開かないようにして、確認したいというのがモチベーションです。

コンパイル

まずgulpで*.hxを監視してコンパイルを行います。

これはgulp-watchとgulp-shellで単純に行えます。

ソースを監視してコンパイル。

srcs = '../src/**/*.hx'

watch(srcs).on 'change', (path) ->
    gulp.src path
      .pipe plumber()
      .pipe shell([
        'echo '
        'echo building'
        'haxe "compile.hxml"'
        'echo built'
      ], {}
      )

リロード

単純に表示用のHTMLをブラウザで開くと、あたらしいタブがどんどん開いてしまいます。

コマンドラインからブラウザ内を操作する手段をみつけられなかったため、JavaScriptでなんとかします。

コンパイル後のファイルを監視し、コンパイルが済み次第、livereloadでブラウザにリロード通知を行います。

まずFlash表示用のHTMLには、リロード通知を受けとるためのコードを埋めこみます。

<script src="http://localhost:35729/livereload.js"></script>

gulpでlivereloadサーバーを起動。

gulp.task 'default', ->
  livereload.listen()

コンパイル後のファイルを監視してリロード通知。

swf = path.join(__dirname, '../export/game.swf')

watch(swf).on 'change', (path) ->
    gulp.src swf
      .pipe livereload()

一連のファイル

コンパイル時には何度かのファイル書き換えが発生するので、コンパイル結果のファイルを直接監視すると、複数回のリロード通知が飛んでしまいます。

コンパイルは別名で行い、終わった後に監視対象ファイルにリネームするのがよいでしょう。

以下が一連のgulpfile.coffeeです。

gulp = require 'gulp'
watch = require 'gulp-watch'
shell = require 'gulp-shell'
plumber = require 'gulp-plumber'
livereload = require 'gulp-livereload'
path = require 'path'

srcs = '../src/**/*.hx'
swf = path.join(__dirname, '../export/game.swf')

gulp.task 'default', ->
  livereload.listen()

  watch(srcs).on 'change', (path) ->
    gulp.src path
      .pipe plumber()
      .pipe shell([
        'echo '
        'echo building'
        'haxe "compile.hxml"'
        'echo built'
        'cp -f ../export/built.swf ../export/game.swf'
      ], {}
      )

  watch(swf).on 'change', (path) ->
    gulp.src swf
      .pipe livereload()

ターミナルでtraceをみる

Haxeはデフォルトでtraceメソッドの結果を画面内に描画してくれますが、読みづらいのでターミナルに表示します。

まずtraceの挙動をいつものやつに変えます。

haxeクラスの任意の場所に以下を記述。

#if (flash9 || flash10)
    haxe.Log.trace = function(v, ?pos) {
      untyped __global__["trace"](pos.className + "#" + pos.methodName + "(" + pos.lineNumber + "):", v);
    }
#elseif flash
    haxe.Log.trace = function(v, ?pos) {
      flash.Lib.trace(pos.className + "#" + pos.methodName + "(" + pos.lineNumber + "): " + v);
    }
#end

~/mm.cfgを編集して(なければ作成します)ロギングを有効にします。

ErrorReportingEnable=1
TraceOutputFileEnable=1

~/.macromedia/Flash_Player/Logs/flashlog.txt に書きだされるという話でしたが見つかりませんでした。

findしたところ /home/user/.config/google-chrome/Default/Pepper Data/Shockwave Flash/WritableRoot/Logs/flashlog.txt にありましたので、これをtail -fなどで表示しておきます。

tail -f "/home/user/.config/google-chrome/Default/Pepper Data/Shockwave Flash/WritableRoot/Logs/flashlog.txt"

ただ、このログは全てのFlashで共有しているので、たとえばAmazonMusicをブラウザで使っているとログがずんどこ流されていって、情報取得手段として機能しません。

我慢するか別の方法で聞きましょう。

現状

作業初期は上記のようにHaxeにおまかせでswfへとコンパイルしていましたが、現在はコンパイルターゲットをAS3にして、最新のAIR SDKでコンパイルしています。

Android上での動作は確認できたので、いずれは配布できるようにしたいなという感じです。