# ドット絵作成プログラムを作ろう

前の章(条件文で穴を掘ったりブロックを積んだりしよう)

# for文を使いこなそう

本章では、下のようなドット絵の作り方を学んでいきます。これはマインクラフトに登場する敵キャラ『クリーパー』の頭部です。(色は簡単にしています。)

羊毛ブロックで作ったクリーパーのドット絵

前テキストでも学習したfor文をさらに使いこなせるようになれば、好きなドット絵を作ることができるようになります。

少し難しい内容になりますが、できることがグッと広がるので、じっくり勉強していきましょう。

# for文の『ネスト』

まずは、下のコードを見てみましょう。

import mcpi.minecraft as minecraft
import time

mc = minecraft.Minecraft.create()

x, y, z = mc.player.getPos()

for i in range(10):
    mc.postToChat(i)
    for j in range(5):
        time.sleep(0.5)
        mc.setBlock(x + j, y + i, z, 35, i)

実行すると、10色のブロックがポコポコと出来上がってくるのがわかるかと思います。その数は、全部で50個にのぼります。同時に、チャット画面に0から9までの数字が数え上げられていきますね。

積み重なった10色の羊毛ブロック

このように、for文の中にfor文を使う、入れ子のようなプログラムを書くことができます。これをfor文の ネスト と言います。このプログラムがどのように動いているのか、詳しく見ていきましょう。

  1. 1つ目のfor文 for i in range(10):

    今まで勉強してきたfor文です。range()の中身の数字の回数だけ、for文の中身をくりかえします。

  2. 何回目のくりかえしなのかをチャットに表示 mc.postToChat(i)

    くりかえしの回数がわかりやすいように、チャット画面に変数iの中身を表示しています。range(10)の場合は、iには最初に0が代入され、くりかえしが進むたびに、1, 2, ... , 9まで増えていくのでした。

  3. 2つ目のfor文 for j in range(5):

    for文の中でさらにfor文を使います。この場合、range(5)なので5回くりかえされるわけですが、1つめのfor文の中なので、これ自体が10回くりかえされます。ややこしいですが、「5回くりかえす」ことを「10回くりかえす」ので、「5 × 10 = 50回くりかえす」ことになるのです。

    変数jには、くりかえすたびに0, 1, 2, 3, 4が順番に代入されていきます。

  4. 0.5秒ずつ待つ time.sleep(0.5)

    くりかえされている順番がわかりやすいように、一回ずつ少し待ってから実行するようにしています。

  5. 羊毛ブロックを置く mc.setBlock(x + j, y + i, z, 35, i)

    ここではくりかえしの回数に応じた位置に、羊毛ブロックを置いています。i0から9まで変化していくごとに、j0から4まで増えていきます。

    プログラムを実行すると、このmc.setBlock()メソッドは、

    • mc.setBlock(x + 0, y + 0, z, 35, 0)
    • mc.setBlock(x + 1, y + 0, z, 35, 0)
    • mc.setBlock(x + 4, y + 0, z, 35, 0)
    • mc.setBlock(x + 0, y + 1, z, 35, 1)
    • mc.setBlock(x + 1, y + 1, z, 35, 2)

    • mc.setBlock(x + 3, y + 9, z, 35, 9)
    • mc.setBlock(x + 4, y + 9, z, 35, 9)

    というように変わっていきます。

# リストのリスト

for文とは少し話が離れますが、リストの少し応用的な使い方を知っておきましょう。

データを番号付きでまとめるためのリストですが、その中身には文字列や数値だけでなく、下のように別のリストも入れることができます。

# 友達の"名前"、"性別"、"年齢"をまとめたリスト
friends = [["Tarou", "male", 14], ["Hanako", "female", 15], ["Takashi", "male", 13]]

例えば、friends[1]のように番号を指定すると、その番号のリストが呼び出されます。この場合ならば["Hanako", "female", 15]ですね。

またリストのリストは横に広がって見づらくなりやすいので、下のように書いて見やすくすることも可能です。

