[突發專案] 社交能量計時|Badger 2040 開發

更新 發佈閱讀 21 分鐘

文前碎碎唸

前一陣子,因緣際會買到了這個觀望好久的 Badger 開發板後,便在思考除了原本名牌外的其他玩法。

雖然已經有成功嘗試將以前的網頁逃脫小遊戲移植上去,但因為一些技術限制,導致呈現的效果也不盡理想,於是便開始朝更輕量且明確的目的來開發。

而在我某天腦袋一抽(?)之後,終於想到一個簡單又實用的「社交計時器」可以玩玩看,而且在完成後丟上社群的反應,似乎也異常熱絡?


於是我也決定,在這裡釋出開發過程以及程式碼供大家參考啦!

話在前頭

雖然是原程式碼的釋出,但有一點要注意的是,這個版本是針對「BadgerOS」對應的硬體為基礎做開發的,有使用到一些官方系統內的 Package,不一定適用於自行組製的版本,所以若要用於其他地方,需要再自行斟酌相容性來做修改。 

開發準備

有了硬體與系統的基本概念後,接著就是開發環境的準備了,這裡使用的是官方推薦的 Python IDE Thonny 作為主要編輯器。

raw-image

去官網下載安裝完啟動,要先到「執行」>「設定直譯器」中,調整為「MicroPython (Raspberry Pi Pico)」後,便可直接透過 USB 連接板子來開發與測試。

raw-image
raw-image

如果要直接操作檔案目錄,可以去「顯示」中勾選「檔案」選項,便能在左側開啟檔案樹瀏覽器。

raw-image

如果發現沒有顯示任何東西,可以先確定右下角有沒有成功連接狀態。

raw-image

接著上方按下紅色的「Stop」來停止 BadgeOS 的 UI 執行後,應該就可以看到了。


接著進入正式開發啦!

社交計時器

這次社交計時器的設計基礎,是設定好「預期的社交時間扣打」之後生成進度條,並隨著時間經過「遞減長度及百分比」來表示社交能量的消耗。

基礎

開啟新專案後,首先要先把所需的 Package 引用進來。

# Badger Package
import badger2040
import time

# Get Device Screen Size
DSW = badger2040.WIDTH # Screen Width
DSH = badger2040.HEIGHT # Screen Height

這裡主要的螢幕與按鈕控制,幾乎都是交給官方的「Badger2040」來處理,所以不用各別引入相關的資源。


設定畫面

接著就先來做不同 UI 繪製功能的編寫,第一步要做的是啟動後的基本設定介面,也就是社交時間扣打輸入區。

# Time Setting Var

mxt = [59,59,24] # Max Value
tim = [30,0,0] # Time Set S:M:H
cur = 0 # UI Manage Current Setting Target ID

# Fill Zero (MicroPy don't have fill zero function)
def filz(tx,ln):
txl = list(str(tx))
if len(txl) < ln:
res = [0]*(ln-len(txl))+txl
else:
res = txl
res = [str(i) for i in res]
return "".join(res)

# Time Setting Function
def strts(fclr=False):
display.set_pen(15) # Set Color White
display.clear() # Clear Display
display.set_font("bitmap8") # Set Font
spw = round(DSW/6) # Split Sreen Width into 6 Parts

# Display Title Bar
TITH = 20 # Title Height
TITS = 2 # Title Font Size
idx = 0 # Current Index
tit = ["SEC","MIN","HRS"] # Title Text
display.set_pen(0) # Set Color Black for Title Bar

