本課所學習的物理模擬,加上手勢互動與碰撞處理,可以應用在很多地方,也足以做出很好玩的3D遊戲。

筆者利用端午節假期,寫了一個「氣泡戳戳樂」遊戲:設想從從地板下放出 n 個上升氣泡,每個氣泡的初始位置與上升速度都不太一樣,戳到一個氣泡可得2分,若讓氣泡上升到天花板就扣1分。

為了讓遊戲更好玩,在其中一個氣泡藏有寶物(正十二面體),戳到可多得10分,不過上升速度會比較快,而且隨機出現。

Mac 可以用滑鼠玩,不過,若用 iPad 或 iPhone 手指觸控應該更好玩,甚至以後可改為 AR 遊戲,或以手把控制的射擊遊戲。

以下是在 Mac mini M2 上錄影,遊戲過程相當順暢,第一次20個氣泡,還算容易,第二次改100個氣泡,難度變很高。記得開啟喇叭:

https://youtu.be/_d9uxJx5n9I

程式用到三個音效,分別在得分、扣分、獲得寶物時,音效來源網址附在程式碼之中,下載後同樣用 QuickTime Player 輸出成壓縮格式 .m4a,再匯入 Swift Playground,會比原來 .wav 檔案小很多。

戳到氣泡時得2分,是利用6-11c手勢互動;氣泡上升到天花板扣1分,則是利用6-11d 碰撞處理;戳到寶物時,讓寶物掉下來,同樣沿用6-11c手勢互動。

這裡比較特別的地方,在於天花板要設定為動態本體(dynamic),才能和可動本體(kinematic)的氣泡發生碰撞。原先設想天花板為靜態本體(static),則無法與氣泡觸發碰撞事件。

天花板雖然設為動態本體,但又必須讓它固定不動,怎麼辦呢?只好解除重力的影響,讓它飄浮在固定位置,但這樣一來,就會被氣球往上頂,所以還要鎖住 Y 軸位移以及三軸旋轉,才能保持不動:

// 天花板設定為動態(.dynamic)才能與氣泡(.kinematic)碰撞
天花板模型.physicsBody = .init(mode: .dynamic)
天花板模型.physicsBody?.isAffectedByGravity = false
天花板模型.physicsBody?.isTranslationLocked.y = true
天花板模型.physicsBody?.isRotationLocked = (x: true, y: true, z: true)

那為什麼不將天花板設為靜態本體,而將氣泡改為動態本體呢?因為這樣一來,氣泡的動作就只能靠外力影響,無法人為控制上升速度。下一課會學習「力場」,可以更進一步熟悉動態本體的控制,或許就能想到不同的做法。