こんにちは、「メカのりまき」です。
この記事では、「マインクラフト」の丸石採掘を「Arduino Micro」を使って自動化させるといったことを行いたいと思います。
この記事では、Windows11のPCを使用しています。
また、「マインクラフト」は統合版(v1.21.41)で、難易度設定は「ノーマル」、操作設定はデフォルトのものを使用しています。
目次
本記事で使用するもの
記事を見て、気になるものがあれば、是非チェックをしてみてください。
マインクラフトで丸石製造機を作る
まずは、マインクラフト内で、丸石を無限に生成することができる、以下のような丸石製造機の作成を行います。
この記事で制作する丸石製造機の材料は以下の通りです。
ネザーでしか手に入らない素材を使用しなくても作れるので、比較的序盤でも作ることが出来ると思います。
燃えないブロックの部分は、エンダーマンに持っていかれるブロック(土や砂など)以外で、丸石と区別がつきやすいブロック(花崗岩、テラコッタなど)をお勧めします。
ネザーに行けるのであれば、ツルハシで壊しづらく燃えることのない真紅の板材、歪んだ板材をお勧めします。
また、階段ブロックはツルハシで壊しづらい木材の階段がお勧めです。
丸石製造機を作成する際に、参考にした動画を以下に貼らせていただきます。
以下の動画では、丸石のできる仕組みの他、採掘やホッパーについてのテクニックなども詳しく説明してくれています。
この記事で制作する丸石製造機は、以下の動画にでてくるコンパクトタイプの丸石製造機をベースとして制作しています。
作り方
では、早速制作を行いたいと思います。
接地するスペースは以下の通りです。
チェストとホッパーを設置する
まず、以下の画像のように穴を掘り、そこにチェストを設置します。
参考にした動画では、チェストは1つだけでしたが、より多くの丸石を収納するために、チェストを2つにしています。
続いて、チェストに丸石を送るために、ホッパーの設置を行っていきます。
まずは、チェストの後ろ側に穴を掘ったあと、ホッパーを2つチェストに繋げるように設置します。
設置するときは、「shiftキー」でしゃがみながら、チェストの後ろ側を右クリックします。
そうすることにより、チェストにホッパーを繋げることができます。
同じように、先程接地した2つのホッパーの後ろ側に、ホッパーを繋げます。
続いて、右側の2つのホッパーの上にホッパーを設置します。
設置するときは、「shiftキー」でしゃがみながら、ホッパーの上側を右クリックします。
最後に、先程設置した上側のホッパーに対して、横からホッパーを繋げるように設置します。
設置するときは、「shiftキー」でしゃがみながら、ホッパーの横を右クリックします。
以上で、チェストとホッパーの設置は完了です。
最後に設置した2つのホッパーにアイテム入れ、チェストにアイテムがしっかり送られるかどうかを確認してみてください。
燃えないブロック、階段ブロック、トラップドアを設置する
続いては、水と溶岩を入れる囲いを設置していきたいと思います。
まずは、燃えないブロックを以下のように設置していきます。
次に、階段ブロックを右側のホッパーの上に設置します。
階段を設置するときは、「shiftキー」でしゃがみながら、ホッパーの上側を右クリックします。
階段ブロックの向きは以下の画像の通りにします。
続いて、以下のようにトラップドアを6個設置します。
その後、燃えないブロックを以下のように設置します。
上記のように、燃えないブロックを設置しましたら、設置したブロックに上り、燃えないブロックで屋根を作ります。
屋根が出来ましたら、下に降りて、トラップドア2個を以下のように設置します。
以上で、水と溶岩を入れる囲いの設置は完了です。
水と溶岩を設置する
囲いができたので、水と溶岩を設置していきます。
まずは、2つの階段に水を入れます。
階段に狙いを定めて、水入りバケツを使用することによって、階段に水を入れることができます。
階段2つに水を入れると以下の画像のようになります。
続いて、溶岩の設置をします。
溶岩の設置場所は以下の画像の部分です。
階段に水が入っていれば、瞬時に丸石が生成されるため、溶岩は溢れません。
別の位置に設置しないように、狙いを定めて溶岩入りバケツを使用してください。
ここまで、出来れば丸石が生成されるのが確認できます。
目印のブロックを設置する
水と溶岩を設置が終わりましたら、採掘をする場所を分かりやすくするために目印のブロックを以下のように設置します。
目印のブロックを設置しましたら、そのブロックの1つ後ろに立ち、丸石の採掘をしてみてください。
この場所から採掘をすれば、丸石の奥にある壁は選択されず、破壊されることは無いはずです。
丸石が次々と生成されること、採掘した丸石がチェストに収納されていることが確認できれば、丸石を無限に採掘するための部分は完成になります。
敵から身を守るために囲いを作る
今回は、夜の間も採掘を続けるため、敵から身を守るための囲いを以下のように設置します。
また、外が夜になっている状態で、外に出たくないため、入り口から入って左側に穴を掘ってベッドを設置します。
これで、夜の間でも採掘が可能になりました。
装置が壊れた際の対策を行う
これから紹介する「Arduino Micro」での採掘は、装置が壊れようともひたすら採掘をし続けます。
装置を壊して溶岩が流れてきても、逃げることなく採掘を続けるため、致命傷を負う可能性があります。
そこで、装置を壊したとしても、致命傷を負わないように、対策をしておきます。
まず、溶岩側のトラップドアの下に穴を掘ります。
これにより、内側のトラップドアを破壊してしまったとしても、溶岩がプレイヤーの立っている場所まで流れてくることが無くなるので安全になります。
次に外側のトラップドアの下にも穴を掘っておきます。
これにより、外側のトラップドアを破壊してしまったとしても、溶岩や水が装置周りの構造物に向かって流れることが無くなります。
以上で、丸石製造機の制作は完了です。
ツルハシを切り替えながら採掘をする
丸石製造機の制作が完了しましたら、ようやく「Arduino Micro」の出番です。
今回は以下の動画のように、ツルハシを切り替えながら採掘をするといったことを行いたいと思います。
ツルハシを切り替えながら採掘をするので、石のツルハシしか作れないような序盤でも約30分間、採掘を続けることができます。
石のツルハシよりも良いツルハシを使用すれば、より長く採掘をしたり、効率を上げたりすることができますが、今回は序盤でも量産可能な石のツルハシを使うこととします。
以下で説明するスケッチを理解していただければ、後から、石のツルハシよりも良いツルハシ用に改造することも容易ですので、是非参考にしていただければと思います。
空のスケッチを書き込む
回路を作成する前に、空のスケッチ(「ファイル」タブの「New Sketch」をクリックしたときに出てくる何の処理も書かれていないスケッチ)を書き込みます。
前に作成した回路がある場合は、その回路を崩す前に空のスケッチを書き込みます。
そうすることにより、前に書き込んだスケッチが、新しく作成しようとしている回路に影響を及ぼすことを防げます。
また、前に作成した回路を崩さずに空のスケッチを書き込むのは、ボードへの入力が無いことによって、PCへの操作が行われる場合があるからです。
新しい回路を作成するときは、いつもこの作業をやっておくと、安全に回路を作成することができます。
回路を作成する
以下のような回路を作成します。
スケッチを書き込む
回路の作成が終わりましたら、以下のようなスケッチを書き込みます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
/* マインクラフトの丸石採掘をArduinoMicroで行う 2024/10/26 mine_cobblestone スケッチの詳細はこちら↓ https://mecha-norimaki.com/mine_cobblestone_01/ */ //ライブラリの読みこみ #include <Mouse.h> //スイッチに繋がっているピンを指定 const int switchPin = 2; //USBを繋げた瞬間暴走してしまうような状態を止めるためのピンを指定 const int pausePin = 13; //採掘を行うツルハシの数を設定 const int pickaxes = 9; //ツルハシを切り替える時間を設定(ミリ秒) unsigned long changeTime = 200000; //採掘を始めるときに時間を格納する変数 unsigned long setTime; //採掘の時間を格納する変数 unsigned long countTime = 0; //消費したツルハシの数をカウントするための変数 int countPickaxes = 0; void setup() { //pausePinに指定したピンを入力ピンとして設定(デフォルト設定なので省略しても良い) pinMode(pausePin, INPUT); //pausePinに指定したピンがHIGHのとき空の文を無限に行い以降の文を実行しないようにする while (digitalRead(pausePin)) {} //スイッチに繋いだピンをプルアップ付きの入力ピンとして設定する pinMode(switchPin, INPUT_PULLUP); //マウスとして利用するための初期設定 Mouse.begin(); } void loop() { //スイッチが押され離された後、採掘を始める if (!digitalRead(switchPin)) { while (!digitalRead(switchPin)) {} delay(200); Mouse.press(MOUSE_LEFT); setTime = millis() - countTime; //ツルハシを使い切るまで、もしくはスイッチが押されるまでループをする while (true) { //採掘の時間を計算する countTime = millis() - setTime; //定数changeTimeで指定した分、時間がたったら、ツルハシを切り替える処理を行う if (countTime >= changeTime) { Mouse.release(MOUSE_LEFT); Mouse.move(0, 0, -1); countPickaxes++; //定数pickaxesで指定した分、ツルハシを使ったら、採掘を終了しループから抜け出す //それ以外の場合は、採掘を続行 if (countPickaxes >= pickaxes) { countPickaxes = 0; countTime = 0; break; } else { Mouse.press(MOUSE_LEFT); setTime = millis(); } } //スイッチが押されたら、採掘を終了してループから抜け出す if (!digitalRead(switchPin)) { Mouse.release(MOUSE_LEFT); while (!digitalRead(switchPin)) {} delay(200); break; } } } } |
スケッチが正しければ、スイッチを押して離した瞬間、採掘を始めます。
このとき、普段使っているマウスでの操作は可能なので、マウスを動かして、採掘の位置をずらしてしまわないように注意してください。
また、採掘中にもう一度スイッチを押すと、採掘を一時停止することができます。
もし、マウスが暴走してしまう場合や上手く採掘が行えない場合は、USBケーブルを抜いて、スケッチや回路を確かめてみてください。
スケッチの解説
暴走を止めるための文
私は「Arduino Micro」にスケッチを書き込むとき、以下のような文を書いて暴走したときの対処を行っています。
まず、スケッチの初めにある以下の文で、「pausePin」という定数を用意して暴走を止めるためのピンの番号を格納しています。
16 17 |
//USBを繋げた瞬間暴走してしまうような状態を止めるためのピンを指定 const int pausePin = 13; |
次に、「void setup()」初めに、以下の文を書くことにより、暴走を止めるためのピンがHIGHのとき空のループを行うようにしています。
36 37 38 39 40 |
//pausePinに指定したピンを入力ピンとして設定(デフォルト設定なので省略しても良い) pinMode(pausePin, INPUT); //pausePinに指定したピンがHIGHのとき空の文を無限に行い以降の文を実行しないようにする while (digitalRead(pausePin)) {} |
上記の文が正しく書き込めていれば、PCとの接続前に「pausePin」に指定したピン(上記の場合だと13番ピン)と5Vピンを接続することで、暴走を止めることができます。
上記の文の詳細や上記の文が機能しなかったときの対処法は、以下の記事で説明していますので、良く分からないという方は、是非以下の記事をご覧になってください。
スイッチを扱うための初期設定
スイッチを扱うための初期設定は以下の通りです。
まず、スケッチの初めにある以下の文により、スイッチに繋がっているピンの番号を定数「switchPin」に格納しています。
13 14 |
//スイッチに繋がっているピンを指定 const int switchPin = 2; |
続いて、「void setup()」の中で以下のような文により、スイッチに繋がっているピンをプルアップ付きの入力ピンとして設定しています。
42 43 |
//スイッチに繋いだピンをプルアップ付きの入力ピンとして設定する pinMode(switchPin, INPUT_PULLUP); |
タクトスイッチやプルアップ付きの入力ピンについて、良く分からないという方は、以下の記事で説明していますので、是非、ご覧になってください。
マウスの操作を行うための初期設定
Arduinoをマウスとして扱うためのライブラリが、標準ライブラリとして存在するため、それを利用します。
まず、スケッチの初めにある以下の文により、「Mouseライブラリ」を読み込みます。
10 11 |
//ライブラリの読みこみ #include <Mouse.h> |
続いて、「void setup()」の中にある以下の文により、マウスの初期設定を行います。
45 46 |
//マウスとして利用するための初期設定 Mouse.begin(); |
「Arduino Micro」でマウスを操作する方法は、以下の記事で説明していますので、マウスを操作する方法が良く分からないという方は、是非以下の記事をご覧になってください。
採掘を始める
今回のスケッチでは、スイッチが押されたときに、採掘をするという処理を行うため、以下のような構成でスケッチを記述しています。
ここで、採掘を始めるための文は以下のようになっています。
51 52 53 54 55 56 57 58 59 |
//スイッチが押され離された後、採掘を始める if (!digitalRead(switchPin)) { while (!digitalRead(switchPin)) {} delay(200); Mouse.press(MOUSE_LEFT); setTime = millis() - countTime; //ツルハシを使い切るまで、もしくはスイッチが押されるまでループをする while (true) { |
ここで、スイッチが押されたとき「if(!digitalRead(switchPin))」の条件を満たしますが、「while (!digitalRead(switchPin)) {}」により、スイッチが押されている間、空のループ処理を行います。
この「while (!digitalRead(switchPin)) {}」は、スイッチが離されることにより、抜け出すことができるので、スイッチが離された後に次の処理に進んでいくことができます。
なぜ、スイッチが離されるまで、待機しているのかというと、内部にも「if(!digitalRead(switchPin))」の条件を用意しており、スイッチが離された状態でないと条件がすぐに満たされてしまうといった問題があるからです。
また、次の処理である「delay(200)」もチャタリングにより、内部にある「if(!digitalRead(switchPin))」の条件が満たされてしまわないようにするための対策です。
スイッチを2つ用意すれば、わざわざこんな事をしなくても良かったような気がしますが、スイッチが2つあると、採掘を始めるとき、または止めるとき、どちらのスイッチを押せば良いのか迷ってしまいそうなので、このようなスケッチを書き、スイッチ1つにまとめてみました。
「delay(200)」の後は、「Mouse.press(MOUSE_LEFT)」により、マウスの左ボタンを押す処理を行い採掘し始めます。
その後、変数「setTime」に「millis() – countTime」を格納します。
ここで、「millis()」というのは、ボードがプログラムの実行を開始した時から現在までの時間をミリ秒単位で返す関数です。
変数「countTime」は、後に説明しますが、初めてスイッチを押した場合は、変数宣言時に格納した「0」です。
28 29 |
//採掘の時間を格納する変数 unsigned long countTime = 0; |
つまり、初めてスイッチを押した場合は、「setTime = millis()」となります。
この「setTime」は、後に採掘の時間を計算するために利用します。
「setTime」に時間を格納した後は、while文によるループ処理に入ります。
while文は、( )内が「true」の場合、{ }内の処理を繰り返し行う文です。
つまり、今回の場合は、常に( )内が「true」になっているので永遠にループすることになりそうですが、内側から「break」という処理を行うことでループから抜け出すことができます。
今回の場合は、ツルハシを使い切るか、もう一度スイッチが押された場合に、「break」を実行し抜け出すような処理をしています。
採掘の時間を計算する
このスケッチでは以下の文によって、ループをするごとに採掘の時間を計算しています。
61 62 |
//採掘の時間を計算する countTime = millis() - setTime; |
このとき、時間の関係を図で表すと以下のようになります。
ここで、先程も使用した「millis()」について、もう少し詳しく説明したいと思います。
「millis()」はボードがプログラムの実行を開始した時から現在までの時間をミリ秒単位で返しますが、返される値は「unsigned long」という型で、「0」から「4294967295」であるという制約があります。
では、ボードがプログラムの実行を開始した時から現在までの時間が「4294967295」ミリ秒を超えるとどうなるのかといいますと、いったん「0」に戻ってそこからカウントし直すような形になります。
グルグル回る時計のようなものをイメージすると、少し分かりやすくなるかもしれません。
ここで、「millis()」よりも変数「setTime()」が大きな値になる場合があるということに気づき、そのとき「millis() – setTime」は、おかしくなるのではないかと考える人がいるかもしれませんがご安心ください。
大変ありがたいことに、「unsigned long」同士で計算を行った場合、しっかりとその差を求めることが出来ます。
「unsigned long」同士での計算結果は、以下の図のようなイメージで、「4294967295 + 1000」は「999」、「999 – 1000」は「4294967295」、そして「999 – 4294967295」は「1000」という風になります。
よって、「millis()」が、「4294967295」を超えるようなことが起きたとしても、その差を計算することができます。
ツルハシを切り替えながら採掘をする
ツルハシを切り替えながら採掘をする処理は、以下の文によって行っています。
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
//定数changeTimeで指定した分、時間がたったら、ツルハシを切り替える処理を行う if (countTime >= changeTime) { Mouse.release(MOUSE_LEFT); Mouse.move(0, 0, -1); countPickaxes++; //定数pickaxesで指定した分、ツルハシを使ったら、採掘を終了しループから抜け出す //それ以外の場合は、採掘を続行 if (countPickaxes >= pickaxes) { countPickaxes = 0; countTime = 0; break; } else { Mouse.press(MOUSE_LEFT); setTime = millis(); } } |
この文では、if文により「countTime」の値が、スケッチの初めに宣言した「changeTime」の値以上かどうかを確認し、条件が正しければ「Mouse.release(MOUSE_LEFT)」、「Mouse.move(0, 0, -1)」により、採掘を一度止めて、ツルハシを切り替えるという処理を行っています。
ここで、スケッチの初めに宣言した「changeTime」の値を変更すれば、ツルハシを切り替える時間の調整をすることができます。
22 23 |
//ツルハシを切り替える時間を設定(ミリ秒) unsigned long changeTime = 200000; |
今回のスケッチでは「countTime」の値を「200000」としているため、200000ミリ秒(200秒)ごとにツルハシを切り替える処理が行われます。
また、ツルハシを切り替える処理を行ったあとは、消費したツルハシの数をカウントするための変数「countPickaxes」の値を1増やします。
さらに、2つめのif文では、「countPickaxes」の値が、スケッチの初めに宣言した「changeTime」の値以上かどうかを確認し、条件が正しければ、「countPickaxes」、「countTime」を「0」にリセットした後、「break」によりループから抜け出す処理を行います。
また、条件が正しくない場合は、「Mouse.press(MOUSE_LEFT)」により、採掘を再開し、「setTime」の値を「millis()」により更新します。
これにより、「countTime」の値はリセットされることになるので、また、スケッチの初めに宣言した「changeTime」の値以上になるまで、採掘をし続ける処理を行うことになります。
ここで、スケッチの初めに宣言した「pickaxes」の値を変更すれば、採掘を行うツルハシの数を調整することができます。
19 20 |
//採掘を行うツルハシの数を設定 const int pickaxes = 9; |
今回のスケッチでは「pickaxes」の値を「9」としているため、9回ツルハシを切り替える処理が行われたらループから抜け出し、採掘を終了させるといった処理が行われています。
スイッチが押されたら採掘を一時停止する
今回のスケッチでは、途中で採掘を停止できるように、スイッチが押されたら、ループから抜け出すといった処理を、while文の中にある以下の文によって行っています。
82 83 84 85 86 87 88 |
//スイッチが押されたら、採掘を終了してループから抜け出す if (!digitalRead(switchPin)) { Mouse.release(MOUSE_LEFT); while (!digitalRead(switchPin)) {} delay(200); break; } |
この文では、スイッチが押されたら、「 Mouse.release(MOUSE_LEFT)」により、採掘を止めて、その後スイッチが離されたら、「break」でループから抜け出すといった処理を行っています。
「while (!digitalRead(switchPin)) {}」と「delay(200)」は、ループから抜け出した後、一瞬で外側の「if(!digitalRead(switchPin))」を満たして、また採掘を始めてしまうといった現象を防ぐための対策です。
今回のスケッチでは、スイッチを押してループから抜け出す際、「countPickaxes」、「countTime」をリセットしていません。
つまり、カウントしていた情報は記録されている状態であるということになります。
ここで、採掘を始める際に「setTime」に「millis() – countTime」を入れるという処理があったと思います。
51 52 53 54 55 56 57 58 59 |
//スイッチが押され離された後、採掘を始める if (!digitalRead(switchPin)) { while (!digitalRead(switchPin)) {} delay(200); Mouse.press(MOUSE_LEFT); setTime = millis() - countTime; //ツルハシを使い切るまで、もしくはスイッチが押されるまでループをする while (true) { |
「countTime」の値は、最初にスイッチを押したときと、ツルハシを使い切ってループを抜け出したときは「0」ですが、スイッチを押すことによって、ループから抜け出した場合は、前に行った採掘の時間が格納されています。
つまり、スイッチを押すことによって、ループから抜け出した場合、「setTime」は、「millis()」によって得られた時間から、前に行った採掘の時間である「countTime」を巻き戻した時間を入れることになります。
そして、採掘の時間は、ループの初めに「millis()」から「setTime」を引くことによって計算しているため、以下の図のように、前に採掘を行っていた時間を含めて、現在の採掘時間を計算することになります。
よって、スイッチが押されたことにより、採掘が停止した場合、もう一度スイッチが押されたら、採掘を途中から再開されるということになります。
終わりに
皆さん、丸石採掘を行うことができたでしょうか。
今回の記事では、「Arduino Micro」を使って、「マインクラフト」の操作を行ってみました。
どちらかしか知らない人にとっては、あまり参考にならない記事だったかもしれません。
「Arduino Micro」などHID機能をもった「Arduinoボード」は、キーボードやマウスの操作が可能ですので、工夫次第で他にも様々な操作が行えます。
当サイトでは、「Arduino Micro」でPCを操作する方法についての記事をいくつか掲載していますので、参考にしていただければ幸いです。
本記事はここまでです。ご清覧ありがとうございました。
広告
今回の主役である「Arduino Micro」です。
まだ持っていないという方は、この機会に是非購入を検討してみてください。
「Arduino Micro」とPCと接続するためのケーブルです。
MicroBタイプのUSBケーブルが無い場合は、合わせて購入を検討してみてください。
今回使用したカラフルなスイッチのセットです。
スイッチを色で判別したいときや見た目をカラフルしたいときにおすすめです。
今回使用したコンパクトなブレッドボードとジャンパーワイヤーのセットです。
コンパクトな回路を作成する際に役立ちます。
楽天モーションウィジェットとGoogleアドセンス広告です。
気になる商品がございましたら、チェックをしてみてください。