-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsound_manager.cpp
More file actions
270 lines (241 loc) · 8.98 KB
/
sound_manager.cpp
File metadata and controls
270 lines (241 loc) · 8.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
#include "sound_manager.h"
using namespace SoundConfig;
/**
* @brief Constructor - initializes sound manager with default state
*/
SoundManager::SoundManager()
: ghost_chase_sound_playing_(false), current_ghost_chase_sound_(nullptr), ghost_blue_sound_playing_(false), start_sound_playing_(false), use_dot1_sound_(true), sound_base_path_(BASE_SOUND_PATH)
{
}
/**
* @brief Load all sound effects required for the game
* @return true if all sounds loaded successfully, false otherwise
*/
bool SoundManager::initialize()
{
try
{
// Load ghost chase sounds (based on pellet percentage)
load_sound_effect(GHOST_CHASE_SOUND_NAME, (sound_base_path_ + GHOST_CHASE_SOUND_FILE).c_str());
load_sound_effect(GHOST_CHASE_SOUND2_NAME, (sound_base_path_ + GHOST_CHASE_SOUND2_FILE).c_str());
load_sound_effect(GHOST_CHASE_SOUND3_NAME, (sound_base_path_ + GHOST_CHASE_SOUND3_FILE).c_str());
load_sound_effect(GHOST_CHASE_SOUND4_NAME, (sound_base_path_ + GHOST_CHASE_SOUND4_FILE).c_str());
load_sound_effect(GHOST_CHASE_SOUND5_NAME, (sound_base_path_ + GHOST_CHASE_SOUND5_FILE).c_str());
// Load pellet collection sounds
load_sound_effect(DOT1_SOUND_NAME, (sound_base_path_ + DOT1_SOUND_FILE).c_str());
load_sound_effect(DOT2_SOUND_NAME, (sound_base_path_ + DOT2_SOUND_FILE).c_str());
// Load power mode and ghost interaction sounds
load_sound_effect(GHOST_BLUE_SOUND_NAME, (sound_base_path_ + GHOST_BLUE_SOUND_FILE).c_str());
load_sound_effect(GHOST_EAT_SOUND_NAME, (sound_base_path_ + GHOST_EAT_SOUND_FILE).c_str());
load_sound_effect(GHOST_RETREAT_SOUND_NAME, (sound_base_path_ + GHOST_RETREAT_SOUND_FILE).c_str());
// Load game state sounds
load_sound_effect(START_SOUND_NAME, (sound_base_path_ + START_SOUND_FILE).c_str());
load_sound_effect(DIE_SOUND_NAME, (sound_base_path_ + DIE_SOUND_FILE).c_str());
load_sound_effect(CUTSCENE_SOUND_NAME, (sound_base_path_ + CUTSCENE_SOUND_FILE).c_str());
load_sound_effect(FRUIT_SOUND_NAME, (sound_base_path_ + FRUIT_SOUND_FILE).c_str());
return true;
}
catch (...)
{
return false;
}
}
/**
* @brief Update background audio based on current game mode and pellet percentage
* @param game_mode Current game state
* @param pellet_percentage Percentage of pellets remaining (0-100)
*/
void SoundManager::update_background_audio(GameMode game_mode, double pellet_percentage)
{
switch (game_mode)
{
case GameMode::STARTING:
// Game starting sequence - play start.wav once
if (!start_sound_playing_)
{
play_sound_effect(START_SOUND_NAME);
start_sound_playing_ = true;
}
break;
case GameMode::NORMAL:
{
// Ghosts are chasing Pac-Man - play appropriate chase sound based on pellet percentage
const char *required_chase_sound = get_chase_sound_for_percentage(pellet_percentage);
// If wrong sound is playing or no sound is playing, switch to correct one
if (!ghost_chase_sound_playing_ || current_ghost_chase_sound_ != required_chase_sound)
{
stop_current_chase_sound();
play_sound_effect(required_chase_sound, -1); // Loop infinitely
ghost_chase_sound_playing_ = true;
current_ghost_chase_sound_ = required_chase_sound;
}
}
break;
case GameMode::POWER_MODE:
// Pac-Man is chasing scared ghosts - play ghostblue.wav, stop chase music
stop_current_chase_sound();
if (!ghost_blue_sound_playing_)
{
play_sound_effect(GHOST_BLUE_SOUND_NAME, -1); // Loop infinitely
ghost_blue_sound_playing_ = true;
}
break;
case GameMode::GAME_OVER:
case GameMode::VICTORY:
// Game ended - stop all background sounds
stop_all_background_sounds();
break;
}
// Handle sound state cleanup based on mode changes
if (game_mode != GameMode::POWER_MODE && ghost_blue_sound_playing_)
{
stop_sound_effect(GHOST_BLUE_SOUND_NAME);
ghost_blue_sound_playing_ = false;
}
if (game_mode != GameMode::STARTING && start_sound_playing_)
{
stop_sound_effect(START_SOUND_NAME);
start_sound_playing_ = false;
}
}
/**
* @brief Play dot collection sound (alternates between dot1 and dot2)
*/
void SoundManager::play_dot_collection_sound()
{
if (use_dot1_sound_)
{
play_sound_effect(DOT1_SOUND_NAME);
}
else
{
play_sound_effect(DOT2_SOUND_NAME);
}
// Toggle for next time
use_dot1_sound_ = !use_dot1_sound_;
}
/**
* @brief Play ghost eat sound (when Pac-Man catches a scared ghost)
*/
void SoundManager::play_ghost_eat_sound()
{
play_sound_effect(GHOST_EAT_SOUND_NAME);
}
/**
* @brief Play ghost retreat sound (when ghost is caught and retreating)
*/
void SoundManager::play_ghost_retreat_sound()
{
play_sound_effect(GHOST_RETREAT_SOUND_NAME);
}
/**
* @brief Play cutscene sound (when level is completed)
*/
void SoundManager::play_cutscene_sound()
{
play_sound_effect(CUTSCENE_SOUND_NAME);
}
/**
* @brief Stop all background sounds (chase, power mode, start sounds)
*/
void SoundManager::stop_all_background_sounds()
{
stop_current_chase_sound();
if (ghost_blue_sound_playing_)
{
stop_sound_effect(GHOST_BLUE_SOUND_NAME);
ghost_blue_sound_playing_ = false;
}
if (start_sound_playing_)
{
stop_sound_effect(START_SOUND_NAME);
start_sound_playing_ = false;
}
}
/**
* @brief Stop all sounds completely (including sound effects)
*/
void SoundManager::stop_all_sounds()
{
stop_all_background_sounds();
// Note: Individual sound effects (dot collection, ghost eat, etc.)
// are short duration and don't need explicit stopping
}
/**
* @brief Get the appropriate ghost chase sound name based on pellet percentage
* @param pellet_percentage Percentage of pellets remaining (0-100)
* @return Sound name constant for the appropriate chase sound
*/
const char *SoundManager::get_chase_sound_for_percentage(double pellet_percentage) const
{
if (pellet_percentage > 75.0)
return GHOST_CHASE_SOUND_NAME; // ghost1.wav
else if (pellet_percentage > 50.0)
return GHOST_CHASE_SOUND2_NAME; // ghost2.wav
else if (pellet_percentage > 25.0)
return GHOST_CHASE_SOUND3_NAME; // ghost3.wav
else if (pellet_percentage > 10.0)
return GHOST_CHASE_SOUND4_NAME; // ghost4.wav
else
return GHOST_CHASE_SOUND5_NAME; // ghost5.wav
}
/**
* @brief Stop the currently playing ghost chase sound
*/
void SoundManager::stop_current_chase_sound()
{
if (ghost_chase_sound_playing_ && current_ghost_chase_sound_ != nullptr)
{
stop_sound_effect(current_ghost_chase_sound_);
ghost_chase_sound_playing_ = false;
current_ghost_chase_sound_ = nullptr;
}
}
/**
* @brief Set the base path for sound files
* @param base_path The base directory path for sounds (e.g., "Resources/Sounds/Normal/")
*/
void SoundManager::set_sound_base_path(const std::string &base_path)
{
sound_base_path_ = base_path;
// Ensure the path ends with a slash
if (!sound_base_path_.empty() && sound_base_path_.back() != '/')
{
sound_base_path_ += '/';
}
}
/**
* @brief Unload all currently loaded sounds to allow reloading with different files
*/
void SoundManager::unload_all_sounds()
{
// Stop all sounds first
stop_all_sounds();
// Free/unload all sound effects by getting the sound_effect pointer first
if (has_sound_effect(GHOST_CHASE_SOUND_NAME))
free_sound_effect(sound_effect_named(GHOST_CHASE_SOUND_NAME));
if (has_sound_effect(GHOST_CHASE_SOUND2_NAME))
free_sound_effect(sound_effect_named(GHOST_CHASE_SOUND2_NAME));
if (has_sound_effect(GHOST_CHASE_SOUND3_NAME))
free_sound_effect(sound_effect_named(GHOST_CHASE_SOUND3_NAME));
if (has_sound_effect(GHOST_CHASE_SOUND4_NAME))
free_sound_effect(sound_effect_named(GHOST_CHASE_SOUND4_NAME));
if (has_sound_effect(GHOST_CHASE_SOUND5_NAME))
free_sound_effect(sound_effect_named(GHOST_CHASE_SOUND5_NAME));
if (has_sound_effect(DOT1_SOUND_NAME))
free_sound_effect(sound_effect_named(DOT1_SOUND_NAME));
if (has_sound_effect(DOT2_SOUND_NAME))
free_sound_effect(sound_effect_named(DOT2_SOUND_NAME));
if (has_sound_effect(GHOST_BLUE_SOUND_NAME))
free_sound_effect(sound_effect_named(GHOST_BLUE_SOUND_NAME));
if (has_sound_effect(GHOST_EAT_SOUND_NAME))
free_sound_effect(sound_effect_named(GHOST_EAT_SOUND_NAME));
if (has_sound_effect(GHOST_RETREAT_SOUND_NAME))
free_sound_effect(sound_effect_named(GHOST_RETREAT_SOUND_NAME));
if (has_sound_effect(START_SOUND_NAME))
free_sound_effect(sound_effect_named(START_SOUND_NAME));
if (has_sound_effect(DIE_SOUND_NAME))
free_sound_effect(sound_effect_named(DIE_SOUND_NAME));
if (has_sound_effect(CUTSCENE_SOUND_NAME))
free_sound_effect(sound_effect_named(CUTSCENE_SOUND_NAME));
}