2017年12月14日木曜日

Minecraft でお家を自動構築してみた

概要

前回までに紹介している minecraft-pi-ruby を使ってそれっぽい家をコマンド一発で作成してみました
所謂チートになるのでメインのワールドではなく遊びで作ったワールドで試すことをおすすめします
なお使うには Forge + Raspberry Jam Mod が必要になるのでまだの方は以下を参考にインストールしてください

環境

  • macOS X 10.13.2
  • Minecraft 1.12.2
  • Forge 1.12.2 - 14.23.1.2555
  • Raspberry Jam 0.93
  • Ruby 2.4.1p111
  • minecraft-pi-ruby 0.0.1

スクリプト

幅 10 高さ 6 奥行き 10 の家を立てます
内装もそれっぽくしています
基本は座標情報を作成して set_block で適切なブロックを配置していきます
初めに土地を整地してから建築しています
今回は 1F 分しか作っていませんが同じように 2F を作ったり地下を作成したりもできると思います
あと庭とか牧場とかも自動で構築できると思います

# coding: utf-8
require 'minecraft-pi-ruby'

class House
  def initialize
    @mc = Minecraft.new
    @base = @mc.get_player_position
  end

  def f1
    front
    right_side
    left_side
    back
    proof
    stairs
    furniture
  end

  def clear
    xrange = -13..13
    yrange = 0..10
    zrange = -13..13
    xrange.each { |x|
      yrange.each { |y|
        zrange.each { |z|
          @mc.set_block(@base.x + x, @base.y + y, @base.z + z, Block::AIR)
        }
      }
    }
  end

  private
  def front
    # レンガx5, レンガx5
    pos1 = @base.clone
    pos2 = @base.clone
    @mc.set_blocks(pos1, pos2.move(x: 4), Block::BRICK_BLOCK)
    @mc.set_blocks(pos2.move(x: 2), pos1.move(x: 10), Block::BRICK_BLOCK)
    # 扉
    pos3 = @base.clone.move(x: 5)
    @mc.set_block(pos3.x, pos3.y, pos3.z, Block::DOOR_WOOD, 0)
    @mc.set_block(pos3.x, pos3.y + 1, pos3.z, Block::DOOR_WOOD, 8)
    # レンガx5, レンガx5
    pos1 = @base.clone.move(y: 1)
    pos2 = @base.clone.move(y: 1)
    @mc.set_blocks(pos1, pos2.move(x: 4), Block::BRICK_BLOCK)
    @mc.set_blocks(pos2.move(x: 2), pos1.move(x: 10), Block::BRICK_BLOCK)
    # レンガ11 x 縦4
    4.times { |i|
      pos1 = @base.clone.move(y: i + 2)
      pos2 = @base.clone.move(x: 10, y: i + 2)
      @mc.set_blocks(pos1, pos2, Block::BRICK_BLOCK)
    }
    # 松明
    5.times { |x|
      pos4 = @base.clone.move(x: (x * 2) + 1, y: 3)
      @mc.set_block(pos4.x, pos4.y, pos4.z, Block::TORCH, 5)
    }
  end

  private
  def right_side
    # レンガ11 x 縦6
    6.times { |i|
      pos1 = @base.clone.move(y: i)
      pos2 = @base.clone.move(y: i, z: 10)
      @mc.set_blocks(pos1, pos2, Block::BRICK_BLOCK)
    }
    # 窓
    pos1 = @base.clone.move(y: 1, z: 2)
    pos2 = @base.clone.move(y: 2, z: 3)
    @mc.set_blocks(pos1, pos2, Block::GLASS)
    @mc.set_blocks(pos1.move(z: 5), pos2.move(z: 5), Block::GLASS)
    # 松明
    5.times { |z|
      pos4 = @base.clone.move(x: -1, y: 3, z: (z * 2) + 1)
      @mc.set_block(pos4.x, pos4.y, pos4.z, Block::TORCH, 2)
    }
  end

  def left_side
    # レンガ11 x 縦6
    6.times { |i|
      pos1 = @base.clone.move(x: 10, y: i)
      pos2 = @base.clone.move(x: 10, y: i, z: 10)
      @mc.set_blocks(pos1, pos2, Block::BRICK_BLOCK)
    }
    # 窓
    pos1 = @base.clone.move(x: 10, y: 1, z: 2)
    pos2 = @base.clone.move(x: 10, y: 2, z: 3)
    @mc.set_blocks(pos1, pos2, Block::GLASS)
    @mc.set_blocks(pos1.move(z: 5), pos2.move(z: 5), Block::GLASS)
    # 松明
    5.times { |z|
      pos4 = @base.clone.move(x: 11, y: 3, z: (z * 2) + 1)
      @mc.set_block(pos4.x, pos4.y, pos4.z, Block::TORCH, 1)
    }
  end

  def back
    # レンガ11 x 縦6
    6.times { |i|
      pos1 = @base.clone.move(y: i, z: 10)
      pos2 = @base.clone.move(x: 10, y: i, z: 10)
      @mc.set_blocks(pos1, pos2, Block::BRICK_BLOCK)
    }
    # 松明
    5.times { |x|
      pos4 = @base.clone.move(x: (x * 2) + 1, y: 3, z: 11)
      @mc.set_block(pos4.x, pos4.y, pos4.z, Block::TORCH, 3)
    }
  end

  def proof
    # ガラス
    9.times { |x|
      9.times { |z|
        pos1 = @base.clone.move(x: 1 + x, y: 5, z: 1 + z)
        if z % 2 == 0
          @mc.set_block(pos1.x, pos1.y, pos1.z, Block::GLASS)
        else
          @mc.set_block(pos1.x, pos1.y, pos1.z, Block::BRICK_BLOCK)
        end
      }
    }
  end

  def stairs
    # 階段
    7.times { |z|
      6.times { |y|
        pos1 = @base.clone.move(x: 1, y: y, z: 3 + z)
        pos2 = @base.clone.move(x: 2, y: y, z: 3 + z)
        if y == z
          @mc.set_block(pos1.x, pos1.y, pos1.z, 108, 2)
          @mc.set_block(pos2.x, pos2.y, pos2.z, 108, 2)
          break
        else
          @mc.set_block(pos1.x, pos1.y, pos1.z, Block::BRICK_BLOCK)
          @mc.set_block(pos2.x, pos2.y, pos2.z, Block::BRICK_BLOCK)
        end
      }
    }
    # 外に出れるように穴を開ける
    3.times { |z|
      pos1 = @base.clone.move(x: 1, y: 5, z: 5 + z)
      pos2 = @base.clone.move(x: 2, y: 5, z: 5 + z)
      @mc.set_block(pos1.x, pos1.y, pos1.z, Block::AIR)
      @mc.set_block(pos2.x, pos2.y, pos2.z, Block::AIR)
    }
  end

  def furniture
    # ラージチェスト
    3.times { |y|
      3.step(6, 3).to_a.each { |x|
        pos1 = @base.clone.move(x: x, y: y, z: 9)
        @mc.set_block(pos1.x, pos1.y, pos1.z, Block::CHEST)
        @mc.set_block(pos1.x + 1, pos1.y, pos1.z, Block::CHEST)
      }
    }
    # かまど
    pos1 = @base.clone.move(x: 5, z: 9)
    @mc.set_block(pos1.x, pos1.y, pos1.z, Block::FURNACE_ACTIVE)
    # 作業台
    pos1.move(x: 3)
    @mc.set_block(pos1.x, pos1.y, pos1.z, Block::CRAFTING_TABLE)
    # 本棚
    3.times { |z|
      2.times { |y|
        pos1 = @base.clone.move(x: 9, y: y, z: 4 + z)
        @mc.set_block(pos1.x, pos1.y, pos1.z, Block::BOOKSHELF)
      }
    }
  end
end

h = House.new
h.clear
h.f1

家の前面、背面、左右、天井を別々の関数で定義しています
あとは家具系のアイテムを配置する関数も用意しています

松明を配置するときだけ少し座標の把握が必要かもしれません
汎用的に作成しているわけではないので、家を広げたり家具を移動する場合は頑張ってポジション情報を変更してください

あとは実行するだけです
実行する際はマイクラを起動しておくのを忘れずに

  • bundle exec ruby house.rb

動作確認

こんな感じの家が一瞬で建ちます
内装
auto_building_my_house1.png

外観
auto_building_my_house2.png

最後に

minecraft-pi-ruby を使って家を自動で構築してみました
とりあえず簡単な家を作成しただけですが、あとはこれを応用するだけで何でもできると思います
一点注意が必要なのは実行したら元の状態には戻せません
自分で家を破壊することは可能ですが元の地形に完全に戻すことはできません

チートなのでサバイバルモードに飽きたらやるようにしましょう
プログラムの勉強にも良いかなとは思うんですが単純なコードになるのでガッツリ勉強するのには向かないかもです

0 件のコメント:

コメントを投稿