【音あり注意】懐かしのテトリス風

,,
コードはこちらから。ちょっと長いです。
  • スプライトとしてブロックが落ちてくる
  • ブロックが底か他のブロックに当たると止まる
  • 止まると次のブロックが落ちてくる
  • 止まった時に一行隙間なくそろうと行が消える
  • 行が消えると上のブロックが下に落ちる
  • 止まった時に高さが一杯だとゲームオーバー
  • BGMを鳴らす

マイクラMakeCode チュートリアル紹介

,,
前回はMakeCodeを使いWindows10版のマイクラでプログラミングする記事を書きました。MakeCodeのサイトにはたくさんのチュートリアル(サンプル)が紹介されています。今回は面白そうなものをいくつか、実際に実行してみながら紹介してみます。

1.超ジャンプ(mega jump)

チャットコマンドに jump 10 のように入力すると、好きな高さまでジャンプできるプログラムです。10は好きな数字でOKです。 使うブロックも2個だけで、シンプルなコードです。num1という変数に入力した高さが入ってきます。では飛んでみましょう。 ちなみに高さ23以上にジャンプすると命の保証ができません・・・。

2.足跡に咲く花(flower trail)

こちらもシンプルです。 プレイヤーが歩いたら、というブロックを使っています。花の種類や、咲かせる場所を変えたりできますね。 息子君と一緒に、足跡に湧くスライムというプログラムを作ったら大変なことになりました。

3.1000TNT

すぐにこういう悪いコトをしてみたくなりますね。ブロックのまとめて置いています。10☓10☓10で1000個ですね。 ちょっと長くなってしまいますが、繰り返しを使って同じコードを書くこともできます。 実行してみると流石に迫力があります。 火遊びはイケナイと知りつつも・・・・、あ~ぁ、この世の終わりです。

MakeCodeでマイクラプログラミング

,
マイクロソフトはMakeCodeというサービスを提供しています。MakeCodeはmicro:bitのコードエディタになっています。
Microsoft MakeCode brings computer science to life for all students with fun projects, immediate results, and both block and text editors for learners at different levels. (意訳) Microsoft MakeCodeは全ての生徒にワクワクするようなコンピュータ・サイエンスの学びを提供します。楽しいプロジェクト、すぐに実行できる環境、様々なレベルに対応するブロック型とテキスト型のコードエディタがあります。
2017年10月23日に、マインクラフトが追加されました。マインクラフトのWindows10版またはEducation Editionがあれば、MakeCodeからマイクラの世界をプログラミングできます。Java版(PC)を購入済みの方はWindows10版をインストールすることができます。 [Minecraft] Java版所有者が無料でWindows10版をダウンロードする手順 Chicken Rainのチュートリアルで、導入の手順を見ておきます。 始めるとすぐに「マイクラとつながっていません、コードコネクトAppを入れて下さい」と英語で表示されます。早く日本語化して欲しいですね。 「Download the App」を押すと今度はこんな画面になります(また英語)。 「Download Code Connection」を押してダウンロードして下さい。終わると「CodeConnection.msi」がありますのでインストールします。インストールが終わると「Code Connection for Minecraft」というショートカットが作成されますので、実行します。こんな画面が表示されると思います。 コピーボタンを押して、コマンドをコピーしておきます。 続いて、プログラミングしたいマイクラの世界を起動します。設定を確認して、チートを有効にしておいて下さい。 マイクラの中で「tキー」を押してチャットを開き、先ほどコピーしたコマンドをペーストして実行します。 するとCodeConnectionがこんな画面になります。 MakeCode以外にも色々接続できるようですね。今回はMakeCodeボタンを押します。 さて準備ができたので、Chicken Rainに戻るとこんな感じのコードを組むことになります。 早速実行してみましょう。「tキー」を押して、チャットを開きchickenと入力します。 大量のニワトリが・・!! MakeCodeのマイクラプログラミングはかなり高度なことができそうです。 全て使うのは大変なくらいブロックが揃っています。

プレイヤー

