1
+ import pygame
2
+ import queue
3
+ import threading
4
+ from eegRead import eeg_data_thread
5
+
6
+ pygame .init () # Initialize Pygame
7
+ pygame .mixer .init () # Initialize Pygame Mixer for sound
8
+
9
+ # Screen dimensions
10
+ WIDTH , HEIGHT = 1000 , 800
11
+ screen = pygame .display .set_mode ((WIDTH , HEIGHT ), pygame .FULLSCREEN ) # Fullscreen mode
12
+ pygame .display .set_caption ("Force Ball Game" )
13
+
14
+ # Colors
15
+ WHITE = (255 , 255 , 255 )
16
+ BLACK = (0 , 0 , 0 )
17
+ RED = (255 , 0 , 0 )
18
+ BLUE = (0 , 0 , 255 )
19
+ GREEN = (0 , 255 , 0 )
20
+ YELLOW = (255 , 255 , 0 )
21
+
22
+ # Fonts
23
+ font = pygame .font .SysFont ('Arial' , 36 , bold = True )
24
+ title_font = pygame .font .SysFont ('Arial' , 72 , bold = True )
25
+
26
+ # Load win sound effect
27
+ win_sound = pygame .mixer .Sound ("C:\\ Users\\ PAYAL\\ Braingame\\ brass-fanfare-with-timpani-and-winchimes-reverberated-146260.wav" )
28
+
29
+ # Ball properties
30
+ ball_radius = 20
31
+ ball_pos = [WIDTH // 2 , HEIGHT // 2 ]
32
+ ball_color = WHITE
33
+ ball_speed = 40
34
+
35
+ # Player properties
36
+ player_width = 10
37
+ player_height = 100
38
+ player1_pos = [50 , HEIGHT // 2 - player_height // 2 ]
39
+ player2_pos = [WIDTH - 50 - player_width , HEIGHT // 2 - player_height // 2 ]
40
+
41
+ clock = pygame .time .Clock ()
42
+
43
+ # Initialize EEG queue
44
+ eeg_queue = queue .Queue ()
45
+ eeg_thread = threading .Thread (target = eeg_data_thread , args = (eeg_queue ,))
46
+ eeg_thread .daemon = True
47
+ eeg_thread .start ()
48
+
49
+ def reset_game ():
50
+ global ball_pos , force_player1 , force_player2
51
+ ball_pos = [WIDTH // 2 , HEIGHT // 2 ]
52
+ force_player1 = 0
53
+ force_player2 = 0
54
+
55
+ # Clear any buffered EEG data
56
+ while not eeg_queue .empty ():
57
+ eeg_queue .get ()
58
+
59
+ def update_ball_position (force_player1 , force_player2 ):
60
+ global ball_pos
61
+ net_force = force_player2 - force_player1 # Correct force direction
62
+ print (force_player2 , force_player1 )
63
+ ball_pos [0 ] += net_force * ball_speed * 0.01
64
+ if ball_pos [0 ] < ball_radius :
65
+ ball_pos [0 ] = ball_radius
66
+ elif ball_pos [0 ] > WIDTH - ball_radius :
67
+ ball_pos [0 ] = WIDTH - ball_radius
68
+
69
+ def handle_input ():
70
+ global force_player1 , force_player2
71
+ keys = pygame .key .get_pressed ()
72
+
73
+ if keys [pygame .K_LEFT ]:
74
+ force_player1 += 0.25
75
+ elif keys [pygame .K_RIGHT ]:
76
+ force_player1 -= 0.25
77
+
78
+ def draw_buttons (paused , first_attempt ): # Button dimensions and positions
79
+ button_width = 120
80
+ button_height = 40
81
+ button_radius = 15 # Radius for rounded corners
82
+
83
+ # Button positions (y-position is moved up slightly for a better fit)
84
+ start_button_rect = pygame .Rect (WIDTH // 4 - button_width // 2 , HEIGHT - 80 , button_width , button_height )
85
+ resume_pause_button_rect = pygame .Rect (WIDTH // 2 - button_width // 2 , HEIGHT - 80 , button_width , button_height )
86
+ exit_button_rect = pygame .Rect (3 * WIDTH // 4 - button_width // 2 , HEIGHT - 80 , button_width , button_height )
87
+
88
+ # Draw buttons
89
+ pygame .draw .rect (screen , GREEN , start_button_rect , border_radius = button_radius ) # Start/Restart Button
90
+ pygame .draw .rect (screen , YELLOW , resume_pause_button_rect , border_radius = button_radius ) # Resume/Pause Button
91
+ pygame .draw .rect (screen , RED , exit_button_rect , border_radius = button_radius ) # Exit Button
92
+
93
+ # Button Texts
94
+ start_text = font .render ("Restart" if not first_attempt else "Start" , True , BLACK )
95
+ resume_pause_text = font .render ("Resume" if paused else "Pause" , True , BLACK )
96
+ exit_text = font .render ("Exit" , True , BLACK )
97
+
98
+ # Calculate text positions for proper centering inside each button
99
+ start_text_pos = (start_button_rect .x + (button_width - start_text .get_width ()) // 2 ,
100
+ start_button_rect .y + (button_height - start_text .get_height ()) // 2 )
101
+
102
+ resume_pause_text_pos = (resume_pause_button_rect .x + (button_width - resume_pause_text .get_width ()) // 2 ,
103
+ resume_pause_button_rect .y + (button_height - resume_pause_text .get_height ()) // 2 )
104
+
105
+ exit_text_pos = (exit_button_rect .x + (button_width - exit_text .get_width ()) // 2 ,
106
+ exit_button_rect .y + (button_height - exit_text .get_height ()) // 2 )
107
+
108
+ # Render the text on the buttons
109
+ screen .blit (start_text , start_text_pos )
110
+ screen .blit (resume_pause_text , resume_pause_text_pos )
111
+ screen .blit (exit_text , exit_text_pos )
112
+
113
+ def check_win_condition ():
114
+ if ball_pos [0 ] <= ball_radius :
115
+ return "PLAYER-A WINS!"
116
+ elif ball_pos [0 ] >= WIDTH - ball_radius :
117
+ return "PLAYER-B WINS!"
118
+ return None
119
+
120
+ def draw_countdown (count ):
121
+ # Create a circular box for the countdown
122
+ countdown_radius = 100 # Radius for the circular box
123
+ countdown_center = (WIDTH // 2 , HEIGHT // 2 ) # Center position for the circle
124
+
125
+ # Draw the circular background
126
+ pygame .draw .circle (screen , BLACK , countdown_center , countdown_radius )
127
+ pygame .draw .circle (screen , WHITE , countdown_center , countdown_radius - 5 ) # Inner white circle for contrast
128
+
129
+ # Set the font size for the countdown number
130
+ countdown_font = pygame .font .SysFont ('Arial' , 96 , bold = True ) # Larger font for the countdown number
131
+ countdown_text = countdown_font .render (str (count ), True , RED ) # Countdown number in red
132
+
133
+ # Center the countdown text in the circular box
134
+ countdown_text_pos = (countdown_center [0 ] - countdown_text .get_width () // 2 ,
135
+ countdown_center [1 ] - countdown_text .get_height () // 2 )
136
+
137
+ # Render the countdown number on the screen
138
+ screen .blit (countdown_text , countdown_text_pos )
139
+
140
+ def draw ():
141
+ screen .fill (BLACK )
142
+
143
+ pygame .draw .rect (screen , RED , (* player1_pos , player_width , player_height )) # Draw Players
144
+ pygame .draw .rect (screen , BLUE , (* player2_pos , player_width , player_height ))
145
+
146
+ pygame .draw .circle (screen , ball_color , (int (ball_pos [0 ]), int (ball_pos [1 ])), ball_radius ) # Draw ball
147
+
148
+ title_text = title_font .render ("Force Ball Game" , True , WHITE ) # Draw game title at the top middle
149
+ screen .blit (title_text , (WIDTH // 2 - title_text .get_width () // 2 , 20 ))
150
+
151
+ player_a_text = font .render ("A" , True , WHITE ) # Draw player names next to their respective lines
152
+ player_b_text = font .render ("B" , True , WHITE )
153
+ screen .blit (player_a_text , (player1_pos [0 ] - player_a_text .get_width () - 20 , HEIGHT // 2 - player_a_text .get_height () // 2 ))
154
+ screen .blit (player_b_text , (player2_pos [0 ] + player_width + 20 , HEIGHT // 2 - player_b_text .get_height () // 2 ))
155
+
156
+ draw_buttons (paused , first_attempt ) # Draw buttons
157
+
158
+ pygame .display .flip ()
159
+
160
+ # Initial forces
161
+ force_player1 = 0
162
+ force_player2 = 0
163
+ game_started = False
164
+ paused = False
165
+ game_running = True
166
+ game_won = False
167
+ first_attempt = True # Keeps track if it's the first game or a restart
168
+
169
+ while game_running :
170
+ for event in pygame .event .get ():
171
+ if event .type == pygame .QUIT :
172
+ game_running = False # Stops the game but keeps the app running
173
+ elif event .type == pygame .MOUSEBUTTONDOWN :
174
+ mouse_pos = pygame .mouse .get_pos ()
175
+ # Check button clicks
176
+ if WIDTH // 4 - 75 <= mouse_pos [0 ] <= WIDTH // 4 + 75 and HEIGHT - 100 <= mouse_pos [1 ] <= HEIGHT - 50 :
177
+ print ("Start/Restart Button Clicked" )
178
+ game_started = True
179
+ paused = False
180
+ game_won = False
181
+ first_attempt = False # After first click, button becomes "Restart"
182
+ reset_game () # Reset the game state when start/restart is clicked
183
+ elif WIDTH // 2 - 75 <= mouse_pos [0 ] <= WIDTH // 2 + 75 and HEIGHT - 100 <= mouse_pos [1 ] <= HEIGHT - 50 :
184
+ print ("Resume/Pause Button Clicked" )
185
+ if game_started :
186
+ paused = not paused # Toggle pause/resume
187
+ elif 3 * WIDTH // 4 - 75 <= mouse_pos [0 ] <= 3 * WIDTH // 4 + 75 and HEIGHT - 100 <= mouse_pos [1 ] <= HEIGHT - 50 :
188
+ print ("Exit Button Clicked" )
189
+ game_running = False # Stop the game and return to main GUI
190
+
191
+ if game_started and not paused :
192
+ handle_input ()
193
+
194
+ if not eeg_queue .empty (): # Update forces from EEG data
195
+ force_player1 , force_player2 = eeg_queue .get ()
196
+ update_ball_position (force_player1 , force_player2 )
197
+
198
+ winner = check_win_condition () # Check for win condition
199
+ if winner :
200
+ winner_text = title_font .render (winner , True , WHITE )
201
+ screen .blit (winner_text , (WIDTH // 2 - winner_text .get_width () // 2 , HEIGHT // 2 - winner_text .get_height () // 2 ))
202
+ pygame .display .flip ()
203
+ pygame .time .wait (1000 ) # Wait for 1 second before starting countdown
204
+ win_sound .play () # Play win sound
205
+
206
+ for count in range (3 , 0 , - 1 ): # Countdown from 3 to 1
207
+ draw ()
208
+ draw_countdown (count ) # Call to draw the countdown
209
+ pygame .display .flip ()
210
+ pygame .time .wait (1000 ) # Wait for 1 second between counts
211
+
212
+ reset_game () # Reset game state
213
+
214
+ # Automatically start the game after countdown ends
215
+ game_started = True # Set game started to True after countdown
216
+
217
+ draw ()
218
+ clock .tick (60 ) # 60 frames per second
219
+
220
+ pygame .quit () # Quit Pygame when the main loop ends.
0 commit comments