3.スクリプトの基本


Mitaka Plusのスクリプト作成にはLua言語を利用します。 Luaについて詳細は公式ウェブサイト(英語)、およびこちらのリファレンスマニュアル(日本語)を参照してください。 ここではLuaの基本的な使い方について簡単に説明します。

スクリプトの例

以下がMitaka Plusでの実際のスクリプトの例になります。

-- 時刻表示・恒星ラベル表示の切り替え
function toggleLabels()

  flag = false;
  if (not Time.timeInfo) or (not Stars.labels) then
    flag = true;
  end

  Time.timeInfo = flag;
  Stars.labels = flag;

end

基本

大文字・小文字を区別します。文末には習慣的に;を付けましょう(実際には無くても問題ありません)。

コメント

--以下行末まで、または-[[〜]]で囲んだ部分はコメントとして無視されます。

数値

スクリプト内では下記のように数値を記述します。

  1.0 -- 実数1.0を表します
  1.5e2 -- 150を表します

文字列

スクリプト内では以下のように""または''で囲んで文字列を記述します。

  "test"
  'test'
  "hello\nworld" -- \nは改行を表します

演算

スクリプトでは以下のように四則演算を記述します。

  A+B -- AとBの加算
  A-B -- AとBの減算
  A*B -- AとBの乗算
  A/B -- AとBの除算
  A%B -- AをBで割った余り
  A^B -- AとBの累乗
  -A  -- 符号の反転
  A..B -- AとBを文字列として連結

変数

変数名はアルファベットから始まり、アルファベットまたは数字、_で構成される名前を付けることができます。 変数には真偽(trueかfalse)、数値(整数、実数)、文字列、テーブル(配列)、関数、オブジェクトなどを代入できます。

  a = true; --aに真を代入
  b = 1.5; --bに実数1.5を代入
  c = "test"; -- cに文字列testを代入

無効値

変数の値がnilの場合、その変数は未定義であることを意味します。逆に変数を破棄したい場合は変数にnilを代入します。

  a = nil; --変数aを破棄

値の変換

数値から文字列への変換にはtostring()関数を、文字列から数値への変換にはtonumber()関数を利用します。書式付で文字列に変換するにはstring.format()関数を利用します。

  a = tostring(1.5); -- aに文字列"1.5"を代入
  b = tonumber("1.5"); -- bに数値1.5を代入
  c = string.format("%d, %d, %d", 0, 1, 2); -- 書式付きで変換。詳細は標準ライブラリを参照してください

テーブル(配列)

一つの変数に複数の値を割り当てたテーブル(他の言語では配列、または連想配列と呼ばれます)を作成することができます。

  a = {};          -- 空のテーブルの作成
  a = { 1, 2, 3 }; -- テーブルの作成
  b = a[1];        -- bにテーブルaのひとつ目の要素1を代入。ひとつ目の要素を表すのはa[0]ではないことに注意
  a[1] = 1.5;      -- テーブルaのひとつ目の要素として1.5を代入
  a["one"] = 1.5;  -- 配列のキーとして文字列"one"を利用

テーブル内の全要素についての処理は以下のように記述できます。

  key = nil;
  while true do             -- 無限ループ
    key = next(<tbl>, key); -- 次の要素値をkeyに代入
    if key == nil then      -- テーブルの末端を超えたら繰り返し終了
      break;
    end
  print(key);               -- 要素値を出力
  end

条件式

if文、while文などに使う、真偽(true, false)を表す条件式は以下のように記述します。

  A==B -- AとBが等しい
  A>B  -- AはBより大きい
  A<B  -- AはBより小さい
  A>=B -- AはB以上
  A<=B -- AはB以下

条件式の否定は以下のように記述します。

  A~=B
  not A==B

複数の条件式は以下のように記述します。

  A==B and A==C -- AとBおよびAとCが等しい
  A==B or A==C  -- AとBまたはAとCが等しい