[su_accordion] [su_spoiler title="トリガー" open="yes" style="default" icon="plus" anchor="" class=""]
  • チャットコマンドを入力した時
  • 歩いた・泳いだ・落下した・登っている・飛んだ・スニークした・走った・バウンドした時
  • 死んだ時
  • 矢を放った時
  • テレポートした時
[/su_spoiler] [su_spoiler title="アクション" open="yes" style="default" icon="plus" anchor="" class=""]
  • メッセージを送信する
  • 現在の位置からテレポートする
  • コマンドを実行する
  • チャットコマンドを実行する
[/su_spoiler] [/su_accordion]

ブロック

[su_accordion] [su_spoiler title="トリガー" open="no" style="default" icon="plus" anchor="" class=""]
  • ブロックが置かれた時
  • ブロックが壊された時
[/su_spoiler] [su_spoiler title="アクション" open="no" style="default" icon="plus" anchor="" class=""]
  • ブロックを置く
  • ブロックをまとめて並べる
  • ブロックで文字を描く
  • レバー・リピーターを操作する
  • ブロックをコピーする
[/su_spoiler] [/su_accordion]

生き物

[su_accordion] [su_spoiler title="トリガー" open="no" style="default" icon="plus" anchor="" class=""]
  • 行動不能になった時
[/su_spoiler] [su_spoiler title="アクション" open="no" style="default" icon="plus" anchor="" class=""]
  • スポーンする
  • 行動不能にする
  • エンチャントする
  • ブロック・アイテムを渡す
[/su_spoiler] [/su_accordion]

エージェント

[su_accordion] [su_spoiler title="アクション" open="no" style="default" icon="plus" anchor="" class=""]
  • 自分の位置に連れてくる
  • 移動させる
  • 向きを変える
  • ブロックを置く
  • 拾わせる
  • 攻撃する
  • 破壊させる
  • 耕させる
[/su_spoiler] [/su_accordion]

ゲームプレイ

[su_accordion] [su_spoiler title="アクション" open="no" style="default" icon="plus" anchor="" class=""]
  • 天気を変える
  • 時間を設定する
  • 難易度を変える
  • ゲームモードを変える
  • 経験値をあげる
[/su_spoiler] [/su_accordion]

ビルダー

[su_accordion] [su_spoiler title="アクション" open="no" style="default" icon="plus" anchor="" class=""]
  • 移動させる
  • 向きを変える
  • マーカーを置く
  • テレポートする
  • ブロックでう埋める
  • ブロックで線を引く
  • ブロックで壁を作る
[/su_spoiler] [/su_accordion]

シェイプ

[su_accordion] [su_spoiler title="アクション" open="no" style="default" icon="plus" anchor="" class=""]
  • ブロックで線を描く
  • ブロックで円を描く
  • ブロックで球を作る
[/su_spoiler] [/su_accordion]

拡張機能

剣で空を飛ぶ!

,,,
今回はpollBlockHitsという、触ったブロックを検出するプログラムを使って空を飛でみます。まずは、こんなコードを実行してみます。 [python] import mcpi.minecraft as minecraft import time mc = minecraft.Minecraft() while True: hits = mc.events.pollBlockHits() if hits: for h in hits: mc.postToChat(h.pos.x) mc.postToChat(h.pos.y) mc.postToChat(h.pos.z) mc.postToChat(h.face) mc.postToChat(h.type) mc.postToChat(h.entityId) time.sleep(0.1) [/python] whileループで繰り返しながら、pollBlockHitsをしています。 このpollBlockHits、利き手に剣を持った状態で、右クリック(ブロックを置くのと同じ操作)すると、そのイベントが記録されます。どんな感じに記録されるかと言うと、 チャットに出力したように、 -93  1  55  7  0  216 こんな感じで記録されます。これは順番に触ったブロックの
  • x座標
  • y座標
  • z座標
  • 方向
  • イベントタイプ(いつも0)
  • エンティティID(今度詳しく)
