Scratch2MCPI プログラミング②壁を作る

壁を作る


Image


今回は、幅10メートル×高さ10メートルの巨大な壁を作るプログラミングを考えていきます。実際に手を動かし、試行錯誤しながら進めると、プログラミングの基礎が身につきます。早速始めましょう。


幅2メートル×高さ1メートルの壁を作ってみる


まずは、前回作ったプログラミングを確認します。


  [mcpiX v]を[0]にする
  [mcpiY v]を[0]にする
  [mcpiZ v]を[10]にする
  [blockTypeId v]を[1]にする
  [blockData v]を[0]にする
  [setBlock v]を送る

このブロックは、座標 (0, 0, 10) に石ブロック(blockTypeId = 1)を設定するスクリプトでした。このプログラミングを改造(modify)していきます。


  [mcpiX v]を[0]にする
  [mcpiY v]を[0]にする
  [mcpiZ v]を[10]にする
  [blockTypeId v]を[1]にする
  [blockData v]を[0]にする
  (setBlock)を送る
  (0.1)秒待つ
  [mcpiX v]を[1]にする
  [setBlock v]を送る

末尾に (0.1)秒待つ[mcpiX v]を[1]にする[setBlock v]を送るを追加します。

(0.1)秒待つは初めて出てきましたが、スクリプトが円滑に実行されるように、一旦停止してタイミングを取る機能があります。このブロックを入れなければ、mcpiX の値が書き換えられる前に、[setBlock v]を送るが実行され、目的通りの働きをしてくれないのです。[setBlock v]を送るの下に (0.1)秒待つを設置するのを忘れないようにしましょう。

(停止する秒数ですが、0.1 秒でなくてもかまいません。プログラミングに慣れてきたら、0.0.1 秒にして高速に建築を進めることも可能です)


Image


スクリプトエリアのブロックセットをクリックして実行すると、2つブロックが並んで設置できました。では10個並んだプログラミングはどうなるでしょうか? (実行前に、[reset v]を送るを実行して、設置したブロックを消してください。以下同じです。)


幅10メートル×高さ1メートルの壁を作ってみる


先ほどと同じように、末尾にブロックを追加していきます。


Image


  (0.1)秒待つ
  [mcpiX v]を[1]にする
  (setBlock)を送る

を切り離して、「複製」してください。


Image


複製したブロックを元のブロックセットの合体させます。「複製」→「合体」の操作を9回繰り返します。そして、[mcpiX v]を[1]にするの数字を、1, 2, 3, 4, 5, 6, 7, 8, 9 と一つずつ変えていきます。すると、以下のブロックセットができるはずです。


  [mcpiX v]を[0]にする
  [mcpiY v]を[0]にする
  [mcpiZ v]を[10]にする
  [blockTypeId v]を[1]にする
  [blockData v]を[0]にする
  [setBlock v]を送る
  (0.1)秒待つ
  [mcpiX v]を[1]にする
  [setBlock v]を送る
  (0.1)秒待つ
  [mcpiX v]を[2]にする
  [setBlock v]を送る
  (0.1)秒待つ
  [mcpiX v]を[3]にする
  [setBlock v]を送る
  (0.1)秒待つ
  [mcpiX v]を[4]にする
  [setBlock v]を送る
  (0.1)秒待つ
  [mcpiX v]を[5]にする
  [setBlock v]を送る
  (0.1)秒待つ
  [mcpiX v]を[6]にする
  [setBlock v]を送る
  (0.1)秒待つ
  [mcpiX v]を[7]にする
  [setBlock v]を送る
  (0.1)秒待つ
  [mcpiX v]を[8]にする
  [setBlock v]を送る
  (0.1)秒待つ
  [mcpiX v]を[9]にする
  [setBlock v]を送る

ブロックをどんどんつなげていくと、スクリプトが長くなってきます。


Image


スクリプトエリアのブロックセットをクリックして実行すると、目的通り、10個のブロックが並びました。