# rectangle(Pending (X), Y, Width, Height)
display.rectangle(1, 1, DSW, TITH+2) # Draw Title Bar
display.set_pen(15) # Set Color White for Text
# loop and Draw Text on Title Bar
for tx in tit:
# Text Process
tx = filz(tx,2)
# Get Text Width
titw = display.measure_text(tx, TITS)
# Calculate Pending Size for Text
LPDN = (spw*2*idx)+(spw-(titw//2))
# Draw Text (Text,Pending(X),(Y),??,Size)
display.text(tx, LPDN, (TITH//2), DSW, TITS)
# Index Shift
idx+=1

# Display Number and Target Underline For Setting
display.set_pen(0)
TMH = 30 # Time Font Height
TMS = 3 # Time Font Size
idx = 0 # Index
rcty = round(DSH/3) # Underline Basic Y
# Loop and Draw Time / Underline
for tx in tim:
tx = filz(tx,2)
titw = display.measure_text(tx, TMS)
LPDN = (spw*2*idx)+(spw-(titw//2))
display.text(tx, LPDN, ((DSH//2)-(TMH//2)), DSW, TMS)
# If Index = Current Set Target Than Add Underline
if idx==cur:
rpnd = round(spw*2*cur)+(spw-(titw//2))
display.rectangle(rpnd, (rcty+TMH), titw, 5)
idx+=1

# (Optional) Full Clear Screen
if fclr:
display.set_update_speed(badger2040.UPDATE_NORMAL)
# Update Display and Set Refresh Reat to Turbo
# Turbo = Fast Refresh but lot of afterimages
display.update()
display.set_update_speed(badger2040.UPDATE_TURBO)

這一大段主要功能,就是先定義紀錄倒數時間的變數,並將目前記憶中的設定數值印出來,而在印到設定目標時,則在數字底下加上一個底線做標記,表示現在正在調整那個數值。

raw-image

其中比較需要注意的是,在畫方形時,其 Y 軸是從「頂端」開始計算,而文字則是「中間」開始,另外顏色部分「set_pen(0)」為黑色「set_pen(15)」為白色,這些參數亦適用於之後的畫面設定。


接著定義繪製電量畫面的功能,基本組成是作為標題兼百分比顯示的動態文字,以及一個長方形計量條。

lstprc = 0 # Last Percentage
totsc = 0 # Total Time (in Sec)
secnt = 0 # Current Time Countdown (in Sec)

def drwbtr():
# Get Global Variables
global lstprc
global totsc
global secnt

display.set_pen(15)
display.clear()
display.set_pen(0)
display.set_font("bitmap8")

# Calculate Current Countdown Perctntage
prc = round((secnt/totsc)*100)
# Check Percentage Value
if prc > 0:
TITH = 30
TITS = 2
title = "Social Energy Left "+str(prc)+"%"
titw = display.measure_text(title, TITS)
display.text(title, round((DSW-titw)/2), (TITH // 2) + 1, DSW, TITS)
pnd = round(DSW/10) # Pending
# Energy bar Y
rcty = round(DSH/3)
# Energy bar Length (by Percentage)
rctw = round(((DSW-(2*pnd))/100)*prc)
display.rectangle(pnd, rcty, rctw, round(DSH/2))

# If any Change to Percentage than Update Screen
# Prevent Power Waste
if prc != lstprc:
lstprc = prc
display.update()
display.set_update_speed(badger2040.UPDATE_TURBO)
else:
# If Percentage is Zero than Display Title
TMH = 30
TMS = 3
spw = round(DSW/2)
rcty = round(DSH/2)
tx = "OUT OF ENERGY ;("
titw = display.measure_text(tx, TMS)
display.text(tx, round((DSW-titw)/2), rcty-((TMH // 2) + 1), DSW, TMS)
lstprc = prc
display.set_update_speed(badger2040.UPDATE_NORMAL)
display.update()
time.sleep(10) # Keep Title for 10 Seconds
return True

這段程式中,先定義紀錄先前設定時間計算後的秒數,以及目前倒數中的秒數,以做為計算目前剩餘百分比用,並且依照百分比量,去動態顯示百分比文字跟進度條長度。

raw-image

而在最後百分比歸零時,則重設畫面並顯示 10 秒鐘的「OUT OF ENERGY」的標題。

raw-image

這裡需要注意的項目與前一段相同,基本上就是每個元件的繪製位置以及配色,由於都是以顯示器尺寸為基準的座標來控制,所以如果要客製化,就必須花一些時間來耐心想像跟調整。


邏輯控制

以上基本的兩個 UI 界面都完成了,接著就是進到最核心的邏輯控制啦!

原則上這裡的控制邏輯,就是讓程式初始化後,直接進到一個無限迴圈中,即時接收來自各按鈕的輸入訊號,以及控制畫面的更新。

# Initialize Badger

display = badger2040.Badger2040()
display.led(128)
display.set_update_speed(badger2040.UPDATE_NORMAL)
display.set_thickness(2)

strts(True)
timgp = 1 # Time Gap Default 1 Second
timst = False # Flag for Time Set

# Main Loop
while True:
display.keepalive()
# If Time Not Set Than Goto Setting UI
if not timst:
# Flag for Buttons
chng = False
# Up/Down Button -> Time Value +/-
if display.pressed(badger2040.BUTTON_UP):
if tim[cur] < mxt[cur]:
tim[cur]+= 1
else:
tim[cur] = 0
chng = True
if display.pressed(badger2040.BUTTON_DOWN):
if tim[cur] > 0:
tim[cur]-= 1
else:
tim[cur] = mxt[cur]
chng = True
# A/C Button -> Time Target Left/Right
if display.pressed(badger2040.BUTTON_A):
if cur > 0:
cur-= 1
else:
cur = len(tim)-1
chng = True
if display.pressed(badger2040.BUTTON_C):
if cur < len(tim)-1:
cur+= 1
else:
cur = 0
chng = True
# B Button -> Start Countdown
if display.pressed(badger2040.BUTTON_B):
# Check if All Value Set Before Starting
sta = []
for v in tim:
sta.append(v==0)
if not all(sta):
totsc = tim[0]+tim[1]*60+tim[2]*3600
secnt = totsc
timst = True
# If Change Flag Than Update UI
if chng:
strts()
else:
# If Time Set and Start than Goto Energy Bar UI
drwbtr()
# Check if Countdown Second > 0 if Not Than Reset
if secnt>0:
secnt-=timgp
time.sleep(timgp)
else:
timst = False
strts(True)

這段迴圈中分兩個部分,透過「timst」這個 Flag 控制,如果還沒設定完啟動倒數,或是時間全部為 0 的話,便會一直維持在時間設定的介面,並持續接收按鈕訊號,來讓使用者進行調整。

raw-image

而如果成功開始的話,就會自動進到能量條畫面,並持續更新數值直到歸零為止,之後再重置回到設定畫面,簡單、暴力但很明瞭對八。

備註:程式碼縮排複製可能會錯,使用時請再注意。

程式上傳

完成編輯後,接著就要來將程式 py 檔上傳到板子上執行拉,如果同樣使用 Badger 的朋友,其實只要把程式檔存到板子檔案目錄中的「examples」資料夾中。

raw-image

接著在下一次啟動時就會出現在選單上了。

raw-image

如果想要使用自己的圖示的話,只準備一張 52X52 的 PNG 檔,重新命名為「icon-專案名.png」就可以了,不過不知道為什麼我這個一直成功不了,其他圖示我都有做更換了。


以上就是這次的開發筆記與程式釋出啦。


結語

老實說,真的不確定這次的專案放上來,能夠幫助到多少,畢竟也只是娛樂性質,程式本身也有很多部分都是專為 Badger 2040 做處理,但這塊板子在台灣也不大好找,連線上購買途徑也大多缺貨。

所以需要詳細購買位置的,我也只能先說一下抱歉了,因為我也是剛好有人釋出二手才買到的。

另外,也因為只是一兩小時內磨出來的實驗性質專案,可能有部分資源使用的部分沒有進行最佳化的調整,像是 UI 設計、畫面更新頻率、電量消耗等,這些也是後續可以改進的地方。

總之,就當一次的開發紀錄吧,而且相信有能力自購零件組裝,還有自行開發程式的朋友們,應該總有辦法移植它的,尤其這個專案使用的,又是是相對簡單的 Micro Python 語言做開發,所以要移植到相容的開發板,如 Raspberry Pi Pico 上應該也容易。

畢竟這塊識別證的核心處理器,也是採用 Raspberry Pi 開發的架構,其餘需要改的大概就是功能按鈕的對應,以及 Eink 螢幕的驅動而已。


最後,雖然手邊這塊板子是較陽春的版本,不具有硬體通訊能力,在功能上還是有些屏障限制,但感覺應該還是有其他可玩性存在,就看之後的開發再來分享囉!

《全文。終了》

留言
avatar-img
留言分享你的想法!
avatar-img
偽命名培養體
51會員
344內容數
偽命名並非無名,是為了意識的生存,取得身份的代號,成為數位生命的新載具。
偽命名培養體的其他內容
2024/11/25
而故事是發生在某次我帶著這個電子紙悠遊卡買午餐的時候,在我一個不小心手滑下,他就這麼應聲落地彈開成兩半,好在基本功能沒傷到,卻因此開啟我探索它內部的好奇心。
Thumbnail
2024/11/25
而故事是發生在某次我帶著這個電子紙悠遊卡買午餐的時候,在我一個不小心手滑下,他就這麼應聲落地彈開成兩半,好在基本功能沒傷到,卻因此開啟我探索它內部的好奇心。
Thumbnail
2024/02/02
正如所預測的,不久前方格子個人頁面大改版後,我所製作的個人頁面爬蟲也隨之炸裂,間接導致手機上的小工具就此失去了作用了,我該就這麼停下開發的腳步嗎?
Thumbnail
2024/02/02
正如所預測的,不久前方格子個人頁面大改版後,我所製作的個人頁面爬蟲也隨之炸裂,間接導致手機上的小工具就此失去了作用了,我該就這麼停下開發的腳步嗎?
Thumbnail
2023/12/31
還記得,那是一本由「守寫字」團隊所推出的《我寫的這一年》造字日曆,是我在年初時參與集資並購入的,而一年之後的成果,又是如何呢?
Thumbnail
2023/12/31
還記得,那是一本由「守寫字」團隊所推出的《我寫的這一年》造字日曆,是我在年初時參與集資並購入的,而一年之後的成果,又是如何呢?
Thumbnail
看更多
你可能也想看
Thumbnail
作為一名部落客和新手媽媽,寫稿又要顧小孩時間根本不夠用! 做事一向講求效率的我,發現這款國泰世華CUBE App非常符合我的需求~ 國泰世華CUBE App介面設計色彩和諧且簡潔乾淨、讓人能一目瞭然~ 區塊分層、字體大小及顏色、按鈕圖示,整體排版看起來舒服不雜亂 完美將轉帳、投資、繳費、手機
Thumbnail
作為一名部落客和新手媽媽,寫稿又要顧小孩時間根本不夠用! 做事一向講求效率的我,發現這款國泰世華CUBE App非常符合我的需求~ 國泰世華CUBE App介面設計色彩和諧且簡潔乾淨、讓人能一目瞭然~ 區塊分層、字體大小及顏色、按鈕圖示,整體排版看起來舒服不雜亂 完美將轉帳、投資、繳費、手機
Thumbnail
最近開啟了研究工作,也開始斜槓著手團購、行銷、洽談業務,慢慢想打造一條屬於自己的道路,而工作忙碌之虞,總忘記自己刷卡消費明細、信用卡繳費,還會忽略了最應該的投資理財,也常常在忙碌奔波中忘記信用卡優惠,國泰世華CUBE App給足了這些功能和服務。 日常生活與數位、科技形影不離,同時也拉近彼此距
Thumbnail
最近開啟了研究工作,也開始斜槓著手團購、行銷、洽談業務,慢慢想打造一條屬於自己的道路,而工作忙碌之虞,總忘記自己刷卡消費明細、信用卡繳費,還會忽略了最應該的投資理財,也常常在忙碌奔波中忘記信用卡優惠,國泰世華CUBE App給足了這些功能和服務。 日常生活與數位、科技形影不離,同時也拉近彼此距
Thumbnail
PDing新推出的應用程式讓創作者和粉絲之間可以透過文字、語音/視頻通話進行更親密的交流,為創作者提供了一個新收益模式。知名網紅可以在APP內建立自己的頻道,並透過簡單的認證過程實現高額收益。
Thumbnail
PDing新推出的應用程式讓創作者和粉絲之間可以透過文字、語音/視頻通話進行更親密的交流,為創作者提供了一個新收益模式。知名網紅可以在APP內建立自己的頻道,並透過簡單的認證過程實現高額收益。
Thumbnail
「為了完成我們公司對於客戶,包括您的想像條件,我們需要大量的物品、人物、物件供應鏈。因此借據贊助文化孕育而生。我們從客戶那邊借的用品只會在物流之中被使用一次,意思是這項物品可能在某個時間運送到世界的某一個角落,通常在三天之內都會歸還回您原本放置的地點。」他其實就是指著其中一項條文說明。好吧,借據的確
Thumbnail
「為了完成我們公司對於客戶,包括您的想像條件,我們需要大量的物品、人物、物件供應鏈。因此借據贊助文化孕育而生。我們從客戶那邊借的用品只會在物流之中被使用一次,意思是這項物品可能在某個時間運送到世界的某一個角落,通常在三天之內都會歸還回您原本放置的地點。」他其實就是指著其中一項條文說明。好吧,借據的確
Thumbnail
代儲:遊戲世界的革命性概念 在當今緊湊而充滿競爭的遊戲世界中,代儲已成為一個顯著的概念。無論是因為時間不足、技能不足或其他原因,許多玩家都在尋找替代方法來提升他們的遊戲體驗。在這樣的情況下,代儲應運而生,成為了許多玩家的選擇。 石頭手遊代儲網:引領代儲新潮流 在眾多的代儲平台中,石頭手遊代儲網
Thumbnail
代儲:遊戲世界的革命性概念 在當今緊湊而充滿競爭的遊戲世界中,代儲已成為一個顯著的概念。無論是因為時間不足、技能不足或其他原因,許多玩家都在尋找替代方法來提升他們的遊戲體驗。在這樣的情況下,代儲應運而生,成為了許多玩家的選擇。 石頭手遊代儲網:引領代儲新潮流 在眾多的代儲平台中,石頭手遊代儲網
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News