ランダムな数値を取得し、その値を利用していろんな方向にブロックを自動建築するプログラムを紹介します。
ただランダムで滅茶苦茶にブロックを設置するのはあまり面白くないので、今回は空を自由に泳ぐヘビのような物体を作ってみましょう。
ランダムな数値を取得する
ランダムとはくじ引きのようなもので、何が出てくるのかが分からないという物です。
このランダムの特性を利用して、
- もし0が出たら東方向に
- もし1が出たら上方向に
- もし2が出たら南方向に
それぞれブロックを建築してゆくというプログラムを、繰り返し処理の中で一時停止しながらコマ送り風に動かすことで、空を泳ぐアニメーションのような効果を演出します。
今回使用する主なプログラミング技術は以下のようなものです。
- ランダムな値を取得する
- プログラムの実行を一時停止する
- 指定した回数ぶん繰り返し処理をする
- リスト型のモノ(変数)を使用する
以下にサンプルプログラムを掲載しますので、ご自身の環境で動かしてみたい場合は以下の場所に保存してください。
ファイルパス(Macの場合)
/Users/ユーザ名/Library/Application Support/minecraft/mcpipy/skysnake.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# coding: UTF-8 # 上のコードを書くことで、日本語のコメントを有効にします # マインクラフト用のプログラムを読み込みます from mine import * # 一時停止が使えるように、時間を扱うことができる time というプログラムを読み込みます import time # ランダムな値が取得できるように、random というプログラムを読み込みます import random # マインクラフト用のプログラムを、すぐに使えるように「mc」として準備します mc = Minecraft() # チャットメッセージを出力します mc.postToChat("skysnake.py の処理を開始します") # チャットメッセージを出力します mc.postToChat('ランダムな方向に少しずつブロックを設置します') # ブロックの種類を設定します block_number = 19 # 自分の位置情報を取得します # 取得してきた位置情報は、それぞれ変数 x, y, z に保存されます x,y,z = mc.player.getPos() # Y方向(上下方向)の設定: はじめに上昇を設定しておきます move_y = 'up' # 建築したブロックの情報を保存するモノを準備しておきます old_x = [] old_y = [] old_z = [] # ブロックを設置する間隔を設定します(単位:秒) sleep_time = 0.3 # ブロックを何回設置するかを設定します loop_num = 100 # ここから: 空でヘビを動かす繰り返し命令を実行します # 繰り返す回数は loop_num で指定した数ぶん for i in range(loop_num): # 一時停止します time.sleep(sleep_time) # 0から2の範囲内で、ランダムな数字を取得します num = random.randint(0, 2) # ランダムに取得した数字をチャットメッセージで確認します # mc.postToChat(num) # もし現在の高さが0以下の場合は、Y方向(上下方向)の設定を上昇にします if y <= 0: move_y = 'up' # もし現在の高さが40以上の場合は、Y方向(上下方向)の設定を下降にします if 40 <= y: move_y = 'down' # もしランダムに取得した数字が0だった場合 if (num == 0): # 東西方向を示すxに1を足します x = x + 1 # もしランダムに取得した数字が1だった場合 if (num == 1): # もしY方向(上下方向)の設定が上昇に指定されていた場合 if move_y == 'up': # 上下方向を示すyに1を足します y = y + 1 # もしY方向(上下方向)の設定が 'up' ではなかった場合 else: # 上下方向を示すyから1を減らします y = y - 1 # もしランダムに取得した数字が2だった場合 if (num == 2): # 南北方向を示すzに1を足します z = z + 1 # 指定した座標にブロックを設置します mc.setBlock(x, y, z, block_number) # i には何回めの繰り返し回数かが記録されています # いま建築したブロックの位置情報を記憶しておきます old_x.insert(i, x) old_y.insert(i, y) old_z.insert(i, z) limit = 20 # もし回転数が20以上だった場合 if (limit <= i): # 20個前に設置したブロックを削除します(空気ブロックに置き換えます) # old_x, old_y, old_z の中に建築したブロックの座標が保存されているので、その値を参照しています index = i - limit mc.setBlock(old_x[index], old_y[index], old_z[index], 0) # 繰り返し命令はここで終了です # ここまで: 空でヘビを動かす繰り返し命令を実行します # チャットメッセージを出力します mc.postToChat('空に残ったブロックを消してゆきます') # 空に残ったブロックを削除します for i in range(limit): # ブロックを削除します(空気ブロックに置き換えます) # old_x, old_y, old_z の中に建築したブロックの座標が保存されているので、その値を参照しています index = i - limit mc.setBlock(old_x[index], old_y[index], old_z[index], 0) # 一時停止します time.sleep(sleep_time) # 繰り返し命令はここで終了です mc.postToChat("実行終了です") |
こちらに掲載したサンプルを実行するには、チャット入力エリアに以下のコマンドを入力してください。
このプログラムを実行すると、黄色いブロックがうねうねと空を飛ぶ様子が見られると思います。
そして設置したブロックが自動で消えてゆくことにも注目する必要があります。
for 繰り返し処理の中でしていること
上のPythonプログラムでは、for の繰り返し処理の中で以下のようなことがおこなわれています。
すでに現在位置は取得できているので、この現在位置を起点にものごとが進んでゆきます。
- ランダムな値を取得します。
- いまの高さを判定し、「上昇モード」または「下降モード」に振り分けます。
- もしランダムな値が「0」だった場合は、東方向に1を足した場所にブロックを設置します。
- もしランダムな値が「1」だった場合は、「上昇モード」か「下降モード」かを判定し、上下方向のどちらかに1ブロックぶんを変化させた場所にブロックを設置します。
- もしランダムな値が「2」だった場合は、南方向に1を足した場所にブロックを設置します。
- ブロックを設置した場所を記憶しておきます。
- もし繰り返し回数が20以上だった場合は、20回前に設置したブロックを削除(空気ブロックに置き換え)します。
このように現在有効な位置にブロック1個ぶんの位置情報をランダムに決定させ、そこにブロックを設置。
そして過去に設置したブロックを削除することで、20ブロックで構成されたヘビのような物体が空をうねうね飛ぶのですね。
ランダムな値を取得するプログラムの解説
ランダムに値を取得するには、まず random という外部のプログラムを読み込んでおく必要があります。
10 11 |
# ランダムな値が取得できるように、random というプログラムを読み込みます import random |
そして、0から2までの数字から、ランダムに値を取得している部分がこちらです。
49 50 |
# 0から2の範囲内で、ランダムな数字を取得します num = random.randint(0, 2) |
0から2までの数字、つまり「0」「 1」「2」 の3種類の中のどれかがランダムに選択されます。
この命令を取得すれば何が出てくるか分かりませんので、「おみくじ」や「じゃんけん」などのプログラムにも使えそうですね。
ヘビの上昇・下降を設定するプログラムの解説
プログラム実行が開始されると、プレーヤがいる場所からヘビが動き出します。
プレーヤのいる場所というのは、以下のプログラムで座標が取得できましたよね。
25 26 27 |
# 自分の位置情報を取得します # 取得してきた位置情報は、それぞれ変数 x, y, z に保存されます x,y,z = mc.player.getPos() |
ここからヘビが下降してしまった場合、ヘビが地中に潜ってしまうので動きを見ることができません。
なので最初はヘビが上昇するように設定しています。
29 30 |
# Y方向(上下方向)の設定: はじめに上昇を設定しておきます move_y = 'up' |
でもヘビが上昇しっぱなしだと宇宙へ飛び出してしまうので、ある程度の高さまで達すると下降に切り替える必要があります。
これと同じように、下降しっぱなしだと地下に潜ってしまいますので、また上昇に切り替える必要があるのですが、その処理をしているプログラムがこちらです。
55 56 57 58 59 60 61 |
# もし現在の高さが0以下の場合は、Y方向(上下方向)の設定を上昇にします if y <= 0: move_y = 'up' # もし現在の高さが40以上の場合は、Y方向(上下方向)の設定を下降にします if 40 <= y: move_y = 'down' |
もしy座標が0以下だった場合、つまり高さが海面と同じだった場合は、上昇モードに設定します。
一方、高さが40以上だった場合は結構高い位置にいるので、下降モードに設定します。
そして、この設定した値を判断して動作分けしている部分がこちらのプログラムです。
69 70 71 72 73 74 75 76 77 78 79 |
# もしランダムに取得した数字が1だった場合 if (num == 1): # もしY方向(上下方向)の設定が上昇に指定されていた場合 if move_y == 'up': # 上下方向を示すyに1を足します y = y + 1 # もしY方向(上下方向)の設定が 'up' ではなかった場合 else: # 上下方向を示すyから1を減らします y = y - 1 |
上昇モードの場合はy座標の値をプラス1にして、
下降モードの場合は、逆にy座標の値をマイナス1にしています。
こうしてx, y, z それぞれの座標が決定したので、ブロックを設置しているんですね。
設置したブロック位置の保存
設置したブロックの位置は、以下に保存されてゆきます。
89 90 91 92 93 |
# i には何回めの繰り返し回数かが記録されています # いま建築したブロックの位置情報を記憶しておきます old_x.insert(i, x) old_y.insert(i, y) old_z.insert(i, z) |
「old_x」「old_y」「old_z」というモノは、33〜35行めで最初に出てきていますよね。
こちらです。
32 33 34 35 |
# 建築したブロックの情報を保存するモノを準備しておきます old_x = [] old_y = [] old_z = [] |
ここでは、まずリスト(または配列)という型のモノを準備しておきます。
このリスト型のモノは、1個のモノの中にたくさんの値を保存できる便利なやつで、
- old_x[0] = これのゼロ個めに入っている値を見るよ!
- old_x[1] = これの1個めに入っている値を見るよ!
- old_x[2] = これの2個めに入っている値を見るよ!
- old_x[3] = これの3個めに入っている値を見るよ!
といったように、モノの中身は番号で分けられています。
この番号はゼロから始まることに注意してください。
そして、91行めではこの「old_x」に以下のような情報を保存しています。
- old_x[0] = [x座標の値]
- old_x[1] = [次のx座標の値]
- old_x[2] = [そのまた次のx座標の値]
上記はX座標のみ解説をしていますが、Y座標やZ座標も同じような意味です。
設置したブロックを一定の条件で削除
もし繰り返し回数が20以上だった場合は、20回前に設置したブロックを削除(空気ブロックに置き換え)するプログラムがあります。
新しいブロックを設置しながら古いブロックを消してゆくことで、アニメーションのような演出で空を移動しているように見えるわけです。
96 97 98 99 100 101 102 |
limit = 20 # もし回転数が20以上だった場合 if (limit <= i): # 20個前に設置したブロックを削除します(空気ブロックに置き換えます) # old_x, old_y, old_z の中に建築したブロックの座標が保存されているので、その値を参照しています index = i - limit mc.setBlock(old_x[index], old_y[index], old_z[index], 0) |
- もし繰り返し回数を記憶している「i」が20以上だった場合
- index というモノに対して、i – limit の計算結果を入れます
もし繰り返しが20回転めだった場合は、20 – 20 の計算結果、つまりゼロの数字が index に入ります。 - 「mc.setBlock」の命令で、指定した座標のブロックを「空気」にします。
102行めでは「old_x[index]」「old_y[index]」「old_z[index]」の指定がありますが、[index] には(2)で計算した値が入っていると考えてください。
もしこの処理がない場合は、設置したブロックが削除されることなく、ずっと空に残っていることになりますので、もし試してみたい場合は102行めのプログラム先頭に「#」を追加(コメントアウト)して、実行してみると良いでしょう。
また、109行め以降も同じようなプログラムが書かれていますので、コメントを見ながらどのような動きになっているか考えてみましょう。