日常英語のようなプログラミング言語で
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

Page 03
08: カード、メッセージ・パス
09: カスタム・コマンド
10: カードのスクリプト・エディター
11: 斜めに動くボタンを増やす


Page 05
17: リピート文2 フォーエバー「forever」
18: スウィッチ文「switch」で方向を変える
19: ボールをバウンスさせるブロック
20: オプション・メニューからボールのスピードを選ぶ




ⓒ 小島健治 / Kenji Kojima