日常英語のようなプログラミング言語で
1行ごとに何をやっているか確認しながらコードを書く Page 04
12: リピート文1、ティックス「ticks」
カードに書かれているカスタム・コマンドは、パラメータで設定した数字の数だけグラフィックが移動します。これをパラメータのピクセル数を3回繰り返して働くリピート文にします。
command moveGrc pItem1, pItem2
set the loc of grc 1 to item 1 of the loc of grc 1 + pItem1, \
item 2 of the loc of grc 1 + pItem2
end moveGrc
カードに書いてあるカスタム・コマンドは上の通りです。バックスラッシュ「\」はこのページのレイアウトの事情で改行しました。このようにバックスラッシュ「\」で改行してもしなくても良いです。コマンドのハンドラーの中のステートメントは、1行で書くことができます。このステートメントを複数回繰り返すリピート文の基本形は、下のようになります。
repeat for 3 times -- リピート文の始め この場合は3回繰り返す(3 times)
-- 繰り返して実行するステートメントがここに来る
end repeat -- 最後に「エンド リピート」で繰り返す回数から抜け出る
ではこの3回の繰り返しをカスタム・コマンド「moveGrc」に適用してみます。
command moveGrc pItem1, pItem2
repeat for 3 times -- 3回繰り返すリピート文始め
set the loc of grc 1 to item 1 of the loc of grc 1 + pItem1, \
item 2 of the loc of grc 1 + pItem2
end repeat -- 繰り返しの回数だけ実行されたらリピートから抜ける
end moveGrc
これでスクリプトに間違いなければ、スクリプト・エディターを「Apply」してカードにあるそれぞれのボタンをクリックしてみます。すぐに気がつくと思いますが、実はこれでは少し問題があります。確かに3回分のピクセル数の移動、この場合はボタン内のパラメータで設定した「20 x 3 times = 60ピクセル」グラフィックは移動しますが、ステートメントを処理されるのが早すぎて、3回移動させたというより60ピクセル1回で移動したように見えてしまいます。それでは1回の処理が終わった後で少し間をとって、それから次のステートメントを実行させるようにします。
LiveCodeで使える時間の単位に「tick ティック」というのがあります。1ティックは60分の1秒を表します。ここではステートメントが実行されたら10ティックスだけ待って(wait)、それからまた繰り返しが行われるようにしました。「tick」は「ticks」と書いても、「ticks」を付けない数字だけで「wait」の後に「10」とだけ書いても有効です。
command moveGrc pItem1, pItem2
repeat for 3 times
set the loc of grc 1 to item 1 of the loc of grc 1 + pItem1, \
item 2 of the loc of grc 1 + pItem2
wait 10 ticks -- 1/6秒待つ
end repeat
end moveGrc
これで3回20ピクセルづつ、計60ピクセルグラフィックが動いたように見えます。
13: ポイントがあるかないかを知るウィズイン「within」
ボタンをどんどん押し続けると、スタック(カード)の外にグラフィックが出てしまいます。とりあえず目で見てグラフィックが外に出たらリセット・ボタンをクリックしてまた中央に戻す事はできますが、これを自動化しましょう。こういう方法はひとつだけとは限らないけれど、ここでは「within ウィズイン」を使う事にします。
「within」は英語の前置詞で、場所で使う場合は「...の内側に」という日本語の意味です。時間で使う場合は「...の間に」という意味になります。LiveCodeで使う場合は、決まった範囲内にある座標があるかないかを知るオペレーター(operator = 操作記号、演算子)です。オペレーター(operator)は足し算引き算で使う「プラス マイナス + -」記号のような役割をする言葉(またはシンボル)
ですが、必ずしも数字の計算だけに使うものではなく、文字列の論理が正しいか間違っているかという判断をするオペレーターもあります。「is within」の場合は、あるポイントが指定した範囲の中にあれば「true 真」、範囲の外にあれば「false 偽」を返します。試しにグラフィック1が見えている状態で
put the loc of grc 1 is within the rect of this cd
グラフィック1の中心の座標がこのカードの範囲内にあるか真偽を返しなさい
をメッセージ・ボックスから送ってみると「true(正しい)」が返されます(下図)。「cd = cardの省略形」
これと反対の用法で「is not within」は、あるポイント(座標)が範囲内にある場合に「false 間違っている」を返し、範囲外にある場合には「true 正しい」を返します。今度は上の図の時とまったく同じ状態で
put the loc of grc 1 is not within the rect of this cd
グラフィック1の中心の座標がこのカードの範囲内にないか真偽を返しなさい
をメッセージ・ボックスから送ると「false 間違っている(範囲内にある)」を返します(下図)。
14: if 文「もし何々ならば ... 」
「もし グラフィック1のポイントが このカードの範囲内になかったら(is not within が true だったら) ... しなさい。」と言う、「if 文」を使ったスクリプトをこれから書いてゆきます。つまりグラフィック1のどこかのポイントがカードの外に出たら「true 真」となる文章です。さてポイントをどうするのかという問題ですが、「the loc of grc 1」ではグラフィック円の真ん中の座標になってしまいますから、ページ1で説明した「topLeft 左上」と「bottomRight 右下」を使います(下図)。
「if 文」の基本構造の説明からしましょう。
if 条件のステートメント then -- 条件の最後に必ず「then」を付ける
(条件が正しければ)ここに書いたステートメントを実行する
(条件が正しくなければ)「if 文」から抜ける
end if -- 最後は「end if」で「if 文」から抜ける
上に書いた「if 文」の基本構造では「条件のステートメント」が1つだけですが、これから書いて行く「if 文」では条件が2つあって、もしどちらかが正しければという比較の「or または」で2つの条件をつなげる必要があります。下に書いた「topLeft」と「bottomRight」の文のどちらかが正しいという文章にします。
the topLeft of grc 1 is not within the rect of this cd
the bottomRight of grc 1 is not within the rect of this cd
ではこの2行を「if 文」の基本構造を元にして、条件のステートメントに作り変えます。
if the topLeft of grc 1 is not within the rect of this cd or \
the bottomRight of grc 1 is not within the rect of this cd then
(条件が正しければ = topLeft か bottomRight のどちらかのポイントがカード内でなかったら)
ここに書いたステートメントを実行する
end if
「if 文」の始めの行の条件のステートメントは必ず「then」で終ります。その後の実行するステートメントはここでは改行して書くようにしていますが、シンプルな「if 文」でしたら「then」の後に実行するステートメントを繋げて「end if」なしで書く事もあります。ここのように改行した場合は、必ず最後に「end if」の行を書いて終わらせます。
15: ビープを鳴らしてリピートの途中から抜ける
それではグラフィック1(円)のどこかがカードの外に出た場合、「ビープ音を鳴らして」「グラフィックをカードの中央に戻す」スクリプトを書きます。
beep -- ビープ音を鳴らす
send mouseUp to btn "reset" -- ボタン「リセット」にマウスアップを送る
exit repeat -- リピートから抜ける
「beep」とだけ書けば、ユーザーが設定しているビープ音が鳴ります。その次の行の実行する内容はすでにボタン「リセット」でできるようになっていますから、ボタン「リセット」をクリック(mouseUp)する「send mouseUp」を送ります。次の行の「exit repeat」で、リピートの途中であっても repeat文のループから抜ける事ができます。上で作った「if 文」に組み込んでみます。
if the topLeft of grc 1 is not within the rect of this cd or \
the bottomRight of grc 1 is not within the rect of this cd then
beep
send mouseUp to btn "reset"
exit repeat
end if
最後に以上のスクリプトを、カード・エディターにすでにあるカスタム・コマンド「moveGrc」のリピート文の中に書き加えます。
command moveGrc pItem1, pItem2
repeat for 3 times
set the loc of grc 1 to item 1 of the loc of grc 1 + pItem1, \
item 2 of the loc of grc 1 + pItem2
if the topLeft of grc 1 is not within the rect of this cd or \
the bottomRight of grc 1 is not within the rect of this cd then
beep
send mouseUp to btn "reset"
exit repeat
end if
wait 10 ticks
end repeat
end moveGrc
16: 「or」と「and」の違い
LiveCodeのオペレイター(operator 操作記号、演算子)は、大きく分けて計算式(数字だけでなく文字列も式と考えて)を扱うヌーメリック・オペレイター(numeric operators 計算式操作)と、 真か偽かを判断するロジカル・オペレイター(logical operator 論理操作、論理演算子)があります。「or」と「and」はどちらもロジカル・オペレイターです。if 文の「or」の場合は上で試したように、「or」で繋がれた条件文の1つが「true」だったら条件が満たされてステートメントが実行されます。「and」の場合は「and」で繋がれた条件文の全てが満たされないと、ステートメントは実行されません。
それでは「or」だけを「and」に変えたカスタム・コマンド「moveGrc」がどうなるか試してみましょう。
command moveGrc pItem1, pItem2
repeat for 3 times
set the loc of grc 1 to item 1 of the loc of grc 1 + pItem1, \
item 2 of the loc of grc 1 + pItem2
if the topLeft of grc 1 is not within the rect of this cd and \
the bottomRight of grc 1 is not within the rect of this cd then
beep
send mouseUp to btn "reset"
exit repeat
end if
wait 10 ticks
end repeat
end moveGrc
スタックの左下と右上コーナーを除いて、グラフィック1の「topLeft」と「bottomRight」がどちらもカードの外に出た(完全にグラフィック円が見えなくなった)時点で、ボタン「リセット」にマウスアップが送られます。今は「or」と「and」の違いの説明ですから、スタックの左下、右上の例外についてはこれでも良いのですが、完全にグラフィック1の円が見えなった時にボタン「reset」にマウスアップが送られるようにするには、「bottomLeft」と「topRight」の条件も「and」で繋いで書き込まなくてはいけません。
command moveGrc pItem1, pItem2
repeat for 3 times
set the loc of grc 1 to item 1 of the loc of grc 1 + pItem1, \
item 2 of the loc of grc 1 + pItem2
if the topLeft of grc 1 is not within the rect of this cd and \
the bottomRight of grc 1 is not within the rect of this cd and \
the bottomLeft of grc 1 is not within the rect of this cd and \
the topRight of grc 1 is not within the rect of this cd then
beep
send mouseUp to btn "reset"
exit repeat
end if
wait 10 ticks
end repeat
end moveGrc
2016年6月8日
役に立ったらドネーションをよろしく。
著者・アーティスト:小島健治
Eメール:index@kenjikojima.com