@@ -82,15 +82,20 @@ def handle_spacebar(self):
8282 if self .game_state == "IDLE" :
8383 self .countdown ()
8484 self .game_state = "PLAYING"
85+ # Schedule the first tick after spacebar is pressed
86+ self .screen .ontimer (self .tick , int (self .delay * 1000 ))
8587
8688 elif self .game_state == "PLAYING" :
8789 self .game_state = "PAUSED"
8890 self .game_text .clear ()
8991 self .game_text .write ("PAUSED" , align = "center" , font = ("Arial" , 24 , "bold" ))
92+ # Don't schedule next tick; game is paused
9093
9194 elif self .game_state == "PAUSED" :
9295 self .game_state = "PLAYING"
9396 self .game_text .clear ()
97+ # Resume ticking when unpaused
98+ self .screen .ontimer (self .tick , int (self .delay * 1000 ))
9499
95100 elif self .game_state == "GAME_OVER" :
96101 self .snake .reset ()
@@ -99,54 +104,62 @@ def handle_spacebar(self):
99104 self .level = 1
100105 self .countdown ()
101106 self .game_state = "PLAYING"
107+ # Schedule the first tick after restart
108+ self .screen .ontimer (self .tick , int (self .delay * 1000 ))
109+
110+ def tick (self ):
111+ """Single game tick - called via ontimer() to avoid busy-waiting."""
112+ # Only process game logic if game is actively playing
113+ if self .game_state != "PLAYING" :
114+ return
115+
116+ self .screen .update ()
117+
118+ # Boundary collision
119+ if self .snake .check_boundary_collision ():
120+ if self .pygame_installed :
121+ self .gameover_sound .play ()
122+ self .game_text .write ("GAME OVER - Press SPACE to Restart" , align = "center" , font = ("Arial" , 20 , "bold" ))
123+ self .game_state = "GAME_OVER"
124+ return
125+
126+ # Food collision
127+ if self .snake .head .distance (self .food .item ) < COLLISION_DISTANCE :
128+ self .food .reposition (self .snake )
129+ self .snake .add_part ()
130+ self .scoreboard .increase ()
131+ if self .pygame_installed :
132+ self .eat_sound .play ()
133+
134+ if self .scoreboard .score % 5 == 0 :
135+ self .level += 1
136+ self .delay -= 0.01
137+ self .game_text .clear ()
138+ self .game_text .write (f"LEVEL { self .level } " , align = "center" , font = ("Arial" , 24 , "bold" ))
139+ self .screen .update ()
140+ time .sleep (0.5 )
141+ self .game_text .clear ()
142+
143+ # Move snake
144+ self .snake .move ()
145+
146+ # Self collision
147+ if self .snake .check_self_collision ():
148+ if self .pygame_installed :
149+ self .gameover_sound .play ()
150+ self .game_text .write ("GAME OVER - Press SPACE to Restart" , align = "center" , font = ("Arial" , 20 , "bold" ))
151+ self .game_state = "GAME_OVER"
152+ return
153+
154+ # Schedule next tick
155+ self .screen .ontimer (self .tick , int (self .delay * 1000 ))
102156
103157 def run (self ):
158+ """Main entry point - display startup message and enter event loop."""
104159 self .game_text .write ("Press SPACEBAR to Start" , align = "center" , font = ("Arial" , 24 , "bold" ))
105-
106- while True :
107- self .screen .update ()
108-
109- if self .game_state in ["IDLE" , "PAUSED" , "GAME_OVER" ]:
110- time .sleep (0.1 )
111- continue
112-
113- # Boundary collision
114- if self .snake .check_boundary_collision ():
115- if self .pygame_installed :
116- self .gameover_sound .play ()
117- self .game_text .write ("GAME OVER - Press SPACE to Restart" , align = "center" , font = ("Arial" , 20 , "bold" ))
118- self .game_state = "GAME_OVER"
119- continue
120-
121- # Food collision
122- if self .snake .head .distance (self .food .item ) < COLLISION_DISTANCE :
123- self .food .reposition (self .snake )
124- self .snake .add_part ()
125- self .scoreboard .increase ()
126- if self .pygame_installed :
127- self .eat_sound .play ()
128-
129- if self .scoreboard .score % 5 == 0 :
130- self .level += 1
131- self .delay -= 0.01
132- self .game_text .clear ()
133- self .game_text .write (f"LEVEL { self .level } " , align = "center" , font = ("Arial" , 24 , "bold" ))
134- self .screen .update ()
135- time .sleep (0.5 )
136- self .game_text .clear ()
137-
138- # Move snake
139- self .snake .move ()
140-
141- # Self collision
142- if self .snake .check_self_collision ():
143- if self .pygame_installed :
144- self .gameover_sound .play ()
145- self .game_text .write ("GAME OVER - Press SPACE to Restart" , align = "center" , font = ("Arial" , 20 , "bold" ))
146- self .game_state = "GAME_OVER"
147- continue
148-
149- time .sleep (self .delay )
160+ self .screen .update ()
161+ # Turtle event loop keeps ontimer() callbacks running
162+ self .screen .mainloop ()
150163
151164
152165if __name__ == "__main__" :
0 commit comments