Mercurial > public > geoquiz
annotate GeoQuiz/Logic/GameProtocol+Extension.swift @ 13:bdfff35dd43c
implement RevenueCat
author | Dennis C. M. <dennis@denniscm.com> |
---|---|
date | Wed, 12 Oct 2022 11:47:29 +0200 |
parents | a793f33f05fb |
children | 136928bae534 |
rev | line source |
---|---|
3 | 1 // |
10
a793f33f05fb
refactor code and fix layout
Dennis C. M. <dennis@denniscm.com>
parents:
9
diff
changeset
|
2 // GameProtocol+Extension.swift |
3 | 3 // GeoQuiz |
4 // | |
5 // Created by Dennis Concepción Martín on 18/9/22. | |
6 // | |
7 | |
8 import Foundation | |
9 import SwiftUI | |
5 | 10 import AVFAudio |
3 | 11 |
12 protocol Game: ObservableObject { | |
13 | |
14 // Define generic type | |
15 associatedtype T: Equatable | |
16 | |
17 // Game | |
18 var data: [String: T] { get set} | |
6 | 19 var dataAsked: [String: T] { get set } |
3 | 20 var correctAnswer: (key: String, value: T) { get set } |
21 | |
22 // User | |
23 var userChoices: [String: T] { get set } | |
24 var userScore: Int { get set } | |
25 var userLives: Int { get set } | |
4 | 26 var correctAnswers: [String: T] { get set } |
27 var wrongAnswers: [String: T] { get set } | |
3 | 28 |
29 // Alerts | |
30 var alertTitle: String { get set } | |
31 var alertMessage: String { get set } | |
7 | 32 var showingGameOverAlert: Bool { get set } |
3 | 33 var showingEndGameAlert: Bool { get set } |
34 var showingWrongAnswerAlert: Bool { get set } | |
4 | 35 var showingExitGameAlert: Bool { get set } |
3 | 36 |
37 // Animations | |
38 var scoreScaleAmount: Double { get set } | |
39 var livesScaleAmount: Double { get set } | |
40 | |
5 | 41 // Sound effects |
42 var player: AVAudioPlayer? { get set } | |
8 | 43 |
44 func selector() | |
3 | 45 } |
46 | |
47 extension Game { | |
48 var questionCounter: Int { | |
49 dataAsked.count | |
50 } | |
51 | |
8 | 52 func askQuestion(selector: () -> Void) { |
3 | 53 guard questionCounter < data.count else { |
7 | 54 alertTitle = "⭐️ Congratulations ⭐️" |
55 alertMessage = "You completed the game." | |
3 | 56 showingEndGameAlert = true |
57 | |
58 return | |
59 } | |
60 | |
8 | 61 selector() |
3 | 62 } |
63 | |
8 | 64 func answer(_ choice: (key: String, value: T), selector: () -> Void) { |
10
a793f33f05fb
refactor code and fix layout
Dennis C. M. <dennis@denniscm.com>
parents:
9
diff
changeset
|
65 let haptics = Haptics() |
9 | 66 |
3 | 67 if correctAnswer == choice { |
9 | 68 haptics.success() |
6 | 69 playSound("correctAnswer") |
4 | 70 |
3 | 71 withAnimation(.easeIn(duration: 0.5)) { |
72 scoreScaleAmount += 1 | |
4 | 73 userScore += 1 |
3 | 74 } |
75 | |
4 | 76 correctAnswers[correctAnswer.key] = correctAnswer.value |
8 | 77 askQuestion { |
78 selector() | |
79 } | |
3 | 80 } else { |
9 | 81 haptics.error() |
6 | 82 playSound("wrongAnswer") |
3 | 83 |
84 withAnimation(.easeIn(duration: 0.5)) { | |
85 livesScaleAmount += 1 | |
4 | 86 userLives -= 1 |
3 | 87 } |
4 | 88 |
89 wrongAnswers[choice.key] = choice.value | |
7 | 90 |
91 if userLives == 0 { | |
92 alertTitle = "🤕 Game over 🤕" | |
93 alertMessage = "Get up and try again." | |
94 showingGameOverAlert = true | |
95 } else { | |
96 alertTitle = "🔴 Wrong 🔴" | |
97 alertMessage = "You have \(userLives) lives left." | |
98 showingWrongAnswerAlert = true | |
99 } | |
3 | 100 } |
101 | |
102 DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [self] in | |
103 withAnimation(.easeIn(duration: 0.5)) { | |
104 scoreScaleAmount = 1 | |
105 livesScaleAmount = 1 | |
106 } | |
107 } | |
108 } | |
5 | 109 |
8 | 110 func reset(selector: () -> Void) { |
7 | 111 dataAsked = [String: T]() |
112 userScore = 0 | |
113 userLives = 3 | |
114 correctAnswers = [String: T]() | |
115 wrongAnswers = [String: T]() | |
8 | 116 askQuestion { |
117 selector() | |
118 } | |
7 | 119 } |
120 | |
6 | 121 private func playSound(_ filename: String) { |
9 | 122 let user = User() |
5 | 123 |
9 | 124 if user.settings.sound { |
125 guard let soundFileURL = Bundle.main.url(forResource: filename, withExtension: "wav") else { | |
126 fatalError("Sound file \(filename) couldn't be found") | |
127 } | |
128 | |
129 do { | |
130 try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.ambient) | |
131 try AVAudioSession.sharedInstance().setActive(true) | |
132 } catch { | |
133 fatalError("Couldn't activate session") | |
134 } | |
135 | |
136 do { | |
137 player = try AVAudioPlayer(contentsOf: soundFileURL) | |
138 player?.play() | |
139 } catch { | |
140 fatalError("Couldn't play sound effect") | |
141 } | |
5 | 142 } |
143 } | |
3 | 144 } |