介紹過 CC: Tweaked Turtle 的特性和指令後
今天來直接看看,怎麼讓 Mining Turtle 挖礦龜為我們工作
假設你還不知道怎麼寫程式讓 Turtle 工作
可以先參考在 /rom/programs/turtle 有兩支專為挖礦龜寫好的指令
excavate.lua 和 tunnel.lua
tunnel 是用來挖隧道用的,隧道寬度固定為 3 格,高度固定為 2 格,長度可自訂
例如輸入
tunnel 5
就是讓小龜往前挖出 寬3 x 高2 x 長5 的隧道,其中長度 5 是從目前小龜所在那一格開始算起
這個程式很方便我們快速挖出一條通道
而如果你嫌高度 2 格不夠怎辦?
那就放兩隻小龜同時挖啊 XD
接下來看看 tunnel.lua 的程式碼
local collected = 0
local function collect()
collected = collected + 1
if math.fmod(collected, 25) == 0 then
print("Mined " .. collected .. " items.")
end
end
每次開挖,都會呼叫 collect(),計算目前挖到的物品總數,並且每 25 個回報一次
local function tryDig()
while turtle.detect() do
if turtle.dig() then
collect()
sleep(0.5)
else
return false
end
end
return true
end
挖掘函數有 tryDig, tryDigUp, tryDigDown 我們看 tryDig 就夠了
turtle.detect() 就是判斷前方是否可以挖,回傳 true / false,相關函數有 turtle.detectUp(), turtle.detectDown()
turtle.dig() 當然就是挖掘前面方塊了,回傳 true / false,相關函數有 turtle.digUp(), turtle.digDown()
local function refuel()
local fuelLevel = turtle.getFuelLevel()
if fuelLevel == "unlimited" or fuelLevel > 0 then
return
end
local function tryRefuel()
for n = 1, 16 do
if turtle.getItemCount(n) > 0 then
turtle.select(n)
if turtle.refuel(1) then
turtle.select(1)
return true
end
end
end
turtle.select(1)
return false
end
if not tryRefuel() then
print("Add more fuel to continue.")
while not tryRefuel() do
os.pullEvent("turtle_inventory")
end
print("Resuming Tunnel.")
end
end
refuel 就是補充燃料了
首先判斷是否有足夠燃料,不夠的話才會試著尋找儲物箱內,是否有適合當燃料的物品
可以看出補充燃料的方式,就是要先選擇某一格
turtle.select(n)
然後 turtle.refuel(1),這裡設計成一次只補充一份,因為我們不知道到底還有多少燃料可以拿來用
然後當燃料不夠,就會持續等著物品放進小烏龜儲物箱的事件 turtle_inventory 發生
此時會再次試著補充讓料
local function tryUp()
refuel()
while not turtle.up() do
if turtle.detectUp() then
if not tryDigUp() then
return false
end
elseif turtle.attackUp() then
collect()
else
sleep(0.5)
end
end
return true
end
再來看看 tryUp,相關函數有 tryDown, tryForward
try 函數每次都先補充燃料確保可以動作
接下來 turtle.up() 試著往上移動
如果失敗了,就用 turtle.detectUp() 判斷上方是否有方塊?如果有,就試著挖開
如果不是方塊,那麼就可能是怪物了,就試著攻擊
最後來看看主程式
for n = 1, length do
turtle.placeDown()
tryDigUp()
turtle.turnLeft()
tryDig()
tryUp()
tryDig()
turtle.turnRight()
turtle.turnRight()
tryDig()
tryDown()
tryDig()
turtle.turnLeft()
if n < length then
tryDig()
if not tryForward() then
print("Aborting Tunnel.")
break
end
else
print("Tunnel complete.")
end
end
turtle.placeDown() 一開始先在下方放置任意方塊,相關函數有 place(), placeUp()
接下來挖掘方塊的順序就是上、左、左上、右上、右下
然後轉正準備挖下一個深度,如果這時侯挖掘失敗了,就會中斷,否則就會一直挖開到玩家指定的長度
看完 tunnel.lua 之後,其實就幾乎學會小烏龜 80% 的函數了!
足以撰寫大部分的挖掘指令
這是實際挖隧道時小烏龜的電腦畫面
接下來看看 excavate.lua
tunnel.lua 是往前挖出隧道,excavate.lua 則是往下挖井,長寬為玩家自訂
會挖得非常深,直達地底遇到基岩才停止
接著就會自動往上移動回到地面上
這是執行過程小烏龜的電腦畫面
假設輸入
excavate 3
就是往下挖出 3 x 3 的深井直達地底
來看看 excavate 的程式碼
local function unload(_bKeepOneFuelStack)
print("Unloading items...")
for n = 1, 16 do
local nCount = turtle.getItemCount(n)
if nCount > 0 then
turtle.select(n)
local bDrop = true
if _bKeepOneFuelStack and turtle.refuel(0) then
bDrop = false
_bKeepOneFuelStack = false
end
if bDrop then
turtle.drop()
unloaded = unloaded + nCount
end
end
end
collected = 0
turtle.select(1)
end
這是小烏龜挖井結束後,返回到地面時,把挖到的東西都「吐」出來的函數
就是這個畫面 XD
這段程式碼邏輯其實很簡單,就是把小烏龜儲物箱的16格一一檢查過
如果有東西就 drop 到地上
而中間有一段用到 _bKeepOneFuelStack 變數,是告訴小烏龜卸貨時,是否保留一格燃料,畢竟燃料還要用嘛!
local function returnSupplies()
local x, y, z, xd, zd = xPos, depth, zPos, xDir, zDir
print("Returning to surface...")
goTo(0, 0, 0, 0, -1)
local fuelNeeded = 2 * (x + y + z) + 1
if not refuel(fuelNeeded) then
unload(true)
print("Waiting for fuel")
while not refuel(fuelNeeded) do
os.pullEvent("turtle_inventory")
end
else
unload(true)
end
print("Resuming mining...")
goTo(x, y, z, xd, zd)
end
這個 returnSupplies 函數則是讓小烏龜「回到」地面後,等待更多燃料並卸貨
然後回到原本的位置繼續開挖
從下面 tryForwards(), tryDown() 可以看出,小烏龜有兩種情況會做這件事
goTo() 則很明顯是直接移動小烏龜到指定位置的函數,用的是相對座標
goTo(0, 0, 0, 0, 1) 便是回到一開始的位置和方向
最後來個掘井畫面
以上是今天對 Mining Turtle 的分享
下一回我會繼續探索更多小烏龜的操作~