Window Athletic の仕組み (その2)

前回 に引き続き Window Athletic の紹介です。 今回は、プロ生ちゃんのテーマを構成するファイルの説明と、テーマを駆動する Lua スクリプトの解説です。

pronama_screenshot

まず、テーマファイルは、以下のファイル群から構成されます。

  • README.txt
  • COPYING.txt
  • logo.png
  • events.lua
  • resource.yaml
  • 画像ファイルとか

テーマファイルとは、これらのファイルを Zip (のような) 圧縮したものになっています。
(Zip のような 圧縮、という表現になる理由は、「zlib 使って圧縮まわりを実装したんだけど、途中で手を抜いたせいで既存の Zip ツールでは展開できないから」 です。 察して頂けると助かります)
(11/28 追記: zip コマンドが扱えるようになりました!)

それぞれのファイルについて簡単に説明すると、README.txt, COPYING.txt, logo.png は、アプリのテーマ変更フォームで表示されるデータになっています。 また、resource.yaml には利用する画像ファイル名や、画像ファイルをどう組み合わせて 1つのセルにするか、という定義がなされています。

resource.yaml の抜粋。(全文へのリンクは、こちら)

- Image:
  - Background: background.png
  - Parts:
      left_0: [ 01-1.png, +16+0 ]
      left_1: [ 01-2.png, +16+0 ]
      left_2: [ 01-3.png, +16+0 ]

そして events.lua には、アプリから定期的に呼び出される関数などが定義されていて、この Lua スクリプトで、マスコット画像をどの位置に、どの画像で表示するか、といったことを制御しています。 以下では、この events.lua について具体的に説明していきます。
events.lua の API については、このページ にドキュメントがあります。

events.lua の役割は、アプリから「これの処理をしてね」っていう依頼が来た時に、それをこなすことです。 具体的には、以下の関数がアプリ側から呼び出されます。

  • initialize_theme() … テーマが読み出された時に1回だけ呼び出される関数です。
  • window_rects_changed() … デスクトップ上のウィンドウの位置や大きさが変更されたら呼び出される関数です。
  • add_actor(actor) … マスコットが追加されたときに呼び出される関数です。マスコッとの初期化などを行います。
  • remove_actor(actor) … マスコットが削除されるときに呼び出される関数です。
  • update_actor(actor) … マスコット毎に 25 msec 間隔で呼び出される関数です。 ここでマスコット位置や画像の更新を指示します。 この関数の戻り値で false を返すことでマスコットの削除を指示します。 (false を返すことで、引き続き remove_actor() が呼び出されます)

プロ生ちゃんのテーマの場合だと、各関数の役割は、以下のようになります。

  • initialize_theme() … 乱数シードの初期化。
  • window_rects_changed() … ウィンドウ情報から、地面とみなす直線を計算する。
  • add_actor(actor) … 新たなプロ生ちゃん生成の処理を行う。
  • remove_actor(actor) … 特に何もしていない。
  • update_actor(actor) … プロ生ちゃんの足元に地面があるかを判定して、落下させたり移動させたりする。 プロ生ちゃんが画面外まで移動したら false を返してプロ生ちゃんを削除する。

events.lua の全文は このリンク になります。 このスクリプトを修正して pronama.dat を作り直すと、テーマの挙動が変更できます。

最後に events.lua において注意するべき点を、2点ほど説明します。

  1. events.lua は、マスコットが作られる毎に読み込まれる。
  2. マスコット(character) 毎のデータは character:set_data(), character:data() を用いて管理する。
マスコット(character) 毎のデータは character:set_data(), character:data() を用いて管理する。

マスコットのデータを保存するために、add_character(), remove_character(), update_character() の引数に渡される character を用います。 character:set_data(key, value), data = character:data(key) といった使い方ができます。 set_data(), data() では文字しか扱えないので、数値を扱う場合には文字に変換してから処理する必要があります。

-- 文字データを保存したり読み出したりする場合
character:set_data('state', 'falling')
state = character:data('state')
数値データを保存したり読み出したりする場合
character:set_data('x', "" .. x)
x = character:data('x') + 0

ここまでで、Window Athletic の簡単な説明はおしまいになります。

何か不明な点があれば、質問して頂ければ追記などいたしますので、コメントをお願いします。