これで完成でもよいのですが、ちょっとカッコ悪いです。さらに長いスクリプトになってくると、ブロックを並べるのも大変ですし、間違いも増えてくるでしょう。

もっとスマートで間違いの少ない書き方はないでしょうか?


繰り返し処理


カテゴリ「制御」の中に (10)回繰り返すが入っています。このブロックを使うと、長いコードを短くすることができます。またスクリプトが読みやすくなって(可読性が向上)、バグ(スクリプトの誤り)を見つけやすくなります。早速使ってみましょう。


  [mcpiX v]を[0]にする
  [mcpiY v]を[0]にする
  [mcpiZ v]を[10]にする
  [blockTypeId v]を[1]にする
  [blockData v]を[0]にする
  (10)回繰り返す
    [setBlock v]を送る
    (0.1)秒待つ
    [mcpiX v]を(1)ずつ変える
  end

(10)回繰り返すを使って、スクリプトを書き換えました。末尾の部分が随分、短く読みやすくなりました。

[mcpiX v]を(1)ずつ変えるが初めて登場しました。繰り返すたびに変数の値を増やしていくブロックです。このブロックがないと、同じ場所に「石ブロック」を10回設定してしまい、目的の働きをさせることができません。

()回繰り返す()を()ずつ変えるはセットで使うと覚えておいてください。


Image


実行すれば、10個のブロックが並び、目的が達成されました。繰り返し処理は便利なので覚えておきましょう。

今後は高さを10個にするスクリプトに挑戦します。


幅10メートル×高さ10メートルの壁を作ってみる


高さを10段にするには、繰り返しブロックを使うと良さそうです。


  (10)回繰り返す
    [setBlock v]を送る
    (0.1)秒待つ
    [mcpiX v]を(1)ずつ変える
  end

上のブロックセットをさらに(10)回繰り返すで囲って、[mcpiY v]を(1)ずつ変えるを追加します。


  [mcpiX v]を[0]にする
  [mcpiY v]を[0]にする
  [mcpiZ v]を[10]にする
  [blockTypeId v]を[1]にする
  [blockData v]を[0]にする
  (10)回繰り返す
    (10)回繰り返す
      [setBlock v]を送る
      (0.1)秒待つ
      [mcpiX v]を(1)ずつ変える
    end
  [mcpiY v]を(1)ずつ変える
  end

これで「X方向にもY方向にも10回繰り返す」スクリプトができそうです。スクリプトを実行してみましょう。


Image



横にずれて、階段のようになってしまいました。原因は何でしょうか? 少し考えてみてください。


Image


正解は、Y方向の繰り返しの際に[mcpiX v]を[0]にするを追加してやることでした。


  [mcpiX v]を[0]にする
  [mcpiY v]を[0]にする
  [mcpiZ v]を[10]にする
  [blockTypeId v]を[1]にする
  [blockData v]を[0]にする
  (10)回繰り返す
    (10)回繰り返す
      [setBlock v]を送る
      (0.1)秒待つ
      [mcpiX v]を(1)ずつ変える
    end
  [mcpiX v]を[0]にする
  [mcpiY v]を(1)ずつ変える
  end

1段目から2段目に移る時に、X方向のズレを修正してやることで目的の動作を実現できました。


【追加ミッション】10 x 10 x 10 の箱を作ってみる


追加のミッションをやってみましょう。同じように、Z方向に10回繰り返すスクリプトを書いてみてください。答えを見る前に自分で考えて、実際手を動かしてやってみることが大事です。


Image


答えは、上のスクリーンショットのブロックセットになります。


  [mcpiX v]を[0]にする
  [mcpiY v]を[0]にする
  [mcpiZ v]を[10]にする
  [blockTypeId v]を[1]にする
  [blockData v]を[0]にする
  (10)回繰り返す
    (10)回繰り返す
      (10)回繰り返す
        [setBlock v]を送る
        (0.1)秒待つ
        [mcpiX v]を(1)ずつ変える
      end
    [mcpiX v]を[0]にする
    [mcpiY v]を(1)ずつ変える
    end
  end
  [mcpiX v]を[0]にする
  [mcpiY v]を[0]にする
  [mcpiZ v]を(1)ずつ変える

