Skip to content

Commit eb8ba61

Browse files
committed
beetle game- requires testing
1 parent 2ede52f commit eb8ba61

File tree

3 files changed

+131
-100
lines changed

3 files changed

+131
-100
lines changed

test/ball.py

Lines changed: 0 additions & 100 deletions
This file was deleted.

test/beetle.jpg

6.34 KB
Loading

test/beetle.py

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import pygame
2+
import pylsl
3+
import numpy as np
4+
import time
5+
from pylsl import StreamInlet, resolve_stream
6+
from scipy.signal import iirnotch, butter, lfilter
7+
import math
8+
9+
pygame.init()
10+
11+
# Screen setup
12+
screen = pygame.display.set_mode((800, 600))
13+
pygame.display.set_caption('Beetle Game')
14+
15+
# Beetle properties
16+
beetle_x, beetle_y = 380, 530
17+
focus_speed_upward = 8 # Speed when moving upward
18+
focus_speed_downward = 4 # Speed when moving downward
19+
focus_timeout = 2 # Time in seconds to stabilize focus
20+
focus_threshold = 5 # Threshold for beta power
21+
22+
# LSL stream setup
23+
streams = resolve_stream('name', 'BioAmpDataStream')
24+
if not streams:
25+
print("No LSL stream found!")
26+
pygame.quit()
27+
exit()
28+
29+
inlet = StreamInlet(streams[0])
30+
print("LSL Stream Started")
31+
sampling_rate = int(inlet.info().nominal_srate())
32+
print(f"Sampling rate: {sampling_rate} Hz")
33+
34+
b_notch, a_notch = iirnotch(50.0 / (500 / 2), 30.0)
35+
b_band, a_band = butter(4, [0.5/ (sampling_rate / 2), 48.0 / (sampling_rate / 2)], btype='band')
36+
37+
# Buffer for EEG data and Focus tracking variables
38+
buffer = []
39+
buffer_size = 500
40+
focus_timer = 0
41+
last_focus_time = time.time()
42+
last_time = time.time()
43+
44+
# Load the beetle image
45+
beetle_image = pygame.image.load('beetle.jpg')
46+
beetle_image = pygame.transform.scale(beetle_image, (80, 80))
47+
48+
# Function to apply filters
49+
def apply_filters(eeg_point):
50+
filtered = lfilter(b_notch, a_notch, [eeg_point])
51+
filtered_point = lfilter(b_band, a_band, filtered)
52+
return filtered_point[0]
53+
54+
def calculate_focus_level(eeg_data, sampling_rate=500):
55+
window = np.hanning(len(eeg_data)) # Apply a Hanning window
56+
eeg_data_windowed = eeg_data * window
57+
fft_data = np.abs(np.fft.fft(eeg_data_windowed))[:len(eeg_data_windowed) // 2]
58+
fft_data /= len(eeg_data_windowed)
59+
freqs = np.fft.fftfreq(len(eeg_data_windowed), d=1 / sampling_rate)[:len(eeg_data_windowed) // 2]
60+
61+
# Compute power in different bands
62+
delta_power = math.sqrt(np.sum((fft_data[(freqs >= 0.5) & (freqs <= 4)]) ** 2))
63+
theta_power = math.sqrt(np.sum((fft_data[(freqs >= 4) & (freqs <= 8)]) ** 2))
64+
alpha_power = math.sqrt(np.sum((fft_data[(freqs >= 8) & (freqs <= 13)]) ** 2))
65+
beta_power = math.sqrt(np.sum((fft_data[(freqs >= 13) & (freqs <= 30)]) ** 2))
66+
gamma_power = math.sqrt(np.sum((fft_data[(freqs >= 30) & (freqs <= 45)]) ** 2))
67+
68+
power = (beta_power + gamma_power) / (theta_power + alpha_power)
69+
print(power)
70+
return power
71+
72+
def update_beetle_position(focus_level, is_focus_stable):
73+
global beetle_y
74+
if is_focus_stable:
75+
beetle_y = max(10 + beetle_image.get_height() // 2, beetle_y - focus_speed_upward) # Prevent moving above border
76+
else:
77+
beetle_y = min(580 - beetle_image.get_height() // 2, beetle_y + focus_speed_downward) # Prevent moving below border
78+
79+
# Game loop
80+
running = True
81+
while running:
82+
try:
83+
for event in pygame.event.get():
84+
if event.type == pygame.QUIT:
85+
running = False
86+
87+
# Read EEG data from the LSL stream
88+
sample, _ = inlet.pull_sample(timeout=0.1)
89+
if sample:
90+
filtered_sample = apply_filters(sample[0])
91+
buffer.append(filtered_sample)
92+
93+
current_time = time.time()
94+
if current_time - last_time >= 1:
95+
last_time = current_time
96+
release_count = int(len(buffer) * 0.2) # Remove oldest 20%
97+
buffer = buffer[release_count:] # Trim buffer
98+
99+
if len(buffer) >= buffer_size: # Process EEG data when the buffer is full
100+
eeg_data = np.array(buffer) # Use filtered data
101+
buffer = [] # Clear the buffer
102+
103+
focus_level = calculate_focus_level(eeg_data)
104+
105+
if focus_level > focus_threshold:
106+
focus_timer = min(focus_timeout, focus_timer + (current_time - last_focus_time))
107+
is_focus_stable = focus_timer >= focus_timeout
108+
update_beetle_position(focus_level, is_focus_stable)
109+
110+
elif 7 <= focus_level <= 8: # No movement of the beetle
111+
print("Beetle remains stationary.")
112+
113+
else:
114+
focus_timer = max(0, focus_timer - (current_time - last_focus_time))
115+
is_focus_stable = focus_timer >= focus_timeout
116+
update_beetle_position(focus_level, is_focus_stable)
117+
118+
last_focus_time = current_time
119+
120+
# Clear the screen and draw the beetle
121+
screen.fill("#FFFFFF")
122+
pygame.draw.rect(screen, (0, 0, 0), (10, 10, 780, 580), 5) # Draw border
123+
screen.blit(beetle_image, (beetle_x - beetle_image.get_width() // 2, beetle_y - beetle_image.get_height() // 2))
124+
125+
pygame.display.update()
126+
127+
except KeyboardInterrupt:
128+
print("Exiting gracefully...")
129+
running = False
130+
131+
pygame.quit()

0 commit comments

Comments
 (0)