# ドット絵をたくさん作ろう

前の章(同じ像を色々な場所に作ろう)

# 繰り返しと関数を組み合わせる

このテキストの内容も終盤です。ここからは、今まで学んできた内容を組み合わせた、発展的な内容になります。この章では、「ドット絵作成プログラムを作ろう」で学んだドット絵を作る方法と、「同じ像を色々な場所に作ろう」で学んだ関数を組み合わせて、マイクラ内で、下のようにドット絵をたくさん作っていきます。

羊毛ブロックでできた、クリーパー・ゾンビ・スケルトンのドット絵

ドット絵作りには、for文のネストを使いましたが、これを全てのドット絵に対して行うのは大変です。そこで、関数を利用して、同じ操作をまとめてしまおう、というお話になります。

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

クリーパーのドット絵は、下のプログラムで作ることができました。

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])

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

一つ一つのドットの色番号を、1行ずつリストに保管し、それをfor文の中で取り出して、ブロックを置いていくというものでした。

作りたいドット絵によって、creeper_colorsのようなリストの中身はもちろん変わりますが、for文の中で行うことは、他のドット絵のリストでも変わりません。なので、この部分を一つの関数としてまとめてあげることができます。

# for文を使う関数

早速、for文の部分を関数にしていきます。関数の名前は、ドット絵を「描く」ので、drawにしましょう。

英単語

「draw」は英語で「(絵や図を)描く」という意味です。対して、「(文字を)書く」場合は「write」を使うことが多いです。

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

まるごとdefから始まるdraw関数の定義の中に入れてあげます。中の各行のインデントを下げることに注意してください。

draw関数の引数は、xyzcolorsの4つです。xyzは、「どこからドット絵を描き始めるか」というスタート地点の座標になります。これまでは、プレイヤーの現在の座標をそのまま使っていました。colorsは、それまでcreeper_colorsとしていた部分です。クリーパー以外のドット絵が入る可能性があるので、ただのcolorsとしています。

これを使って先ほどのコードを書き直してみます。

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]
]


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


draw(x, y, z, creeper_colors)

最後の行でdraw(x, y, z, creeper_colors)という形で、draw関数を呼び出しています。結果は以前のものと変わりませんが、ポイントは、draw関数と定義することで、ドット絵を作る操作を何度でも呼び出せるようになったということです。

# 各Mobのドット絵

今回のプログラムでは、マインクラフトのMobである「クリーパー」、「ゾンビ」、「スケルトン」をまとめて作っていきます。手順としては、

  1. ドット絵を用意して色番号を確認
  2. その番号をリストにまとめる
  3. draw関数の引数として呼び出す

という流れになります。3については最後に3つまとめて行うので、まずは色番号を確認してリストにまとめていきましょう。

# クリーパー

# 色番号

以前作ったものよりも色を追加して、より実物に近づけています。(近づいてます…よね?)使える色自体は多くないので、どこまでこだわれるか、というところです。

クリーパーの色番号つきドット絵

# リスト

色番号を、上の行から順にリストにまとめていきます。

creeper_colors = [
    [5, 13, 5, 5, 0, 5, 5, 13],
    [13, 5, 5, 5, 13, 5, 5, 0],
    [5, 15, 15, 5, 13, 15, 15, 0],
    [5, 15, 15, 5, 5, 15, 15, 5],
    [5, 5, 5, 15, 15, 0, 13, 5],
    [5, 13, 15, 15, 15, 15, 5, 5],
    [0, 13, 15, 15, 15, 15, 5, 13],
    [5, 5, 15, 5, 5, 15, 13, 5]
]

# 完成図

もし単体で呼び出すと、このようになります。

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

# ゾンビ

# 色番号

ゾンビの色番号付きドット絵

# リスト