です。 さて、このpollBlockHitsを使って、何回かに渡って面白いことをやってみましょう。今日は飛んでみます。コードはこんな感じ。 [python] import mcpi.minecraft as minecraft import time import mcpi.block as block from mcpi.vec3 import Vec3 mc = minecraft.Minecraft() def fly(): while True: if len(mc.events.pollBlockHits()): mc.player.setPos(mc.player.getPos() + Vec3(0,3,0)) time.sleep(0.1) fly() [/python] pollBlockHitsのイベントの中身は見ていませんが、イベントがあったか(右クリックしたかどうか)だけをみて、あったら主人公を上に飛ばしています。右クリックしたら飛ぶってことですね。飛んでみると、 おぉー飛んだ。まだまだ飛んだ! 飛びすぎかな~~、あ、落ちた! あ~あ、死んじゃいました。飛びすぎには注意ですね。着地は水の上がいいかもしれません。 [amazon_link asins='1119269067,3864903734,4800711657,4839960488,479814911X,4800711274' template='ProductCarousel' store='kikushun-22' marketplace='JP' link_id='8fc8bd6a-4ea4-11e7-9891-d399843555be']

鉱石吸い出しの術

,,,
前回は地面スケスケの術を使って、主人公の足元の貴重な鉱石を見えるようにしました。今回はもっと簡単に鉱石が手に入るプログラムを作っていきます。鉱石吸い出しの術です。巨大なブタさんを動かした時に使ったMinecraftShapeを使います。コードはこんな感じです。 [python] import mcpi.minecraft as minecraft import mcpi.minecraftstuff as stuff import mcpi.block as block from mcpi.vec3 import Vec3 mc = minecraft.Minecraft() pos = mc.player.getTilePos() def vacuumeMetal(start, dist, target): metalBlocks = [] for y in range(0, dist.y): for x in range(0, dist.x): for z in range(0, dist.z): blk = mc.getBlock(start.x + x, start.y + y, start.z + z) if blk in target: metalBlocks.append(stuff.ShapeBlock(x, y, z, blk)) mc.setBlock(start.x + x, start.y + y, start.z + z, block.AIR) metalShape = stuff.MinecraftShape(mc, pos + Vec3(-dist.x/2, 0, -dist.z/2), metalBlocks) target = [ block.IRON_ORE.id, block.GOLD_ORE.id, block.DIAMOND_ORE.id, block.REDSTONE_ORE.id, block.EMERALD_ORE.id, block.LAPIS_LAZULI_ORE.id] vacuumeMetal(pos + Vec3(-10, -64, -10), Vec3(20, 64, 20), target) [/python] 早速実行してみますが、その前にスケスケの術を使ってどこに鉱石があるのか確認してみます。 見えますね。かなりの量の鉄があることが分かります。では、今回の吸い出しの術を実行してみます。 どうでしょう。鉱石がきれいサッパリと無くなっているのが分かります。では鉱石はどこにいってしまったのでしょうか。主人公の頭上を見てみると、 おぉー!たくさんの鉱石が!それにダイヤもあったんですね。これらの鉱石はもう堀り放題です。

地面スケスケの術

,,,
前回は金属探知機ということで、主人公の足元に鉱石があるかをチャットするプログラムを作りました。今回は、もっと簡単に鉱石を発見できるプログラムを作ってみます。その名も地面スケスケの術。一言でいうと、地面の土や石ブロックを一瞬でガラスに変えてしまいます。 [python] import mcpi.minecraft as minecraft import mcpi.block as block import time from mcpi.vec3 import Vec3 mc = minecraft.Minecraft() def makeDirt2Glass(start, dist): for y in range(0, dist.y): for x in range(0, dist.x): for z in range(0, dist.z): blk = mc.getBlock(start.x + x, start.y + y, start.z + z) if blk in [block.GRASS.id, block.DIRT.id, block.STONE.id, block.GRAVEL.id]: mc.setBlock(start.x + x, start.y + y, start.z + z, block.GLASS) pos = mc.player.getTilePos() makeDirt2Glass(pos + Vec3(-10, -64, -10), Vec3(20, 64, 20)) [/python] 実行してみると、こんな感じになります。 ガラスを壊して進んでいきます。今回はなんと廃坑も発見できました。鉱石探し以外にも効率がアップできそうです。 深いところに進むと鉱石の種類が増えてきます。見渡すだけでも
  • 石炭
  • レッドストーン
  • エメラルド
  • ダイヤモンド
が見つけられます。 ここまででも十分にゲームバランスがおかしいですが、次回はさらに効率化してみます。

