이 게임에서 스토리는 트리 구조를 따른다.
즉, N
번째 스토리에서 플레이어가 선택을 하면 다음 스토리는 아래 규칙에 따라 결정된다.
이게 2차원 배열로해서 처리해주기에는 매 row마다 길이도 달라지고 번거로워질 것 같아서, 한 번 쭉 1차원 배열로 한다는 가정하에 노드에 인덱스를 매겨봤다.
그랬더니 다음과 같이
1번 -> 다음 스토리단계(N) = `N -> 2N + 1`
2번 -> 다음 스토리단계(N) = `N -> 2N + 2`
1번과 2번을 어떻게 인지하냐!?
이렇게 View속성에서 tag
를 달아줬다. 각각 1과 2를 달았으니 그냥
2 * step + choice
를 하면 되는 것이다. choice
는 uibtn.tag
로 가져왔다.
mutating func nextStep(_ choice: Int) {
step = 2 * step + choice // 선택지(태그값 1 또는 2) - 다음 스토리로 이동
}
📌 다시 시작 버튼 (IBAction
)
@IBAction func restartGame(_ sender: UIButton) {
StoryBrain.shared.step = 0 // 처음 스토리로 되돌리기
updateUI() // UI 업데이트
}
MVC패턴 강의 챌린지의 일환이라 이를 StoryBrain
이라는 Model에서 관리한다.
스토리 데이터는 Story
구조체를 배열로 저장하며, 현재 진행 중인 스토리(step
)를 기준으로 선택지에 따라 이동해준다 !
StoryBrain.swift
struct StoryBrain {
let StoryArr: [Story] = [
Story(
title: """
당신은 고대 신전 앞에 서 있습니다.
신전 안으로 들어갈까요, 아니면 주변을 먼저 살펴볼까요?
""",
choice: ["신전 안으로 들어간다.", "주변을 살펴본다."]
),
Story(
title: """
신전 안으로 들어오니, 왼쪽 복도와 오른쪽 복도로 나뉘어 있습니다.
왼쪽 복도는 어둡고 축축하며, 오른쪽 복도는 희미한 빛이 새어 나옵니다.
어느 쪽으로 갈까요?
""",
choice: ["왼쪽 복도로 간다.", "오른쪽 복도로 간다."]
),
...
]
var step = 0 // 현재 스토리 위치
func getStoryText() -> String {
return StoryArr[step].title
}
func getStoryChoices() -> [String] {
return StoryArr[step].choice
}
mutating func nextStep(_ choice: Int) {
if 2 * step + choice < StoryArr.count {
step = 2 * step + choice // 다음 스토리로 이동
} else {
handleEnding(choice) // 엔딩 처리
}
}
private mutating func handleEnding(_ choice: Int) {
if choice == 1 {
step = 0
} else {
exitApp()
}
}
private func exitApp() {
UIApplication.shared.perform(#selector(NSXPCConnection.suspend))
}
}
handleEnding(_:)
함수 추가 → 엔딩 시 처리 로직을 분리해 가독성을 높임. exitApp()
함수 추가 → 앱 종료 기능을 별도로 관리할 수 있도록 분리. 일반적으로 iOS에서는 exit(0)
을 사용하여 앱을 강제 종료하는 것을 권장하지 않는다고 해서 .
how to exit ios app properly
그래서 이렇게 좀 알아본결과 홈 화면으로 튕기게? 할 수 있는 방식을 추천받았다.
UIApplication.shared.perform
)private func exitApp() {
UIApplication.shared.perform(#selector(NSXPCConnection.suspend))
}
근데 여론을 보니 이것도 그렇게 칭찬받는 방법은 아니고,
"종료" 팝업을 띄워서 사용자가 직접 나가도록 유도하는 것이 UX적으로도 더 타당하다고 한다 !
2N + 1, 2N + 2
공식 적용)isHidden
활용하여 버튼 가시성 조절)UIApplication.shared.perform
)