dvc890 commited on
Commit
facad23
·
verified ·
1 Parent(s): 9525472

Update pages/GameZen.tsx

Browse files
Files changed (1) hide show
  1. pages/GameZen.tsx +22 -7
pages/GameZen.tsx CHANGED
@@ -13,7 +13,7 @@ export const GameZen: React.FC = () => {
13
  const [isPlaying, setIsPlaying] = useState(false);
14
  const [gameState, setGameState] = useState<'IDLE' | 'PLAYING' | 'FINISHED'>('IDLE');
15
  const [timeLeft, setTimeLeft] = useState(2400); // Seconds
16
- const [currentVolume, setCurrentVolume] = useState(0);
17
  const [isFullscreen, setIsFullscreen] = useState(false);
18
 
19
  // Game Logic State
@@ -50,6 +50,9 @@ export const GameZen: React.FC = () => {
50
  const sourceRef = useRef<MediaStreamAudioSourceNode | null>(null);
51
  const reqRef = useRef<number>(0);
52
 
 
 
 
53
  // Sync Refs
54
  useEffect(() => { isPlayingRef.current = isPlaying; }, [isPlaying]);
55
  useEffect(() => { gameStateRef.current = gameState; }, [gameState]);
@@ -139,6 +142,7 @@ export const GameZen: React.FC = () => {
139
  setQuietSeconds(0);
140
  setTotalSeconds(0);
141
  setScore(100);
 
142
 
143
  await startAudio();
144
  setIsPlaying(true);
@@ -170,14 +174,25 @@ export const GameZen: React.FC = () => {
170
  if (analyserRef.current && dataArrayRef.current) {
171
  analyserRef.current.getByteFrequencyData(dataArrayRef.current as any);
172
  const avg = dataArrayRef.current.reduce((a,b)=>a+b) / dataArrayRef.current.length;
173
- const vol = Math.min(100, Math.floor(avg / 2));
174
- setCurrentVolume(vol);
175
-
176
- // Game Logic
 
 
 
 
 
 
 
 
 
 
 
177
  if (delta > 0) {
178
  setTotalSeconds(prev => prev + delta);
179
  // Count as quiet only if below threshold (Levels 1 & 2)
180
- if (vol < threshold) {
181
  setQuietSeconds(prev => prev + delta);
182
  }
183
  }
@@ -196,7 +211,7 @@ export const GameZen: React.FC = () => {
196
  // Score Calculation
197
  const calculatedScore = totalSeconds > 0 ? Math.round((quietSeconds / totalSeconds) * 100) : 100;
198
 
199
- // Determine Current State (4 Levels)
200
  const getZenState = () => {
201
  if (currentVolume < threshold * 0.5) return 'DEEP';
202
  if (currentVolume < threshold) return 'FOCUSED';
 
13
  const [isPlaying, setIsPlaying] = useState(false);
14
  const [gameState, setGameState] = useState<'IDLE' | 'PLAYING' | 'FINISHED'>('IDLE');
15
  const [timeLeft, setTimeLeft] = useState(2400); // Seconds
16
+ const [currentVolume, setCurrentVolume] = useState(0); // This is now the SMOOTHED volume
17
  const [isFullscreen, setIsFullscreen] = useState(false);
18
 
19
  // Game Logic State
 
50
  const sourceRef = useRef<MediaStreamAudioSourceNode | null>(null);
51
  const reqRef = useRef<number>(0);
52
 
53
+ // Logic Refs for Smoothing
54
+ const smoothedVolRef = useRef(0);
55
+
56
  // Sync Refs
57
  useEffect(() => { isPlayingRef.current = isPlaying; }, [isPlaying]);
58
  useEffect(() => { gameStateRef.current = gameState; }, [gameState]);
 
142
  setQuietSeconds(0);
143
  setTotalSeconds(0);
144
  setScore(100);
145
+ smoothedVolRef.current = 0; // Reset smooth vol
146
 
147
  await startAudio();
148
  setIsPlaying(true);
 
174
  if (analyserRef.current && dataArrayRef.current) {
175
  analyserRef.current.getByteFrequencyData(dataArrayRef.current as any);
176
  const avg = dataArrayRef.current.reduce((a,b)=>a+b) / dataArrayRef.current.length;
177
+ const rawVol = Math.min(100, Math.floor(avg / 2));
178
+
179
+ // --- SMOOTHING ALGORITHM (Fast Attack, Slow Decay) ---
180
+ // If getting louder, react fast (0.2). If getting quieter, react slow (0.05).
181
+ // This prevents flickering at the threshold.
182
+ const smoothingFactor = rawVol > smoothedVolRef.current ? 0.2 : 0.05;
183
+ smoothedVolRef.current = smoothedVolRef.current + (rawVol - smoothedVolRef.current) * smoothingFactor;
184
+
185
+ // Ensure strictly non-negative
186
+ if (smoothedVolRef.current < 0) smoothedVolRef.current = 0;
187
+
188
+ const displayVol = Math.round(smoothedVolRef.current);
189
+ setCurrentVolume(displayVol);
190
+
191
+ // Game Logic uses SMOOTHED volume for stability
192
  if (delta > 0) {
193
  setTotalSeconds(prev => prev + delta);
194
  // Count as quiet only if below threshold (Levels 1 & 2)
195
+ if (displayVol < threshold) {
196
  setQuietSeconds(prev => prev + delta);
197
  }
198
  }
 
211
  // Score Calculation
212
  const calculatedScore = totalSeconds > 0 ? Math.round((quietSeconds / totalSeconds) * 100) : 100;
213
 
214
+ // Determine Current State (4 Levels) based on SMOOTHED volume
215
  const getZenState = () => {
216
  if (currentVolume < threshold * 0.5) return 'DEEP';
217
  if (currentVolume < threshold) return 'FOCUSED';