今天來一起看看各種小烏龜一起工作吧
Mining Turtle 我已經很熟了,可以挖礦直達地底
那拿鑽石斧的 Felling Turtle 呢?
我本以為它只能砍樹,實測發現它也能挖礦
而 Mining Turtle 也能砍樹
所以我不太確定兩者有什麼差異 @@
令我比較訝異的是,拿鑽石鏟的 Digging Turtle
我本以為它至少能鏟土和沙子
實測卻發現連鏟土都無法,只能鏟沙,感覺非常不實用 ><
至於拿鑽石鋤頭的 Farming Turtle
可以在其儲物箱先備好植物種子和骨粉
整個種植過程的 API 呼叫如下:
接下來我試著把之前學到的東西一起複習並應用
之前已介紹過,挖礦龜可以掘井挖隧道
但如果玩家想要到達地底,總不能朝著深井跳下去吧 .....
所以必須改寫 /rom/programs/turtle/excavate.lua 讓這支程式可以挖樓梯出來!
部分程式碼如下,因為有點長,我就直接在程式碼註解說明每一段的大概
在這之前,我先設置好 GPS 基地台,請參考之前的文章
-- 讓玩家指定挖掘的深度,例如 mining 5 那就只會挖出深度 5 的樓梯,然後折返
local depthLimit = tonumber(tArgs[1])
if depthLimit < 1 then
print("Depth must be positive")
return
end
-- 目前挖掘的深度
local depth = 0
-- 吐出的東西總數
local unloaded = 0
-- 收集的東西總數
local collected = 0
local protocol = 'mining' -- 這是傳訊時讓監控中心分辨用的,如果是鏟子龜,protocol 就是 digging,砍樹龜則是 'felling'
peripheral.find("modem", rednet.open) -- 找到身上的所有 modem 後打開它
rednet.host(protocol, 'yoshi')
-- 印出訊息,同時傳送到網路上給監控中心。這裡用的是廣播,只要有監聽 protocol 都可收到
local function printThenSend(message)
print(message)
rednet.broadcast(message, protocol)
end
-- 把東西丟出來放到地上,這是挖掘完畢後回到地上的作業
local function unload()
printThenSend("Unloading")
for n = 1, 16 do
local nCount = turtle.getItemCount(n)
local data = turtle.getItemDetail(n)
-- 不要把火把丟掉,可能還會再用
if nCount > 0 and data.name ~= 'minecraft:torch' then
turtle.select(n)
turtle.drop()
unloaded = unloaded + nCount
end
end
collected = 0
turtle.select(1)
end
local function collect()
-- 收集物品。略,這部分跟原本 excavate.lua 大同小異
end
-- 從儲物箱內尋找火把,然後放置在左方,放完後再轉回正前方。這麼做是為了照耀通道,好讓主人走下去 XD
local function placeTorch()
for n = 1, 16 do
local nCount = turtle.getItemCount(n)
if nCount > 0 then
turtle.select(n)
local data = turtle.getItemDetail()
if data.name == 'minecraft:torch' then
turtle.place()
break
end
end
end
end
-- 因為我已經架設好 GPS 基地台,所以每隻小烏龜只要有 Ender Modem 都可以隨時取得 GPS 座標並回報
local function reportPosition(currentDepth)
if math.fmod(currentDepth, 10) == 0 then
local x, y, z = gps.locate(2, false)
local msg = string.format("Depth: %s GPS: %d %d %d", currentDepth, x, y, z)
printThenSend(msg)
end
end
-- @tparam boolean dig 是否邊移動邊挖掘? 如果 dig = false, 小烏龜只會嘗試移動,不挖任何東西
local function tryForwards(dig)
while not turtle.forward() do
if turtle.detect() then
if dig and turtle.dig() then
collect()
else
return false
end
elseif turtle.attack() then
collect()
else
sleep(0.5)
end
end
if dig then
-- 往前多挖一格,這樣玩家才能走下去
turtle.dig()
-- 往左邊挖一格,讓走道寬一點
turtle.turnLeft()
turtle.dig()
turtle.turnRight()
else
turtle.forward()
end
return true
end
-- @tparam boolean dig 是否邊移動邊挖掘? 如果 dig = false, 小烏龜只會嘗試移動,不挖任何東西
local function tryDown(dig)
while not turtle.down() do
if turtle.detectDown() then
if dig and turtle.digDown() then
collect()
else
return false
end
elseif turtle.attackDown() then
collect()
else
sleep(0.5)
end
end
-- 挖寬兩格
if dig then
turtle.turnLeft()
turtle.dig()
-- 深度每 6 格放一支火把
if dig and (depth % 6 == 0) then
placeTorch()
end
turtle.turnRight()
end
depth = depth + 1
reportPosition(depth)
return true
end
-- @tparam boolean dig 是否邊移動邊挖掘? 如果 dig = false, 小烏龜只會嘗試移動,不挖任何東西
local function tryUp(dig)
while not turtle.up() do
if turtle.detectUp() then
if dig and turtle.digUp() then
collect()
else
return false
end
elseif turtle.attackUp() then
collect()
else
sleep(0.5)
end
end
depth = depth - 1
reportPosition(depth)
return true
end
local done = false
-- 先往下開挖,直到指定深度
while not done do
if not tryForwards(true) or not tryDown(true) then
done = true
break
end
if depth >= depthLimit then
break
end
end
printThenSend("Returning")
-- 挖到指定深度後,開始回程。迴轉後往上走
turtle.turnLeft()
turtle.turnLeft()
done = false
while not done do
if not tryUp(false) or not tryForwards(false) then
done = true
break
end
if depth == 0 then
break
end
end
unload()
上述的程式碼,大約指定深度 50 ,就可以挖出這樣的樓梯通道
雖然形狀有點怪,還需要再優化 XD
回到地面上後,把東西都一股腦丟出來了
而挖掘過程中,小烏龜的螢幕顯示就像這樣
不過,我們不可能就這樣跟著小烏龜下去,它挖到哪,我們走到哪
所以這時候就需要 Ender Modem 把小烏龜狀態傳達給監控中心了!
首先我有一台有 Ender Modem 的電腦,並接上三台大螢幕
分別監控三種 protocol 訊息:mining、digging、felling
也就是挖礦龜、鏟沙龜、砍樹龜的作業
程式碼如下
local centerMonitor = peripheral.wrap("monitor_5")
local leftMonitor = peripheral.wrap("monitor_4")
local rightMonitor = peripheral.wrap("monitor_2")
rednet.open('right')
rednet.host('monitor', 'center') -- 這台電腦的 protocol 是 monitor、名稱是 center
parallel.waitForAny(
function ()
while true do
local senderID, message, protocol = rednet.receive('mining')
term.redirect(centerMonitor)
print("Turtle ID: " .. senderID)
print("message: " .. message)
end
end,
function ()
while true do
local senderID, message, protocol = rednet.receive('digging')
term.redirect(leftMonitor)
print("Turtle ID: " .. senderID)
print("message: " .. message)
end
end,
function ()
while true do
local senderID, message, protocol = rednet.receive('felling')
term.redirect(rightMonitor)
print("Turtle ID: " .. senderID)
print("message: " .. message)
end
end
)
rednet.close()
我在三個 function 間持續不斷地切斷,只要有收到小烏龜訊息,就把 ID 和訊息發送到螢幕上顯示
這樣一來,監控中心可以根據不同的 protocol 來決定顯示方式
例如我把 mining 的訊息顯示到正中央大螢幕
digging 訊息顯示在左方螢幕,felling 訊息顯示在右方螢幕
執行過程大概的畫面如下
以上就是今天的分享了~
其實在這 30 天,沒辦法充分花時間在遊戲體驗
前期花了許多時間在熟悉 Lua 語言特性和語法
後期則一直在自己探索 CC: Tweaked 模組的使用方式
所以我的程式碼和範例應用其實都滿簡單的XD
我相信 CC: Tweaked 可以應用得非常有趣,讓很多事情都全自動化了
(那主人還要幹嘛 .....)
在國內幾乎沒有人把這模組介紹得非常詳細(應該是沒有)
只知道有些幼童程式語言學習的課程似乎有玩到,但沒有玩得很深入
說來說去就是 Turtle,並沒有從 Computer 開始的基礎介紹
所以只能找國外各種範例和文章,或是自己嘗試了~
感謝這三十天有追蹤和閱讀我文章的網友們
如果你也有玩麥塊,試試看,會很有趣~