Minecraft PI EDITIONへブロック取得APIと、pythonのvisualライブラリを使って描いた画像です。
Minecraftは始めたばかりで操作もままならず、その真の面白さに到達できる気がしていませんが、APIを使うのは面白いなあと感じております。このままゲームの面白さではなくコマンドライナーとしての面白さを追求していきたいと思っています。
では、Minecraft PI EDITIONをダウンロードして実行します。
pi@raspberrypi:~/Downloads $ wget https://s3.amazonaws.com/assets.minecraft.net/pi/minecraft-pi-0.1.1.tar.gz pi@raspberrypi:~/Downloads $ tar xzf minecraft-pi-0.1.1.tar.gz -C ~/ pi@raspberrypi:~/Downloads $ cd ~/mcpi pi@raspberrypi:~/mcpi $ ./minecraft-pi
Minecraftを起動したら、別の端末ウィンドウにて、
pi@raspberrypi:~/mcpi $ cd api/python/mcpi
各APIは、本ディレクトリ内にあるminecraft.pyに記載されています。たとえばブロック関連のAPIを確認するには、’def.*Block’で検索すれば良いです
pi@raspberrypi:~/mcpi/api/python/mcpi $ grep -A3 'def.*Block' minecraft.py def pollBlockHits(self): """Only triggered by sword => [BlockEvent]""" s = self.conn.sendReceive("events.block.hits") events = [e for e in s.split("|") if e] -- def getBlock(self, *args): """Get block (x,y,z) => id:int""" return int(self.conn.sendReceive("world.getBlock", intFloor(args))) def getBlockWithData(self, *args): """Get block with data (x,y,z) => Block""" ans = self.conn.sendReceive("world.getBlockWithData", intFloor(args)) return Block(*map(int, ans.split(","))) -- def getBlocks(self, *args): """Get a cuboid of blocks (x0,y0,z0,x1,y1,z1) => [id:int]""" return int(self.conn.sendReceive("world.getBlocks", intFloor(args))) def setBlock(self, *args): """Set block (x,y,z,id,[data])""" self.conn.send("world.setBlock", intFloor(args)) def setBlocks(self, *args): """Set a cuboid of blocks (x0,y0,z0,x1,y1,z1,id,[data])""" self.conn.send("world.setBlocks", intFloor(args)) pi@raspberrypi:~/mcpi/api/python/mcpi $
ブロックのIDは、block.pyに書かれています。’スペース2個=’でgrepするとうまい具合に一覧が取得できます。
pi@raspberrypi:~/mcpi/api/python/mcpi $ grep ' =' block.py AIR = Block(0) STONE = Block(1) GRASS = Block(2) DIRT = Block(3) COBBLESTONE = Block(4) WOOD_PLANKS = Block(5) SAPLING = Block(6) BEDROCK = Block(7) WATER_FLOWING = Block(8) WATER = WATER_FLOWING WATER_STATIONARY = Block(9) LAVA_FLOWING = Block(10) LAVA = LAVA_FLOWING LAVA_STATIONARY = Block(11) SAND = Block(12) GRAVEL = Block(13) GOLD_ORE = Block(14) IRON_ORE = Block(15) COAL_ORE = Block(16) WOOD = Block(17) LEAVES = Block(18) GLASS = Block(20) LAPIS_LAZULI_ORE = Block(21) LAPIS_LAZULI_BLOCK = Block(22) SANDSTONE = Block(24) BED = Block(26) COBWEB = Block(30) GRASS_TALL = Block(31) WOOL = Block(35) FLOWER_YELLOW = Block(37) FLOWER_CYAN = Block(38) MUSHROOM_BROWN = Block(39) MUSHROOM_RED = Block(40) GOLD_BLOCK = Block(41) IRON_BLOCK = Block(42) STONE_SLAB_DOUBLE = Block(43) STONE_SLAB = Block(44) BRICK_BLOCK = Block(45) TNT = Block(46) BOOKSHELF = Block(47) MOSS_STONE = Block(48) OBSIDIAN = Block(49) TORCH = Block(50) FIRE = Block(51) STAIRS_WOOD = Block(53) CHEST = Block(54) DIAMOND_ORE = Block(56) DIAMOND_BLOCK = Block(57) CRAFTING_TABLE = Block(58) FARMLAND = Block(60) FURNACE_INACTIVE = Block(61) FURNACE_ACTIVE = Block(62) DOOR_WOOD = Block(64) LADDER = Block(65) STAIRS_COBBLESTONE = Block(67) DOOR_IRON = Block(71) REDSTONE_ORE = Block(73) SNOW = Block(78) ICE = Block(79) SNOW_BLOCK = Block(80) CACTUS = Block(81) CLAY = Block(82) SUGAR_CANE = Block(83) FENCE = Block(85) GLOWSTONE_BLOCK = Block(89) BEDROCK_INVISIBLE = Block(95) STONE_BRICK = Block(98) GLASS_PANE = Block(102) MELON = Block(103) FENCE_GATE = Block(107) GLOWING_OBSIDIAN = Block(246)
getBlock(x,y,z)を使い、指定座標のブロックIDを取得してみます。
pi@raspberrypi:~/mcpi/api/python/mcpi $ python -c' > import minecraft > mc=minecraft.Minecraft.create() > print mc.getBlock(0,0,0) > ' 1 pi@raspberrypi:~/mcpi/api/python/mcpi $
結果に1が表示されましたが、これがブロックIDです。上でgrepしたように、1はSTONEのブロックです。
getBlockを使い、連続で100個ほど取得してみましょう。
pi@raspberrypi:~/mcpi/api/python/mcpi $ python -c' > import minecraft > mc=minecraft.Minecraft.create() > for x in range(0,100): > print mc.getBlock(x,0,0) > ' | pr -t10 | expand 1 1 1 1 1 1 1 1 1 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 15 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 pi@raspberrypi:~/mcpi/api/python/mcpi $
あれ、何か変です。実際にやってみると分かりますが、少し重たく感じます。
出力をしないようにして、時間計測してみます。
pi@raspberrypi:~/mcpi/api/python/mcpi $ time python -c' > import minecraft > mc=minecraft.Minecraft.create() > for x in range(0,100): > mc.getBlock(x,0,0) ' real 0m5.086s user 0m0.240s sys 0m0.030s pi@raspberrypi:~/mcpi/api/python/mcpi $
5秒かかりました。
5秒ぐらい、と思うかもしれませんが、Minecraftのマップは3次元ですので、
yもzも100個分とすると、 5秒 x 100 x 100 =
~$ bc <<< '5*100*100' 50000 ~$ !!'/60/60' bc <<< '5*100*100''/60/60' 13 ~$
上記コマンドの結果のとおり、50000秒、つまり13時間となります。
取得する空間を小さくして実験してみましょう。
pi@raspberrypi:~/mcpi/api/python/mcpi $ time python -c' > import minecraft > mc=minecraft.Minecraft.create() > for x in range(0,10): > for y in range(0,10): > for z in range(0,10): > print mc.getBlock(x,y,z) ' | pr -t10 | expand > data.txt real 0m50.165s user 0m1.250s sys 0m0.350s pi@raspberrypi:~/mcpi/api/python/mcpi $
約50秒でした。これぐらいなら待てます。
取得したデータを確認してみます。
pi@raspberrypi:~/mcpi/api/python/mcpi $ head data.txt 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 pi@raspberrypi:~/mcpi/api/python/mcpi $
ブロックは同じ種類のIDが固まって地形を形成していますので、このように冗長なデータとなります。
(その2へ続く)
コメント
Thanks, I was doing a google search and your site came up for homes for rent in Altamonte Springs, FL but anyway, I have enjoyed reading it, keep it up!