SDL

せりか式 - Presentation - SDL

SDL(Senario Description Language)についてです.
シナリオや,オブジェクトの定義に関する重要な言語です.
これを理解しないことには始まりません.

セミコロン(;)までが1つの文になります.
オブジェクトの定義や,パラメータの指定などを行います.

1文はセミコロンがでるまでなので,複数行に渡って書くことができます.
逆に1行に複数の文を書くこともできます.
ただし,文字列の途中で改行を入れるようなことはしてはいけません.

また,好きなだけスペースや改行を入れることができます.
以下の3つは,見た目は違いますが,SDLの意味しているところは同じです.
それぞれのスタイルにあった見やすい書き方をしてもらえればいいと思います.

    1: picture { text { caption = "test"; }; x = 0; y = 0; } pic1;
    1: picture {
    2:     text { caption = "test"; }; x = 0; y = 0;
    3: } pic1;
    1: picture {
    2:     text {
    3:         caption = "test";
    4:     };
    5:     x = 0; y = 0;
    6: } pic1;

コメント

シナリオ中にコメントを入れておくことができます.
シナリオの説明や,デバッグ用にシナリオの一部をコメントアウトしておくことができます.

コメントは,一行コメントがシャープ(#)で, 複数行コメントがスラッシュ+アスタリスク(/* ... */)です.

ただし,文字列中はシャープもスラッシュ+アスタリスクもコメント記号にならないので注意が必要です.

    1: # example 1 ここはコメント
    2:
    3: /* ここからコメント
    4: コメントの中
    5: ここまでコメント */ ここはコメントではありません
    6:
    7: text{
    8:     caption = "Hello # World!"; 行の途中に#がありますが,文字列中なのでコメントにはなりません.
    9: } txt1;
   10:
   11: text{
   12:     caption = "Hello /* World!"; 行の途中に/*がありますが,先ほどと同様に文字列中なのでコメントにはなりません.
   13: } txt#2; ここはコメントになってしまいます.

大文字と小文字

この二つは区別されます.
そのため,次の3つはそれぞれ別の物を表します.
color, Color, COLOR
シナリオを書いているとごちゃごちゃになることがあるので,ある程度自分ルールを決めておいた方がいいと思います.

パラメータと変数

SDL...というよりはシナリオにはパラメータと変数という2つの概念があります.
パラメータは,シナリオの動作に関する,すでに定義されている変数です.
変数は,ユーザが自由に値を入れておけるオブジェクトです.

変数は,変数名の前にダラー($)がつきます.
パラメータはダラーなどはつきませんが,名前がすでに決まっており,自由に使うことはできません.
基本的にパラメータの値を設定できるのは,シナリオヘッダの部分のみです.

パラメータ

パラメータには,数値や文字列の他に,識別子や数列といった値を利用できます.
以下に利用できる値の種類をあげますが,例であげているabは,パラメータとして存在しているわけではなく, 説明の都合上利用しているだけの文字列です.

Numbers(float, integer)
名前の通り,数値の型です.
整数や小数を表現できますが,指数を表すことはできません.
floatの場合,整数と小数.integerの場合,整数のみを表しています.
    a = 1000;
    b = 0.5;
    c = -1.0;
    # 以下は間違えています
    a = 1e3;       # eを使った指数表記はできません
    b = - 0.5;     # マイナス(-)と数値の間にスペースがある
Number Lists(number list, integer list)
数値列を表す値です.
上記のnumbersをカンマ(,)で区切って並べたものです.
    a = 1, 2, 3, 4, 5;
Strings
文字列の型です.
double quotation(")でくくられたものが文字列になります.
文字列中に"を入れたい場合は,円マーク(\)を"の前に入れます.

他に円マーク(\)を前に入れないといけない文字は, 円マーク(\),ダラー($)があります.

また,\n\tは,それぞれ改行,タブを表しています.
    a = "Hello";                             # Hello
    b = "\"String with double quotation\"";  # "String with double quotation"
    c = "line1\nline2\nline3";               # line1<改行>line2<改行>line3
    d = "Special characters: \\, \$";        # Special characters: \, $
Identifiers
識別子です.
すでに定義済みの値(文字列)のことです.
Identifiersの途中にスペースが入ることはありません.
    a = correct_responce;
    b = false;
    c = forever;
Names
オブジェクトの名前です.
トライアルや,ピクチャーなどに対して付けた名前であり,ユーザが決めたものになります.
こちらも,名前の途中にスペースが入ることはありません.
    text { caption = "string"; } txt1;
    # 上のtxt1が名前になります
    a = txt1;
Colors
色に関する値です.
RGB(Red, Green, Blue)のそれぞれの強さを0から255までの数値でリストにしたものになります.
    red = 255, 0, 0;
    green = 0, 255, 0;
    blue = 0, 0, 255;

なんか,ここに載せていないものも時々使われています.
vector_3dとかいろいろ...
名前やsampleからなんとなく想像してください.

変数

変数は,変数名の前にダラー($)がつきます.
変数は,変数を定義したより後で有効になります.

個人的にはブロック有効範囲のほうが使い勝手が良かったのですが,

    1: # example
    2: $size = 16;
    3: $str = "string";
    4:
    5: picture {
    7:     $size = 32;            # $sizeの値を書き換え
    8:     text {
    9:         caption = $str;
   10:         font_size = $size;
   11:     };
   12:     x = 0; y = 0;
   13: }pic1;                     # pictureを抜けてもsizeは変更されており,32のまま

変数として利用できる値は以下のとおりです.

すべて,パラメータの指定と同じものです.
Stimuls Namesは,表現が変わっていますが,パラメータの指定のNamesと同じものです.
パラメータでは利用できたlistやcolorsは利用できません.

その代わりに,listやcolorsはstringで代用します.

配列

配列はarrayで実現することができます.
が,配列は,PCLで使うためにあるので,SDL上で配列を利用することは出来ません.
できるのは配列を作成することのみです.
例は,繰り返しを見て下さい.

数式

シングルクオーテーション(')でくくられた部分は数式になります.
四則演算といくつかの関数を使った計算式を書くことができます.
また,かっこ()を利用した演算順序の定義もできます.

以下が,利用できる関数です.
関数を利用する場合,関数名とかっこの間に空白が入らないように注意して下さい.
int (d)はエラーとなります.

int(d) 小数点以下を切り捨て
abs(d) 絶対値
ceil(d) dと同じか,それ以上で最小の整数.
floor(d) dと同じか,それ以下で最大の整数.
sqrt(d) 平方根.但し,dは正数とする.
sin(d) sin, cos, tan.
但し,dはラジアンであるとする.
cos(d)
tan(d)
acos(d) アークコサイン.但し,dは-1から1の閉区間値.計算結果は0からpiまでの閉区間値.
asin(d) アークサイン.但し,dは-1から1の閉区間値.計算結果は-pi/2からpi/2までの閉区間値
arctan(d)アークタンジェント.計算結果は-pi/2からpi/2までの閉区間値
exp(d) eの累乗
log(d) eを底とする対数.但し,dは正数.
log10(d) 10を底とする対数.但し,dは正数.
以下に,簡単な計算例をあげます.
    1: # example
    2: $i = '1 + 2'; # 3
    3: $i = '(1 + 2) * (3 - 4)'; # -3
    4: $i = '12 / 5'; # 2.4
    5: $i = 'int($j+0.5)'; # $jを四捨五入

繰り返し(LOOP)

同じことを繰り返す命令としてLOOP命令があります.
トライアルを繰り返す,配列用にデータを読み出す,といった用途に利用できます.
LOOPは指定した回数だけ繰り返しますが,指定した変数には0から値が入るので注意が必要です.

    1: # example
    2: LOOP $i 10;
    3: # ここが $i = 0 から $i = 9 までの10回繰り返されます
    4: ENDLOOP;
また,繰り返し回数を0にしても,必ず1度は繰り返し部分が実行されてしまいます.
Cでいうところのdo~whileループとして実現されているようですね.
    1: # example
    2: LOOP $i 0;
    3: # $i = 0 として実行される
    4: ENDLOOP;
次に,例をあげておきます.
といっても,大体マニュアルから持ってきたものですが.
配列に通し番号のjpgを読み出して,中央に配置したpictureを作成する.
pic[1]からpic[10]に"pic0.jpg"から"pic9.jpg"を読み出します.
LOOP用の変数の値と配列のインデックス番号がずれているので注意して下さい.
    1: # example
    2: array {
    3:     LOOP $i 10;
    4:     picture {
    5:         bitmap { filename = "pic$i.jpg"; };
    6:         x = 0; y = 0;
    7:     };
    8:     ENDLOOP;
    9: } pics;

同じ番号に読み出したい場合は,テンポラリ変数を用意して,$iを1増やした数を利用するようにします.
    1: # example
    2: array {
    3:     LOOP $i 10;
    4:     $tmp = '$i + 1';
    5:     picture {
    6:         bitmap { filename = "pic$tmp.jpg"; };
    7:         x = 0; y = 0;
    8:     };
    9:     ENDLOOP;
   10: } pics;

pictureをずらしながらtrialを繰り返します.
このようにすることで,アニメーションを行うことができます.
が,各フレーム毎のウェイトを指定することができません.
    1: # example
    2: trial {
    3:     LOOP $i 100;
    4:     $tmp = '$i * 10 - 500';
    5:     picture {
    6:         text { caption = "*"; };
    7:         x = $tmp; y = 0;
    8:     };
    9:     duration = 200;
   10:     ENDLOOP;
   11: } pics;

分岐(IF)

条件によって行いたい処理を分岐させることができます.
それが,IF命令です.

    1: # example
    2: IF '$i == 1';
    3:     # $i が 1 のとき実行される
    4: ENDIF;
分岐の条件には数値の他,文字列や数式などを書くことができます.
いずれの場合にしても 0以外 であるときにIFの中が実行されます.

値の比較として使われるのは,以下の6種類です.
<, <=, >, >=, ==, !=
    1: # example
    2: IF '$i < $j';
    3:     # $i が $j よりも小さいときに実行
    4: ENDIF;
    2: IF '$i <= $j';
    3:     # $i が $j よりも小さいか,同じ時ときに実行
    4: ENDIF;
    2: IF '$i > $j';
    3:     # $i が $j よりも大きいときに実行
    4: ENDIF;
    2: IF '$i >= $j';
    3:     # $i が $j よりも大きいか,同じときに実行
    4: ENDIF;
    2: IF '$i == $j';   # = が2つあることに注意
    3:     # $i と $j が同じときに実行
    4: ENDIF;
    2: IF '$i != $j';
    3:     # $i と $j が異なるときに実行
    4: ENDIF;
とはいえ,プログラミング言語ではないので,あまり複雑な分岐はできません.
AまたはBであるとき,AかつBのとき,といったような分岐は1つのIFでは実行できないので,複数のIFを組み合わせて実行することになります.
もしくは,数式の加算と乗算を使って擬似的にor,andを実現します.
また,いわゆるELSEが無いので,必要に応じて,仕掛けを作っておく必要があります.
IFを組み合わせて使う場合変数名$elseの名前が重複しないように気を付けて下さい.
elseの例
    1: # example
    2: $else1 = 1;
    3: IF '$i == 1';
    4:     $else1 = 0;# $else1 を 0 にしてしまう
    5:     # $i が 1 のとき実行される
    6: ENDIF;
    7: IF '$else1 == 1';
    8:     # $else1 が 1 の時に実行される
    9:     # 3行目のIFが実行されている場合,$else1は0に変更されているので実行されない
   10: ENDIF;
and, orの例
    1: # example
    3: IF '($i == 1) + ($i == 2)';
    5:     # $i が 1 または $i が 2 のとき実行される
    6: ENDIF;
    7: IF '($i == 1) * ($j == 1)';
    9:     # $i が 1 かつ $j が 1 のとき実行される
   10: ENDIF;


トップへ