friends = [
  ["Tarou", "male", 14],
  ["Hanako", "female", 15],
  ["Takashi", "male", 13]
]

# クリーパーを作ろう

さてここまでの内容で、冒頭のクリーパーを作る準備はほとんど整いました。あとは、設計図となるクリーパーのドット絵があると良さそうです。ゲーム上の実物は、緑を中心としたまだら模様をしていますが、今回は簡単にするために、黄緑と黒の2色だけで作ります。

クリーパーのドット絵

これを8×8の羊毛ブロックで作っていきます。羊毛ブロックは、番号35ですが、色を015までで選ぶことができました。

番号 番号
0 8 ライトグレー
1 オレンジ 9 シアン
2 マゼンタ 10 紫色
3 空色 11
4 黄色 12 茶色
5 黄緑色 13
6 ピンク 14
7 グレー 15

今回は、5の黄緑と、15の黒を使って、一つ一つのドットをブロックに置き換えていきます。

色番号のついた、クリーパーのドット絵

クリーパーを、8つのブロック行が、縦に8つ積み重なったものだと考えます。それぞれの行にあるブロックの色番号をリストにすると、例えば一番上の行は[5, 5, 5, 5, 5, 5, 5, 5]、一番下の行は、[5, 5, 15, 5, 5, 15, 5, 5]といった感じになります。こうすると、クリーパーを、各行のリストがまとまったリストとして表すことができそうです。

creeper_colors = [
    [5, 5, 5, 5, 5, 5, 5, 5],
    [5, 5, 5, 5, 5, 5, 5, 5],
    [5, 15, 15, 5, 5, 15, 15, 5],
    [5, 15, 15, 5, 5, 15, 15, 5],
    [5, 5, 5, 15, 15, 5, 5, 5],
    [5, 5, 15, 15, 15, 15, 5, 5],
    [5, 5, 15, 15, 15, 15, 5, 5],
    [5, 5, 15, 5, 5, 15, 5, 5]
]

あまり面影は感じられませんが、これがクリーパーをつくる各ブロックの色をまとめたものになります。あとは、これを上から一行ずつ羊毛ブロックにしていきます。実際のコードは下のようになります。

import mcpi.minecraft as minecraft

mc = minecraft.Minecraft.create()

x, y, z = mc.player.getPos()

creeper_colors = [
    [5, 5, 5, 5, 5, 5, 5, 5],
    [5, 5, 5, 5, 5, 5, 5, 5],
    [5, 15, 15, 5, 5, 15, 15, 5],
    [5, 15, 15, 5, 5, 15, 15, 5],
    [5, 5, 5, 15, 15, 5, 5, 5],
    [5, 5, 15, 15, 15, 15, 5, 5],
    [5, 5, 15, 15, 15, 15, 5, 5],
    [5, 5, 15, 5, 5, 15, 5, 5]
]

for i in range(8):
    row = creeper_colors[i]
    for j in range(8):
        mc.setBlock(x + j, y + 8 - i, z, 35, row[j])

for文の部分が分かりづらいですので、詳しく見ていきます。

for i in range(8):
  row = creeper_colors[i]

creeper_colorsリストの要素数だけ、for文でくりかえすようにしています。今回は8行のドット絵なので、8行分の色の情報リストが、要素として入っています。それを一つずつ取り出してブロックにしていきたいので、操作は8回くりかえすため、range(8)としています。

変数iには0から7までの数字が順に入っていきますので、くりかえすごとに、変数rowの中身は、creeper_colors[0]からcreeper_colors[7]まで変わっていきます。creeper_colors[0]creeper_colorsリストの0番目なので、[5, 5, 5, 5, 5, 5, 5, 5]ですね。このようにrowの中身は変化していきます。

英単語

「row(ロウ)」は英語で「行」という意味です。対して、列は英語で「column(カラム)」といいます。

