1
+ import pygame
2
+ import pylsl
3
+ import numpy as np
4
+ import time
5
+ from pylsl import StreamInlet , resolve_stream
6
+
7
+ pygame .init ()
8
+
9
+ # Screen setup
10
+ screen = pygame .display .set_mode ((800 , 600 ))
11
+ pygame .display .set_caption ('Focus Game' )
12
+
13
+ # Ball properties
14
+ ball_x , ball_y = 400 , 550
15
+ ball_radius = 20
16
+ focus_speed_upward = 8 # Speed when moving upward
17
+ focus_speed_downward = 4 # Speed when moving downward
18
+ focus_timeout = 2 # Time in seconds to stabilize focus
19
+ focus_threshold = 1000000000 # Threshold for beta power
20
+
21
+ # LSL stream setup
22
+ streams = resolve_stream ('name' , 'BioAmpDataStream' )
23
+ if not streams :
24
+ print ("No LSL stream found!" )
25
+ pygame .quit ()
26
+ exit ()
27
+
28
+ inlet = StreamInlet (streams [0 ])
29
+ print (" LSL Stream Started" )
30
+
31
+ # Buffer for EEG data and Focus tracking variables
32
+ buffer = []
33
+ buffer_size = 500
34
+ focus_timer = 0
35
+ last_focus_time = time .time ()
36
+ last_time = time .time ()
37
+
38
+ def calculate_focus_level (eeg_data ):
39
+ fft_result = np .fft .fft (eeg_data )
40
+ freqs = np .fft .fftfreq (len (eeg_data ), 1 / 500 )
41
+ positive_freqs = freqs [:len (freqs ) // 2 ]
42
+ fft_magnitude = np .abs (fft_result [:len (freqs ) // 2 ])
43
+
44
+ # Extract beta band power (13-30 Hz)
45
+ beta_band = np .where ((positive_freqs >= 13 ) & (positive_freqs <= 30 ))
46
+ beta_power = np .sum (fft_magnitude [beta_band ] ** 2 )
47
+ print (f"Beta Power: { beta_power } " )
48
+
49
+ return beta_power
50
+
51
+ def update_ball_position (focus_level , is_focus_stable ):
52
+ global ball_y
53
+ if is_focus_stable :
54
+ ball_y = max (0 , ball_y - focus_speed_upward ) # Move upward, bounded by top
55
+ else :
56
+ ball_y = min (600 - ball_radius , ball_y + focus_speed_downward ) # Move downward, bounded by bottom
57
+
58
+ # Game loop
59
+ running = True
60
+ while running :
61
+ try :
62
+ for event in pygame .event .get ():
63
+ if event .type == pygame .QUIT :
64
+ running = False
65
+
66
+ # Read EEG data from the LSL stream
67
+ sample , _ = inlet .pull_sample (timeout = 0.1 )
68
+ if sample :
69
+ buffer .append (sample [:1 ]) # Append new data to buffer
70
+
71
+ current_time = time .time ()
72
+ if current_time - last_time >= 1 :
73
+ last_time = current_time
74
+ release_count = int (len (buffer ) * 0.2 ) # Remove oldest 20%
75
+ buffer = buffer [release_count :] # Trim buffer
76
+
77
+ if len (buffer ) >= buffer_size : # Process EEG data when the buffer is full
78
+ eeg_data = np .array (buffer )[:, 0 ] # Use only the first channel
79
+ buffer = [] # Clear the buffer
80
+
81
+ focus_level = calculate_focus_level (eeg_data )
82
+
83
+ if focus_level > focus_threshold :
84
+ focus_timer = min (focus_timeout , focus_timer + (current_time - last_focus_time ))
85
+ else :
86
+ focus_timer = max (0 , focus_timer - (current_time - last_focus_time ))
87
+
88
+ is_focus_stable = focus_timer >= focus_timeout
89
+ update_ball_position (focus_level , is_focus_stable )
90
+ last_focus_time = current_time
91
+
92
+ screen .fill ((0 , 0 , 0 ))
93
+ pygame .draw .circle (screen , (255 , 0 , 0 ), (ball_x , ball_y ), ball_radius ) # Draw the ball
94
+ pygame .display .update ()
95
+
96
+ except KeyboardInterrupt :
97
+ print ("Exiting gracefully..." )
98
+ running = False
99
+
100
+ pygame .quit ()
0 commit comments