Quoridor iOS Game:Part 1
驗證(註冊/登入)、個人檔案頁面、角色頭像設計
整個遊戲的畫面設計配色使用星宇航空的配色,也模仿了許多現有 App 的畫面,如:Pokémon GO、Instagram。
遊戲註冊/登入
Facebook、Google、Twitter、Email、忘記密碼
登入流程與畫面設計模仿 Pokémon GO,讓玩家先選擇是「回鍋玩家」還是「新玩家」,之後再選擇要使用 Facebook、Google、Twitter 或 Email 註冊登入,在畫面的轉換過程中也使用了 withAnimation
來呈現動畫效果。
不管是選擇回鍋還是新玩家,都會進到同一個畫面,只是會根據一開始玩家的選擇來決定顯示「Sign in」或「Sign up」,這是因為 Facebook 登入、Google 登入、Twitter 登入,並不會因為是註冊或登入而在驗證流程上有什麼不同(程式碼並無不同)。
按下 Facebook 登入、Google 登入或 Twitter 登入就會開始各自的驗證流程,順利的話就會直接進入到遊戲,如果在登入時發現是新用戶(Firestore 中沒有玩家資料),就會直接使用這些社群帳號的頭像與 Email 來初始設定玩家的資料,只是可惜的是抓到的頭像畫質都不高。而如果中途取消或遇到錯誤失敗的話,就會跳出自己設計的 Alert
,但因為可能發生的錯誤太多了,就沒一一撰寫錯誤訊息,而是直接使用 error.localizedDescription
。
在整個 app 中,執行操作都會顯示 ProgressView
來讓使用者知道有點擊到有在執行,而不會說按了都沒動的感覺,因為像在使用社群媒體登入時,並不會馬上跳出驗證畫面。
接下來是使用 Email 註冊、登入、忘記密碼:
在 Email 的註冊與登入也是同一個畫面,但如果是從回鍋玩家進到這個畫面,就會多顯示忘記密碼的選項,讓使用者可以輸入 Email,我們就會寄發忘記密碼的信件,玩家可以點擊信中的連結就能重設新密碼。
但有個缺點是,這個重設密碼的信件總是會被丟到垃圾郵件裡⋯⋯。
在 Email 與 Password 的這兩個輸入框,使用到了 FocusState
與 onSubmit
來讓使用者可以在 Email 欄位輸入完時按下 Enter 直接切換到 Password 欄位,在 Password 欄位輸入完時按下 Enter 直接執行註冊或登入的 func
。
個人檔案頁面
TabView
、個人頁面、編輯個人資料
成功驗證進入到遊戲後,上方會顯示金幣數與星星數(之後會加入的遊戲設計,類似排位,贏了獲得星星,輸了掉星),下方使用 TabView
,可以手指左右滑來轉換頁面,或點擊底部自己設計的 icon 來切換畫面。
個人頁面顯示了:玩家頭像、名稱、加入日期、玩的場次數、勝率、最高星星數、年紀、星座、Email。
編輯個人資料的畫面模仿 Instagram,使用到 TextField
、Menu
搭配 Picker
、Slider
,點擊頭像下方的「Change profile photo」就會跳出選項,可以移除頭像(改使用存在 Firebase Storage 的預設頭像)、上傳照片(未來會使用新 iOS 16 的 PhotosPicker
)、設計角色(跳出頭像設計畫面)。這裡比較特別的是可以編輯 Email,這會更新當初註冊的 Email address,下次就可以使用更新後的 Email 登入,所以如果是使用 Facebook 登入、Google 登入或 Twitter 登入的話,就無法編輯 Email(顯示上 opacity
會設成 0.65,有點淡灰的感覺),但如果有額外連結 Email 帳號就可以編輯!(這部分後面會有說明)
接下來是設計角色的部分:
一進到角色設計的畫面,會先顯示上次儲存的設計樣式,可以使用 ColorPicker
選擇頭像底色,隨機設計時也會一同將底色的 Color
隨機,在顯示各個配件時,一樣使用自行設計的 TabView
跟 enum
綁定,好處是可以藉由左右滑動來切換配件類型,中間橫向的 ScrollView
也能根據 enum
來填滿按鈕底色與執行 scrollTo()
,而如果是直接點擊橫向的 ScrollView
中的按鈕也能連動到下方的 TabView
做切換,在某些的配件也設計了「不放」的按鈕,如:身體、眼睛、手,一定要放,所以不會有「不放」的按鈕。按下「Done」會上傳照片至 Firebase Storage 與更新玩家在 Firestore 中的頭像資料欄位,所以需要一點時間,一樣顯示 ProgressView
,完成後再將 sheet
收起。
在 View Model 中的所有 func
幾乎都使用到了 complete Result Type,來讓 View 可以知道有沒有執行成功或失敗,每個畫面一樣也設計了 Alert,如果 Result Type 是 .failure()
,就會把轉圈圈的 ProgressView
改成自己設計的 Alert 訊息(error.localizedDescription
),按下「OK」後,連同白底一起消失。
帳號設定
登出、刪除帳號、連結社群帳戶、變更密碼
整個設定的頁面也是模仿 Instagram。
刪除帳號會:將 Firebase Storage 中儲存的頭像刪除、將 Firestore 中的玩家資料刪除,這兩個都刪除完了會刪掉在 Auth 中的帳號,完成刪除帳號功能。
連結社群帳戶可以讓多個帳號同時綁定在同一個 Firebase 驗證帳號,玩家使用其中任一個社群帳戶就能登入遊戲存取同一個遊戲資料,特別的是,因為在設定中也設計了變更密碼的功能,所以會判斷如果使用者有綁定 Email,才能在設定中更換密碼,取消或沒有綁定 Email 的話,就無法再設定中找到變更密碼(在編輯個人資料裡也無法編輯 Email 欄位)。
而能綁定當然也能取消綁定,但我們還多做了一個機制,就是如果此帳號只剩下了一個綁定的帳號的話,就無法再繼續取消綁定了,因為 Firebase 可以取消綁定到一個都沒有,但這時玩家如果登出之後,就再也沒有任何方式能再次登入了,這會導致浪費 Firebase 的空間。
最後是更換密碼的部分了:
在這三個欄位,使用到了 FocusState
來判斷顯示提示字,如果處於 focus 狀態,提示字就會上移並縮小,當 focus 離開時,輸入欄位有值的話,提示字則會停留在上方維持縮小的狀態,但如果輸入欄位是空的話,提示字則會恢復原來的位置與大小。而這三個欄位同樣使用到了 onSubmit
來達到讓使用者只要按下 Enter 就能 focus 到下一個欄位,如果是在最後一個欄位「再次輸入新密碼」的 onSubmit
則會執行變更密碼的 func
(和右上方的「Save」做一樣的事)。
右上方的「Save」按鈕只有在三個欄位都有值,而且輸入兩次新密碼都相同時,才會變成可以按的橘色狀態。
最後一個欄位的提示字,會判斷使否兩次輸入的新密碼相同,如果不相同就會持續顯示錯誤紅字,但當還沒輸入,是空的欄位的話,則不會顯示錯誤,畢竟使用者都還沒輸入你就跟他說不對,這樣不太好。
這裡的判斷舊密碼,因為 Firebase 並無提供取得使用者密碼的功能,所以我們在使用者註冊時,就會用 @AppStorage
來儲存密碼,並與第一個欄位的值做判斷,要相同才會執行密碼變更。
GitHub Repository
Star this repo!
Medium Part 2 文章
遊戲功能、音樂、設定、排行榜、雙語、AdMod⋯⋯