zombie_colors = [
    [13, 13, 13, 13, 13, 13, 13, 13],
    [13, 13, 13, 13, 5, 5, 13, 13],
    [13, 5, 5, 5, 5, 5, 5, 5],
    [5, 5, 5, 5, 13, 5, 5, 5],
    [5, 15, 15, 5, 5, 15, 15, 5],
    [5, 5, 5, 13, 13, 5, 5, 13],
    [5, 5, 13, 5, 5, 13, 5, 13],
    [13, 13, 13, 13, 13, 13, 5, 13]
]

# 完成図

羊毛ブロックで作ったゾンビのドット絵

# スケルトン

# 色番号

スケルトンの色番号付きドット絵

# リスト

skeleton_colors = [
    [7, 7, 7, 7, 7, 7, 7, 7],
    [7, 7, 7, 7, 8, 8, 7, 7],
    [7, 8, 8, 8, 8, 8, 8, 7],
    [8, 8, 8, 8, 7, 8, 8, 8],
    [8, 15, 15, 8, 8, 15, 15, 8],
    [8, 8, 8, 7, 7, 8, 8, 7],
    [8, 15, 15, 15, 15, 15, 15, 7],
    [7, 7, 7, 7, 7, 7, 7, 7]
]

# 完成図

羊毛ブロックで作ったスケルトンのドット絵

# draw関数で簡単に作ろう

これらのMob達をすべて一気に作ってしまいましょう。プログラムは下のようになります。

import mcpi.minecraft as minecraft

mc = minecraft.Minecraft.create()

creeper_colors = [
    [5, 13, 5, 5, 0, 5, 5, 13],
    [13, 5, 5, 5, 13, 5, 5, 0],
    [5, 15, 15, 5, 13, 15, 15, 0],
    [5, 15, 15, 5, 5, 15, 15, 5],
    [5, 5, 5, 15, 15, 0, 13, 5],
    [5, 13, 15, 15, 15, 15, 5, 5],
    [0, 13, 15, 15, 15, 15, 5, 13],
    [5, 5, 15, 5, 5, 15, 13, 5]
]

zombie_colors = [
    [13, 13, 13, 13, 13, 13, 13, 13],
    [13, 13, 13, 13, 5, 5, 13, 13],
    [13, 5, 5, 5, 5, 5, 5, 5],
    [5, 5, 5, 5, 13, 5, 5, 5],
    [5, 15, 15, 5, 5, 15, 15, 5],
    [5, 5, 5, 13, 13, 5, 5, 13],
    [5, 5, 13, 5, 5, 13, 5, 13],
    [13, 13, 13, 13, 13, 13, 5, 13]
]

skeleton_colors = [
    [7, 7, 7, 7, 7, 7, 7, 7],
    [7, 7, 7, 7, 8, 8, 7, 7],
    [7, 8, 8, 8, 8, 8, 8, 7],
    [8, 8, 8, 8, 7, 8, 8, 8],
    [8, 15, 15, 8, 8, 15, 15, 8],
    [8, 8, 8, 7, 7, 8, 8, 7],
    [8, 15, 15, 15, 15, 15, 15, 7],
    [7, 7, 7, 7, 7, 7, 7, 7]
]


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


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

draw(x, y, z, creeper_colors)
draw(x + 9, y, z, zombie_colors)
draw(x + 18, y, z, skeleton_colors)

まずMobのリストを全て準備し、それを描くためのdraw関数を定義します。その後、いつものように座標を調べるたのち、draw関数を3回呼び出すプログラムです。

draw関数の引数colorsに、creeper_colorszombie_colorsskeleton_colorsを入れることで、それぞれのドット絵を作ってくれます。呼び出す時に、x方向に9ずつ座標をずらして、3つのドット絵がキレイに横並びになるようにしています。

羊毛ブロックでできた、クリーパー・ゾンビ・スケルトンのドット絵

draw関数を使わなければ、ややこしいfor文のネストを3回も書かなければならず、面倒ですし、ミスのもとです。それに、もっとたくさんのドット絵を作りたいときにも再利用できます。

# おわりに

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

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

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


練習問題