なお、文字列と数値は一致しません。つまり、1.0と"1.0"は異なります。

条件分岐

条件によって処理内容を変えるには以下のようにif文を記述します。

  if (条件式1) then
    条件式1が真の場合の処理
  elseif (条件式2) then
    条件式2が真の場合の処理
  else
    条件式1でも条件式2も偽の場合
  end
  -- if文の例
  if a==1 then
    print("a is 1.");
  else
    print("a is not 1.");
  end

繰り返し処理

条件を満たすまで繰り返し同じ処理をさせるには以下のようにwhile文、repeat文またはfor文として記述します。

  while 条件式 do
    条件式が真の場合に繰り返す処理
  end
  repeat
    -- 条件式が真の場合に繰り返す処理
  until 条件式
  for i=0, 10, 2 do
    -- iは0から2づつ10になるまで増加、その間繰り返す処理
    -- (3つめの増分2は省略できます)
  end
  -- while文の例
  count = 0;
  while count<5 do
    print("count is less than 5.");
    count = count+1;
  end

繰り返し処理中に break; を実行すると繰り返し処理から抜けて繰り返しの次の行にジャンプします。

  -- breakの例
  count = 0;
  while true do -- 無限ループ
    if count>=5 then
      break;
    end
    count = count+1;
  end

関数

一連の処理を関数としてまとめると、同じ処理を何度も実行したりスクリプトを読みやすく記述するのに便利です。関数はfunctionに続けて関数名、処理内容を記述し、endで囲みます。関数名に続けて、関数に渡す値(引数)を複数個定義できます。また、関数内から値を返す(返値)場合はreturnに続けて返したい値を記述します。関数からは複数の値を返すこともできます。

  -- 関数test()の定義
  function test()
    処理内容
  end
  -- 関数test()の実行
  test();
  -- 引数、返値付きの関数test2()の定義。ここでの引数aは関数外では利用できません。
  function test2(a)
    return a + 2;
  end
  b = test2(1.2); -- bに関数の実行結果3.2を代入
  --複数の返値を返す関数test3()の定義。
  function test3()
    return 1, 2;
  end
  a, b, c = test3(); -- aに1、bに2を代入。返値に対応しないcの値は不変

ローカル変数

関数の定義内、条件分岐や繰り返し文の処理部分、{ }で囲まれたブロック内では、この中でのみ利用可能なローカル変数を定義することができます。

  count = 0;
  while count<5 do
    local text = "counter value is "..count;
    print(text);
    count = count+1;
  end

  print(text); -- ここではもう変数textは利用できません

オブジェクト

Mitaka Plus に特有の機能は、オブジェクトとして機能ごとにまとめられています。

それぞれのオブジェクトには、状態を表すプロパティと、特定の機能を実行する関数であるメソッドを保有しています。

プロパティはオブジェクト名とプロパティ名をピリオド"."で区切って記述します。プロパティに値を設定することでMitaka Plusを操作し、またプロパティ値によって状態を取得します。

  Camera.zoom = 1.5 * mtk.UNIT_AU; -- Cameraオブジェクトのzoomプロパティに値を設定
  currentZoom = Camera.zoom; --  Cameraオブジェクトのzoomプロパティの値を取得

メソッドはオブジェクト名とメソッド名をコロン":"で区切って関数のように記述します。メソッドは関数と同様に引数や返値を持つ場合があります。メソッドを呼び出すことによってMitaka Plusを操作したり、状態を取得することができます。

  Camera:jumpToTarget(); -- メソッドの実行によってターゲット天体の近くに移動する 

オブジェクトの詳細についてはスクリプトリファレンスを参照してください。

値の確認

変数や計算結果などの値の確認には、print()関数を利用します。引数に与えた値が文字列としてスクリプト出力ウィンドウに表示されます。

  a=1;
  print(a); -- aの値を表示。出力: 1
   
  a=1;
  print(a..", 2"); -- aの値と文字列を連結して表示。出力: 1, 2