なんでも金属探知機

,,,
マインクラフトのサバイバルモードでは、素材集めが大切です。特に鉄や金、ダイヤなどの貴重なブロックはとても重要です。でも数が少ないので探すのが大変。ということで、今回は、プログラミングの力で、あっという間に貴重なブロックを探せるようにしてみます。 [python] import mcpi.minecraft as minecraft import mcpi.block as block import time from mcpi.vec3 import Vec3 mc = minecraft.Minecraft() def scanIron(depth): for y in range(0, depth): pos = mc.player.getTilePos() blk = mc.getBlock(pos.x, pos.y - y, pos.z) if blk == block.IRON_ORE.id: mc.postToChat("Iron! y=" + str(-y)) while True: scanIron(64) time.sleep(1) [/python] 主人公の足元のブロックを深さ128まで、鉄鉱石のブロックIDがあるか探して、見つかったらチャットするというプログラムを書きました。それをwhile True:で繰り返し続けています。while True:の無限ループから抜けてプログラムを終了するにはctrlキーとcキーを一緒に押してください。さて実行しながら歩いてみましょうか。見つかるでしょうか。 おおっ!?あります。今足元に鉄鉱石があるはずです。 主人公からの深さチャットしているので、掘り進むと数字が小さくなります。 そして、ついに・・・ 出たー!! 続けて、プログラムをちょっと改良して、鉄鉱石以外にも、金鉱石、ダイヤモンド鉱石にも反応するようにしてみました。 [python] def scanTarget(depth, target): for y in range(0, depth): pos = mc.player.getTilePos() blk = mc.getBlock(pos.x, pos.y - y, pos.z) if blk in target: mc.postToChat(target[blk] + "! " + str(-y)) while True: scanTarget(128, target) time.sleep(1) [/python] さてどうでしょうか。 こんなに簡単にダイヤモンドを見つけることができてしまいます。 普通のマインクラフトのサバイバルでは、ダイヤモンドを探すのにブランチマイニングなどをして、ずーっと石を掘り続けないといけないですが、こんな簡単に見つけることができます。次回はもっと簡単に貴重なブロックを「見える」ようにしてみます。

進撃の巨大ブタさん

,,
今回は3Dカラープリンターの時に作った巨大なブタさんを動かしてみます。 ブロックを動かすには、minecraftstuff.pyというものを使います。Martin O'Hanlonさんというイギリスの方が作成して、こちらで紹介されています。 minecraftstuff.pyを手に入れて、mcpiフォルダの中に入れておいてください。まずはブロックの動かし方です。2×2×2の赤いサイコロを作って動かします。 [python] import mcpi.minecraft as minecraft import mcpi.minecraftstuff as stuff import mcpi.block as block import time from mcpi.vec3 import Vec3 mc = minecraft.Minecraft() pos = mc.player.getTilePos() cubelocks = [ stuff.ShapeBlock(0,0,0,block.REDSTONE_BLOCK), stuff.ShapeBlock(1,0,0,block.REDSTONE_BLOCK), stuff.ShapeBlock(0,1,0,block.REDSTONE_BLOCK), stuff.ShapeBlock(0,0,1,block.REDSTONE_BLOCK), stuff.ShapeBlock(1,1,0,block.REDSTONE_BLOCK), stuff.ShapeBlock(0,1,1,block.REDSTONE_BLOCK), stuff.ShapeBlock(1,0,1,block.REDSTONE_BLOCK), stuff.ShapeBlock(1,1,1,block.REDSTONE_BLOCK) ] cubeShape = stuff.MinecraftShape(mc, pos + Vec3(5,5,5), cubelocks) for i in range(0, 20): time.sleep(0.5) cubeShape.moveBy(1,0,0) cubeShape.clear() [/python] こんな赤いサイコロが まで進んでいきます。 さて、いよいよブタさんを動かします。コードはこんな感じです。 [python] import mcpi.minecraft as minecraft import mcpi.minecraftstuff as stuff import mcpi.block as block import time import csv from mcpi.vec3 import Vec3 mc = minecraft.Minecraft() pos = mc.player.getTilePos() def shape3D(start, data, inc): shape = [] for y in range(0,len(data)): for z in range(0,len(data[y])): for x in range(0,len(data[y][z])): if data[y][z][x] != 0: shape.append(stuff.ShapeBlock(x,y,z,inc[data[y][z][x]])) return shape; inc_pig = {1:block.WOOL_PINK, 2:block.WOOL_BROWN, 3:block.WOOL_BLACK, 4:block.WOOL_WHITE, 5:block.WOOL_RED} data =[] with open('pig.csv', 'r') as f: file = csv.reader(f) plane = [] for line in file: if len(line) == 0: data.append(plane) plane = [] else: plane.append(line) data.append(plane) data_conved = [[[int(elm) for elm in l] for l in p] for p in data] pigBlocks = shape3D(mc.player.getPos() + Vec3(1,0,1), data_conved, inc_pig) pigShape = stuff.MinecraftShape(mc, pos + Vec3(-10,0,5), pigBlocks) for i in range(0, 100): time.sleep(0.2) pigShape.moveBy(-1,0,0) pigShape.clear [/python] shapeを作るところは、カラープリンターの時のprint3Dとほとんど同じです。 では、 おおー、本当にブタさんが進んでいきます。ブタさんのぶつかった所はブロックが無くなってしまうみたいです。

