iT邦幫忙

2021 iThome 鐵人賽

DAY 18
0
Software Development

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

Day18 將電腦接上印表機,將程式碼或文章包裝成書吧

  • 分享至 

  • xImage
  •  

今天來玩玩新的 CC: Tweaked 方塊:Printer
跟 Disk Drive 一樣,放置在電腦旁邊即可自動接上電腦。
這是印表機的使用畫面,左邊放置墨水,也就是麥塊裡面的各色「染料」,不過一次只能選擇一種顏色的染料。
右上方放置 CC: Tweaked Printed Page 也就是印表紙
列印的輸出則會自動放到第二排
但是印表紙無法自動堆疊,所以連續列印的話,一次最多六頁
CC: Tweaked Printer

那麼,要怎麼開始列印呢?
當我們把印表機接上電腦後,在使用 edit.lua 編輯檔案時,按下 Ctrl,除了原本的「Save」、「Exit」之外,還可以看到多一個「Print」選項,點了之後就會開始將檔案內容印到紙張上。檔案內容如果太多,則會自動印成多張紙。
這時候如果缺墨水或是缺紙,都會有提示訊息。
把列印成功後的紙張拿下來一看,會長這個樣子,至於內容當然就是看你檔案了
這真是太神奇了,在麥塊裡面開機、寫 Code、看大螢幕、還可以把 Code 印出來保存!
CC: Tweaked Printed Pages Preview

但是如果你要印的頁面很多,這樣就會很佔物品欄空間,所以 CC: Tweaked 還提供將多張紙綑在一起的方式,如下圖,將列印後的紙再加上一條線,就變成了「Printed Pages」
把 Printed Pages 使用拿起來看時,可以按左右方向鍵來閱讀上下頁
CC: Tweaked Printed Pages

CC: Tweaked 甚至還提供將一綑紙張再次包裝成書的方式,如下圖。使用書的方式一樣透過左右鍵,跟 Printed Pages 沒什麼不同,差別似乎只是更有儀式感 XD ?
CC: Tweaked Printed Books

這是閱讀一本書的畫面
CC: Tweaked Printed Books Preview

CC: Tweaked Printer 可以多色列印嗎?

礙於這款印表機的設計,如果要連續列印,只能選擇單一顏色染料
如果想要印出多個顏色,就需要手動操作,步驟如下:

  1. 先印一部分
  2. 換印表機墨水
  3. 把剛印完的紙拿回去再印
  4. 透過 Printer API setCursorPos(x, y),getCursorPos() 更改列印的位置
  5. 再次列印

這樣就可以變相的印出多色紙張,這部分有興趣可自行嘗試,我就不 demo 了
其實印表機如果可以提供填充墨水的 API,會方便很多啊!

自行撰寫 Printer API 來操作 CC: Tweaked 印表機

以下是透過 Printer API 自己撰寫的片段,可以看到要列印紙張其實還滿容易的!

printer = peripheral.wrap('back')
if (printer.getInkLevel() > 0 and printer.getPaperLevel() > 0) then -- 檢查墨水和紙張
    if (printer.newPage()) then         -- 準備列印新的一頁,這時候還是會再次檢查紙張
        print(printer.getPageSize())    -- 示範如何取得紙張大小
        printer.setPageTitle("ironman") -- 設定頁面標題
        printer.write(2021)             -- 要列印的內容
        printer.endPage()               -- 結束這張紙的列印
    end
end

體驗過印表機的操作後,我也還是嘗試了解 Printer 背後原理。

edit.lua #84
這個是在檔案編輯後按下 Ctrl 按鈕,會判斷電腦是否有接印表機,有的話就出現「Print」選項
此時不會檢查印表機墨水和紙張

if peripheral.find("printer") then
    table.insert(tMenuItems, "Print")
end

edit.lua #337
這一大段是使用者按下「Print」後的操作

Print = function()
    local printer = peripheral.find("printer")  -- 再次檢查印表機是否 ready
    if not printer then
        sStatus = "No printer attached"
        return
    end

    local nPage = 0                             -- 總共列印的頁面數
    local sName = fs.getName(sPath)
    if printer.getInkLevel() < 1 then           -- 檢查印表機墨水
        sStatus = "Printer out of ink"
        return
    elseif printer.getPaperLevel() < 1 then     -- 檢查印表機紙張
        sStatus = "Printer out of paper"
        return
    end

    local screenTerminal = term.current()
    local printerTerminal = {
        getCursorPos = printer.getCursorPos,
        setCursorPos = printer.setCursorPos,
        getSize = printer.getPageSize,
        write = printer.write,
    }
    printerTerminal.scroll = function()
        if nPage == 1 then
            printer.setPageTitle(sName .. " (page " .. nPage .. ")")
        end

        while not printer.newPage() do
            if printer.getInkLevel() < 1 then
                sStatus = "Printer out of ink, please refill"
            elseif printer.getPaperLevel() < 1 then
                sStatus = "Printer out of paper, please refill"
            else
                sStatus = "Printer output tray full, please empty"
            end

            term.redirect(screenTerminal)
            redrawMenu()        -- 每次要改變螢幕訊息時,都要重新繪製 Menu button,但原理我沒看懂 @@
            term.redirect(printerTerminal)

            sleep(0.5)
        end

        nPage = nPage + 1
        if nPage == 1 then
            printer.setPageTitle(sName)
        else
            printer.setPageTitle(sName .. " (page " .. nPage .. ")")
        end
    end

    bMenu = false
    term.redirect(printerTerminal)          -- terminal 導向印表機,開始列印
    local ok, error = pcall(function()
        term.scroll()
        for _, sLine in ipairs(tLines) do
            print(sLine)
        end
    end)
    term.redirect(screenTerminal)           -- terminal 導回電腦螢幕
    if not ok then
        print(error)
    end

    while not printer.endPage() do          -- 印表機的輸出空位滿了,這時候將輸出的紙張拿起來後,會繼續自動列印
        sStatus = "Printer output tray full, please empty"
        redrawMenu()
        sleep(0.5)
    end
    bMenu = true

    if nPage > 1 then
        sStatus = "Printed " .. nPage .. " Pages"
    else
        sStatus = "Printed 1 Page"
    end
    redrawMenu()
end,

CC: Tweaked 印表機的分享就到這裡
目前為止,我們已經有 Disk Drive、Speaker、Printer、Monitor 等電腦週邊
而且和電腦介接的方式都完全一致,只有六個方位可以放置
那如果我們真的需要多個磁碟機、印表機
甚至我就是想要雙螢幕、三螢幕來寫 Code 呢 ...
下一回我來試著讓這個願望成真吧!


上一篇
Day17 將電腦接上喇叭 - 談 Lua 的錯誤處理
下一篇
Day19 將電腦接上數據機和網路線
系列文
在麥塊的農場裡寫 Lua30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言