ライブラリの作成

スクリプトを複数のファイルに分割して記述することができます。 よく使う関数などはまとめて別ファイルに記述し、共用すると便利でしょう。別ファイルに記述したスクリプトは、dofile()関数で実行することができます。

  dofile("library.lua"); --同じフォルダのlibrary.luaを記述したのと同じ効果

標準ライブラリ

Luaスクリプトにあらかじめ備わっている以下の関数を利用することができます。

  dofile("test.lua");
  --ファイル名で指定されたLuaスクリプトファイルを読み込んで実行します。
  error("Errir occured.");
  --エラーとしてメッセージ文字列を表示してスクリプトを終了します。
  tonumber("1.5");
  --文字列を数値に変換して返します。数値に変換できなかった場合はnilを返します。ここでは1.5が返されます。
  tostring(1.5);
  --数値を文字列に変換して返します。ここでは"1.5"が返されます。
  type(a);
  --変数aの型を文字列で返します。変数の値が数値なら"number"、文字列なら"string"となります。
  string.find(検索対象, 検索文字列, 開始位置);
  string.find("test", "es", 1); --2,3が返値になります。
  -- 検索対象から検索文字列を検索してその開始位置と終了位置を返します。
  -- 見つからない場合はnilを返します。開始位置は1で最初から、2だと2文字目以降からの検索になります。省略することも可能です。
  string.format(書式文字列, 値, 値, ...);
  string.format("%d, %g, %s", 1.0, 1.5, "test"); --出力: "1, 1.5, test"
  --書式文字列で定義された書式で値を文字列化します。書式文字列内では
  --その後の値の順に並べられ、その際に%dが整数、%gが実数、%sが文字列の値を表します。
  string.lower("Test");
  --文字列を小文字にして返します。ここでは"test"が返されます。
  string.upper("Test");
  --文字列を大文字にして返します。ここでは"TEST"が返されます。
  string.sub(文字列, 開始位置, 終了位置);
  string.sub("test", 2, 3); --出力:"es"
  --文字列のうちから指定した範囲の部分文字列を返します。最初の文字位置を1として表します。
  math.pi      --パイ(3.14159...)を表します。
  math.deg(a); --aの値をラジアンから度に変換して返します。
  math.rad(a); --aを度からラジアンに変換して返します。
  math.max(a, b, c, ...); --a, b, c, ...内での最大値を返します。
  math.min(a, b, c, ...); --a, b, c, ...内での最小値を返します。
  math.random(); --0以上1未満の実数の乱数値を返します。
  math.random(最大値); --1以上最大値以下の整数の乱数値を返します。
  math.random(最小値, 最大値); --最小値以上、最小値以下の整数の乱数値を返します。
  math.abs(a); --aの絶対値を返します。
  math.acos(a); --aのアークコサインを返します。
  math.atan(a); --aのアークタンジェントを返します。
  math.atan2(a, b); --a/bのアークタンジェントを返します。
  math.ceil(a); --aの切り上げ値を返します。
  math.cos(a); --aのコサインを返します。
  math.cosh(a); --aの双曲線余弦を返します。
  math.exp(a); --aの指数を返します。
  math.floor(a); --aの切り捨て値を返します。
  math.fmod(a); --aの整数部と小数部を返します。
  math.frexp(a); --aの正規化した小数部と指数部を返します。
  math.ldexp(a, b); --仮数aと指数bから実数を計算して返します。
  math.log(a); --aの対数を返します。
  math.log10(a); --aの対数を返します。
  math.modf(a); --aの浮動小数点数の剰余を返します。
  math.pow(a, b); --aのb乗を返します。
  math.sin(a); --aのサインを返します。
  math.sinh(a); --aの双曲線正弦を返します。
  math.sqrt(a); --aの平方根を返します。
  math.tan(a); --aのタンジェントを返します。
  math.tanh(a); --aの双曲線正接を返します。