3Dスキャナとプリンターでなんでもコピー

,,
前回はカラー3Dプリンターを作りました。今回はスキャナーを作ります。積み上げられているブロックの範囲を指定して、スキャン。スキャンしたデータを使って、好きな場所に3Dプリントするという流れでやっていきます。 まず、スキャンする相手ですが、前回作ったブタさんにします。 [python] import mcpi.minecraft as minecraft import mcpi.block as block from mcpi.vec3 import Vec3 mc = minecraft.Minecraft() class Obj3D: def __init__(self, data, ink): self.data = data self.ink = ink def getData(self): return self.data def getInk(self): return self.ink def scan3D(start, dist): data = [] ink_inv={} for y in range(0, dist.y): plane=[] for z in range(0, dist.z): line=[] for x in range(0, dist.x): blk = mc.getBlockWithData(start.x + x, start.y + y, start.z + z) if not blk in ink_inv: ink_inv[blk] = len(ink_inv) line.append(ink_inv[blk]) plane.append(line) data.append(plane) ink = {v:k for k, v in ink_inv.items()} obj = Obj3D(data, ink) return obj def print3D(start, data, inc): for y in range(0, len(data)): for z in range(0, len(data[y])): for x in range(0, len(data[y][z])): if data[y][z][x] != 0: mc.setBlock(start.x + x, start.y + y, start.z + z, inc[data[y][z][x]]) start = mc.player.getTilePos() obj = scan3D(start, Vec3(20, 20, 20)) [/python] こんな感じでブタさんをスキャンします。scan3Dではデータとインクの2つを戻したいので、クラスとしてObj3Dを作って、そのオブジェクトを戻しています。 [python] ink = {v:k for k, v in ink_inv.items()} [/python] はink_invのキーと値を入れ替えて、インクを作っています。 ポイントになるのが、主人公の向き(方角)です。F3を押して、eastになっていると読み込みやすいです。 読み取ったデータをprintしてみると、 [0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3, 3, 0, 0, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3, 3, 0, 0, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3, 3, 0, 0, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3, 3, 0, 0, 0, 0, 0] [0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0] この部分はブタさんの足のウラですね。 スキャンできているので、このデータをプリントしてみます。 無事にブタさんがコピーできました。続いて、自分で積んだブロックをスキャンしてみます。頑張って新しく羊さんを作っておきました。 ブタさんと同じようにスキャンしてプリントできるはずですが、スキャンした後、ブタさんのpigのようにファイルに出力してみます。では実行します。 見事に羊さんもコピーされました。ファイルはsheep.csvです。 と作ってきました。これがあれば、csvで設計した形や、目の前の形をいつでもコピー(スキャンして、プリントすることができます。クリーパー(creeper.csv)などの敵キャラも形を作ってからコピーできますし、 氷原のような珍しい地形(バイオーム)を草原の中に持ってくることもできます。