Z方向に繰り返すさいに、「mcpiX,」「mcpiY」の値をリセットすることを忘れないようにしましょう。


Image


このプロジェクトは、「ファイル」→「名前を付けて保存」から保存しておきましょう。新しい名前は「mcpi_box」としました。


このプロジェクト(mcpi_box.sb)はダウンロードして、自分で確かめることがきます。

サンプルプログラムのページへ

(サンプルプログラムのページに移動します。ダウンロードしたいファイルのリンクをマウスで右クリックして、「対象をファイルに保存」などのメニューを実行してください。)


次回のお題は「チェック模様の床を作ろう」です。今回は「石ブロック」のみ積み上げましたが、積み上げるブロックを途中で変えるにはどうすればいいのか? 「条件分岐」について考えていきます。


【付録】座標系の簡単な説明


Image


コンピューターに仕事をさせるには、正確に位置を指定してやらなくてはなりません。

正確に位置を指定するには、「座標系」を使うと便利です。上の図は、「3次元直交座標系」と言います。マインクラフトでも採用されている、最もポピュラーな座標系です。

点の位置を表すときに、X軸の値、Y軸の値 、Z軸の値 の3つの値を使って表します。x = a, y = b, z = c の点は、(a, b, c) として表せます。


Image


Minecraft Pi では、主人公(steave)が初めに立っている位置を原点(0)として、前方向をZ、左手方向をX、上方向をYとして、座標系が決定されています。(正確には、steave はX=0, Z=0の地点に登場しますが、Y方向は初登場した場所(平地または丘、山)によって数値が違います。)


  [mcpiX v]を[0]にする
  [mcpiY v]を[0]にする
  [mcpiZ v]を[10]にする
  [blockTypeId v]を[35]にする
  [blockData v]を[14]にする
  (30)回繰り返す
    [setBlock v]を送る
    (0.1)秒待つ
    [mcpiX v]を(1)ずつ変える
  end
  [mcpiX v]を[0]にする
  [blockData v]を[5]にする
  (30)回繰り返す
    [setBlock v]を送る
    (0.1)秒待つ
    [mcpiY v]を(1)ずつ変える
  end
  [mcpiY v]を[0]にする
  [blockData v]を[11]にする
  (30)回繰り返す
    [setBlock v]を送る
    (0.1)秒待つ
    [mcpiZ v]を(1)ずつ変える
  end
  [mcpiZ v]を[0]にする

上のスクリーンショットのスクリプトを実行すると、マインクラフトの世界に座標系を描くことができます。(本来、座標系は細い線で表しますが、マインクラフトなので、1メートルのぶっとい線になってしまいますが。)


Image


  [mcpiX v]を[5]にする
  [mcpiY v]を[5]にする
  [mcpiZ v]を[5]にする
  [blockTypeId v]を[35]にする
  [blockData v]を[15]にする
  [setBlock v]を送る

上のブロックセットの「mcpiX,」「mcpiY」「mcpiZ」の値を変えて(-30 〜 +30)、実行してみてください。指定した場所に黒い点が設置されます。何度も繰り返すうちに、黒い点がどの辺りに現れるか予想がつくようになってくるでしょう。座標系の感覚が身についてくるまで、やってみよう。(上のスクリーンショットでは、mcpiX=5, mcpiY=5, mcpiZ=5 の位置に点を置いてあります)


このプロジェクト(mcpi_coordinate_system.sb)はダウンロードして、自分で確かめることがきます。

サンプルプログラムのページへ

(サンプルプログラムのページに移動します。ダウンロードしたいファイルのリンクをマウスで右クリックして、「対象をファイルに保存」などのメニューを実行してください。)


座標系は3次元の話になるので、少し難しく感じる人もいることでしょう。マインクラフトで自動建築をするためには必要な知識です。繰り返し学習して身につけてください。


次回は、模様のついた床作りに挑戦します。