![見出し画像](https://assets.st-note.com/production/uploads/images/73233148/rectangle_large_type_2_1cd4d77040a192dd752d354655325f2b.png?width=1200)
Processing でマイクラ④ 村を自動生成する
マイクラの魅力の一つは、「自動生成される世界」です。マイクラで新規ワールドを作成するたびに、異なったバイオーム(海、山、砂漠、平地など)が現れます。ところどころに村があり、地下迷宮や寺院、海底神殿など、魅惑的なスポットがランダムに存在しています。私はマイニングしていてダンジョンに出くわすと、テンションがバク上がり↑です。
さて今回は、マイクラ風の村の自動生成に挑戦してみました。20軒の家と道路、岩地だけの簡単な世界ですが、マイクラが世界を作る仕組みが感じられることと思います。
ランダムな家を作成する
def minecraftic_house(w, d, h, x=0, z=0):
# heights = [0, 4, 5, 6, 7, 8, 8, 7, 6, 5, 4, 0]
heights = [0]
for i in range(w):
if i < w / 2:
if w % 2 == 0:
heights.append(h - (w / 2) + i + 1)
else:
heights.append(h - (w / 2) + i)
else:
heights.append(h + (w / 2) - i)
heights.append(0)
# print(heights)
wood_id = 35
roof_color = randint(0, 15)
body_id = 5
pillar_id = 12
for i in range(w + 2):
for j in range(d):
roof_height = heights[i]
if (i == 1 and j == 0) or (i == 1 and j == d - 1) or (i == w and j == 0) or (i == w and j == d - 1):
block_id = pillar_id
else:
block_id = body_id
if roof_height > 0:
for k in range(roof_height):
block_positions.append((i + x, k, j + z, block_id))
else:
block_positions.append((i + x, k + 1, j + z, wood_id, roof_color))
else:
block_positions.append((i + x, heights[1] - 1, j + z, wood_id, roof_color))
# クラフトデータを作成
for i in range(2):
for j in range(10):
minecraftic_house(
randint(5, 11),
randint(5, 11),
randint(8, 11),
j * 15,
i * 30,
)
![](https://assets.st-note.com/img/1646028380978-sbuJUSc0gD.png)
マイクラ編の第一回で作った家のプログラムを改造しました。同じ家が並んでいてもつまらないので、縦横高さ、屋根の色がランダムに作成されるように変更しています。屋根の色は羊毛で表しており、16種類の色を表現できます。
for文を二重にすることで、10 x 2 軒のマイクラ風の家が建築されます。Processingのスケッチを実行するたびに、違った家の並びが現れます。そしてその並びは2度と現れないのです。(厳密にいうと、何度も何度もやっていたら同じ並びが現れます。)
道路を建築する
def road():
for i in range(150):
for j in range(9):
if 0 < i % 10 < 5 and j == 4:
block_id = 12
else:
block_id = 1
block_positions.append((i, -1, j + 15, block_id))
road()
![](https://assets.st-note.com/img/1646028459555-cihkwuLqKe.png)
家の並びと平行に道路を建築しました。単に石ブロックを並べるだけではつまらないので、中央線(砂で表現)を描いています。こだわるのならば、縁石や歩行者用の道を作るのもよいでしょう。いくらでも細部を作りこんでいくことができます。
街路樹を植える
def tree(x, z):
tree_height = randint(7, 8)
for i in range(tree_height):
wood_id = 35
branch_color = 12
leaf_color = 13
if i < 3:
block_positions.append((x, i, z, wood_id, branch_color))
elif i == tree_height - 1:
block_positions.append((x, i, z, wood_id, leaf_color))
else:
for j in range(3):
for k in range(3):
block_positions.append((x - 1 + j, i, z - 1 + k, wood_id, leaf_color))
# クラフトデータを作成
for i in range(2):
for j in range(10):
minecraftic_house(
randint(5, 11),
randint(5, 11),
randint(8, 11),
j * 15,
i * 30,
)
tree(j * 15, 13) # 追記
tree(j * 15, 25) # 追記
![](https://assets.st-note.com/img/1646028820275-uSCsNaqrJb.png)
家と道路の間に、街路樹を植えました。これでぐっとリアルさが増したように思います。街路樹は羊毛の茶色と緑で作りました。高さはランダムに 7 か 8 を選ぶようにしてあります。
バイオームを作成する
地形作成編①で紹介させていただいた、Webサイトをまた利用させていただきます。
地形自動生成
150x150サイズの地形を作成し、「minecraftic_village.csv」の名前で保存します。csv を読み込んで、地形を作成するコードは以下のようになります。
import csv
import codecs
sketch_name = 'minecraftic village'
def land():
with open(csv_file, 'r') as f:
reader = csv.reader(codecs.EncodedFile(f, 'utf-8', 'utf-8-sig'), delimiter=",")
land_data = [row for row in reader]
row_num = len(land_data)
column_num = len(land_data[0])
max_height = int(max([max(l) for l in land_data]))
print(max_height)
for i in range(row_num):
for j in range(column_num):
land_height = int(land_data[i][j])
if j < 45 or 90 < j:
for k in range(land_height):
block_positions.append((i, k, j - 50, 1))
elif j == 45 or j == 90:
for k in range(int(land_height / 2)):
block_positions.append((i, k, j - 50, 1))
land()
![](https://assets.st-note.com/img/1646029255695-xvUgvpe71P.png)
地形作成編①のコードを少し修正しています。
地形の配置を Z方向に50移動させています。家並みが存在する場所はバイオームを設置しないようにしました。バイオームと家並みの境界線は段差が少なくなるように調整してあります。
これで、マイクラ風の村の建築は完了です。マイクラ(本物)の内部で動くプログラムは、今回紹介したもの(もどき)より、もっともっと複雑です。しかしやっていることはランダムに地形を生成することですから、今回のプログラムと本質は同じということができます。
村をマイクラの世界にコピーする
![](https://assets.st-note.com/img/1646029658263-fPMLu7HDro.png?width=1200)
マイクラの世界にコピーしてみました。なかなかいい感じです。スライムが遊んでいるのが楽しいです。改造するとしたら、バイオームと家並みの境界が段差が大きいので、もっとなだらかにしたいです。バイオームがすべて石なのも不自然ですね。細かい修正は読者の皆様にお願いします。
Processing x Minecraft = Processincraft の世界にようこそ!
前の記事
Processing でマイクラ③ Processingからマイクラにデータを送信
次の記事
MagicaVoxel① はじめてのボクセルアート
その他のタイトルはこちら