次に2つ目のfor文です。

    for j in range(8):
        mc.setBlock(x + j, y + 8 - i, z, 35, row[j])

今度は、各行について、横方向にブロックを並べるために、mc.setBlock()メソッドを8回くりかえすことになります。

mc.setBlock(x + j, y + 8 - i, z, 35, row[j])の引数が難しいですね。

# x座標: x + j

ここが、2つ目のfor文によって変わるポイントになります。jの値が大きくなるのに伴って、ブロックを置く場所がx方向にずれていきますね。

# y座標: y + 8 - i

ブロックを置く高さ、すなわちクリーパーの、上から何行目かを決めています。ここは、最初のfor文で決まっています。上から積んでいくために、まず8を足してからiを引くことで、くりかえすたびにy + 8y + 7、…、y + 1まで1行ずつ下がっていきます。

y + 8の状態で、x座標が大きくなりながら8つブロックを置き、次にy + 7になり、同じくx座標が大きくなり…という流れで、8回×8回の、計64回ブロックを置いていきます。

# z座標: z

z座標は今回はzのままで固定します。あまり考える必要はないでしょう。

# ブロック番号: 35

35は羊毛ブロックでした。羊毛でないといけないわけではないのですが、色の種類が多いので、このような場合には扱いやすいです。

付録0:ブロックの種類番号表

# ブロック種類(色): row[j]

ここでブロックの色を決めます。rowは、1つ目のfor文がくりかえされるたびに、

[5, 5, 5, 5, 5, 5, 5, 5]

[5, 5, 5, 5, 5, 5, 5, 5]

[5, 5, 15, 5, 5, 15, 5, 5]

と変化していくのでした。そして2つ目のfor文がくりかえされるたびに、jの値が大きくなるため、row[j]でで取り出す要素も一つずつずれていきます。これと同時に、x座標も進んでいくので、一つ一つちがう色のブロックを置いていくことができます。(今回は2色しかありませんが…)


for文のネストは慣れるまでとても難しいと思いますが、自分で手を動かして、プログラムを実行して身につけていきましょう。

# 応用編:好きな大きさのドット絵を自在に作るプログラム

今回作成したプログラムは、8×8マス専用のものでしたが、変数を上手く使うことで、簡単に好きな大きさのドット絵を作ることができます。

import mcpi.minecraft as minecraft

mc = minecraft.Minecraft.create()

x, y, z = mc.player.getPos()

colors = [
    [0, 0, 15, 15, 15, 15, 15, 15, 0, 0],
    [0, 15, 4, 4, 4, 4, 4, 4, 15, 0],
    [15, 4, 4, 15, 4, 4, 15, 4, 4, 15],
    [15, 4, 4, 15, 4, 4, 15, 4, 4, 15],
    [15, 4, 4, 4, 4, 4, 4, 4, 4, 15],
    [15, 4, 15, 4, 4, 4, 4, 15, 4, 15],
    [15, 4, 15, 4, 4, 4, 4, 15, 4, 15],
    [15, 4, 4, 15, 15, 15, 15, 4, 4, 15],
    [0, 15, 4, 4, 4, 4, 4, 4, 15, 0],
    [0, 0, 15, 15, 15, 15, 15, 15, 0, 0]
]

height = len(colors)

for i in range(height):
    row = colors[i]
    width = len(row)
    for j in range(width):
        mc.setBlock(x + j, y + height - i, z, 35, row[j])

スマイリーのドット絵

試しに10×10マスのドット絵を作ってみました。

len()を使って、colorsリスト、そこから取り出したrowリストそれぞれの要素数を調べています。こうすることで、8などの決まった数を入力しなくても、好きな大きさのドット絵を作ることができるようになります。

# おわりに

Prosenseではマインクラフトを使ったプログラミングの個別指導もおこなっております。

マンツーマンでレッスンを受けながらマインクラフトでプログラミングを学びたい方はいますぐProsenseのLINE公式アカウントに登録ください。

ProsenseのLINE公式アカウントと友達になる


練習問題