iT邦幫忙

2021 iThome 鐵人賽

DAY 22
1
Software Development

在麥塊的農場裡寫 Lua系列 第 22

Day22 高階網路應用 GPS 和 Ender Modem

今天來看 CC: Tweaked 最後一個網路應用 GPS
用途是讓電腦可以取得自己的座標
而這個座標系統是可以完全自定義的,有 x y z 座標
當然這座標數字不是隨便亂打,如果輸入不合理的數字,GPS 系統還是會無法運作
或是取得奇怪的座標

這是網路上找到的圖片
CC: Tweaked GPS System
所以我就依樣畫葫蘆,建立一座自己的 GPS 系統
CC: Tweaked GPS System
稍微目測計算一下後,用 gps 指令(/rom/programs/gps.lua)各自定義座標
我的四臺電腦分別給予座標如下

gps host 3 0 258
gps host -3 0 258
gps host 0 -3 255
gps host 0 3 255

這樣就完成了一座 GPS 衛星定位系統!
在這無線範圍內的電腦,只要也安裝 Wireless Modem,就可以查詢自己的座標

gps locate

CC: Tweaked GPS Locate
是不是很簡單呢?

為何要談 Ender Modem ?

Ender Modem 可說是 CC: Tweaked 最強大的數據機!
是怎麼強法?!
Ender 這個命名,我不確定是不是終界使者安德的意思?
Minecraft Ender

根據官方文件,它的強大來自兩個特點:

  1. 可傳輸 2,147,483,647 (2^31-1) 個方塊!這太扯了,根本無距離限制,一個 Ender Modem 傳遍所有角落,愛傳多遠就傳多遠
    CC: Tweaked Ender Modem
  2. 可進行 Cross-Dimension 傳輸 ..... 這我找了好久,始終沒找到 demo,我其實沒搞懂 Cross-Dimension 的意思 XD

但是我猜測,Cross-Dimension 傳輸指的是,我可以從原本的世界傳訊到地獄,或是反過來從地獄傳來訊息 ~~~ (聽起來有點可怕)
實測的結果,每次進出地獄,電腦就 reboot 重開機,所以這部分我也無法向大家介紹了 :P

回到正題,為何要扯 Ender Modem?
想像一下你要建造一個超大範圍 GPS 系統,而根據之前實測,Wireless Modem 傳輸距離大約 64 格方塊,難不成你要為此到處放 Repeater 來延展訊號嗎?!那不累死 ...
所以,你 GPS 系統的四台電腦,都應該要搭配 Ender Modem
這樣只要你在非常遙遠的電腦也是安裝 Ender Modem,就可以隨時取得座標了!

電腦不會動,取得座標幹嘛?!

電腦雖然不會動,取得座標意義似乎不大?
但到目前為止,我還有一個重要角色沒介紹,那就是 Turtle 小烏龜!
它是可以到處移動的電腦!很多之前介紹過的指令,它也都可以用
如果你的小烏龜在遠處挖礦砍樹不知去哪了,你就可以設計小烏龜綁 Ender Modem
並每隔一段時間回傳自己座標,是不是很可愛 XD

除了 Turtle 小烏龜,還有手持裝置 Pocket Computer 也可能會需要取得自己的座標

CC: Tweaked GPS 設計原理

最後,我來挖一下到底它 GPS 系統怎麼實作的
先看 /rom/programs/gps.lua
以下我刪去很多細節程式碼

if sCommand == "locate" then
    -- Just locate this computer (this will print the results)
    gps.locate(2, true)

elseif sCommand == "host" then
    -- 判斷是否為 Pocket Computer,是的話就報錯,GPS 的基地台電腦位置必須固定

    -- 尋找 Wireless Modem / Ender Modem,如果沒有就報錯

    -- 取得玩家輸入的 x y z 座標

    -- Open a channel
    local modem = peripheral.wrap(sModemSide)
    modem.open(gps.CHANNEL_GPS)     -- 特殊 Channel,65534

    -- Serve requests indefinately
    local nServed = 0
    while true do
        local e, p1, p2, p3, p4, p5 = os.pullEvent("modem_message")
        if e == "modem_message" then
            -- We received a message from a modem
            local sSide, sChannel, sReplyChannel, sMessage, nDistance = p1, p2, p3, p4, p5
            if sSide == sModemSide and sChannel == gps.CHANNEL_GPS and sMessage == "PING" and nDistance then
                -- We received a ping message on the GPS channel, send a response
                modem.transmit(sReplyChannel, gps.CHANNEL_GPS, { x, y, z })
            end
        end
    end
end

可以看到 gps host 指令的實作,仍然是去監聽底層的 modem_message 事件
並判斷是否為特定 GPS Channel,以及訊息是否為 "PING"
是的話,就回應自己的 x y z 座標

至於 gps.locate
則要參考 /rom/apis/gps.lua
以下是非常簡略地解釋其邏輯

-- 收到 locate 指令,會向 GPS Channel 發出 "PING" 訊息
modem.transmit(CHANNEL_GPS, CHANNEL_GPS, "PING")

while true do
    local e, p1, p2, p3, p4, p5 = os.pullEvent()
    if e == "modem_message" then
        -- 收到回應後,判斷是否為 GPS Channel,是的話就將座標暫存
        -- 當座標至少有 3 組或以上,就可以計算出目前電腦的 GPS 座標
    end
end

大家可以看到整個 GPS 的應用底層邏輯
也是完全依靠 Modem API
那麼 CC: Tweaked 的網路應用就介紹到這裡
下一回來玩玩新的道具~


上一篇
Day21 用更高階的網路框架實現更多功能
下一篇
Day23 CC: Tweaked 升級版的電腦
系列文
在麥塊的農場裡寫 Lua30

尚未有邦友留言

立即登入留言