【Swift 開發】#2 播棋 Mancala

Yesa
海大 SwiftUI iOS / Flutter App 程式設計
6 min readApr 3, 2023

--

在非洲每六十秒,就有一分鐘過去。在台灣玩非洲棋,時間一分分過去。

My Mancala App KV

成品特色:

  • 可變更主題 & 背景 & 音樂。
  • 生動的教學模式。
  • 利用圓餅圖顯示戰績。
  • 可選擇跟電腦 OR 朋友 PK。
  • 本地端儲存個人化設定 & 戰績。
  • ~~齁廚狂喜~~

遊戲規則:

  1. 遊戲目標: 讓靠近自己這排的右邊大洞裝滿愈多的寶石,遊戲結束時將比較雙方大洞的寶石數量。
rule 1

2. 一開始每人有 24 顆寶石,一個小洞裝 4 顆。輪到玩家的回合時,玩家可移動自己某個小洞的寶石。

(大洞的寶石無法移動,大洞的寶石數量代表分數)

rule 2

3. 寶石將一個個逆時針移動到旁邊的洞。當移動的最後一顆寶石落在自己的大洞時,可以再次移動自己小洞的寶石。

(寶石移動時不可落在對手的大洞)

rule 3

4. 移動的最後一顆寶石落在自己空的小洞,而且此洞的對面也有寶石時,兩個洞的寶石將被收到玩家的大洞。當某一邊的小洞沒有寶石時遊戲結束,此時畫面上小洞的寶石也會成為分數,它們將全部移動到大洞。

rule 4

程式介紹:

想到戰績表,那肯定是帶有旋轉動畫的圓餅圖吧!

起初,我找了很久 SwiftUI 有沒有辦法直接做出圓餅圖,後來我臨機一閃,為何我要執著於尋找現有的函式,或是其他大神的路徑繪畫法呢?

圓餅圖 in SwiftUI

我想到的是"疊圖",將起始的兩個半圓擺放好,在疊上兩個可以旋轉的半圓,若是左邊的機率高一些,左半邊旋轉的角度就多一些,反之同理。

疊圖的方式可以增加更多的元素,只要角度算的好,利用一圈疊一圈的方式,也可以繪製出更多選項的圓餅圖,有機會我會出一篇來詳細介紹(?

ZStack {
Circle()
.frame(width: 150, height: 150)
.foregroundColor(.red)
Circle()
.trim(from: 0.25, to: 0.75)
.frame(width: 150, height: 150)
.foregroundColor(.teal)
Circle()
.trim(from: 0.25, to: 0.75)
.frame(width: 150, height: 150)
.foregroundColor(.red)
.rotationEffect(Angle(degrees: isRotated ? -180+angle : -180))
.opacity(angle>0 ? 1:0)
Circle()
.trim(from: 0.25, to: 0.75)
.frame(width: 150, height: 150)
.foregroundColor(.teal)
.rotationEffect(Angle(degrees: isRotated ? angle : 0))
.opacity(angle<0 ? 1:0)
}

遊戲 AI 遵照我玩 Mancala 的思維,去判斷當下的最佳選擇

func gameAI(point: [Int]) -> Int {
let zero = point.filter { $0 == 0 }
var hole: Int

......

return hole
}

變更背景音樂的方式

guard let url = Bundle.main.url(forResource: songs[music], withExtension: "mp3") else { fatalError("Failed to find sound file.") }
let item = AVPlayerItem(url: url)
AVPlayer.bgQueuePlayer.replaceCurrentItem(with: item)

文字輸入效果

func typeWriter(at position: Int = 0) {
if position == 0 {
text = ""
}
if position < texts[page].count {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
text.append(texts[page][position])
typeWriter(at: position + 1)
}
}
if position == texts[page].count {
typeDone = true
}
}

若是在打字動畫還沒結束時加上新的文字會導致程式崩潰,所以我加上了typeDone去確認輸出有無結束。

--

--

Yesa
海大 SwiftUI iOS / Flutter App 程式設計

A student without a MacBook, trying to learn the Swift language with an iPad.