Whenever you use while True: (sans break) in turtle code, you're defeating the event hander. You should instead use an ontimer() event to run your code compatibly with the event handler. Below is my rewrite of your code to do this along with some other functional and style tweaks:

from turtle import Turtle, Screen
import random
import time

SIZE = 20

class Square:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def drawself(self, turtle):
        """ draw a black box at its coordinates, leaving a small gap between cubes """

        turtle.goto(self.x - SIZE // 2 - 1, self.y - SIZE // 2 - 1)

        turtle.begin_fill()
        for _ in range(4):
            turtle.forward(SIZE - SIZE // 10)
            turtle.left(90)
        turtle.end_fill()

class Food:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.is_blinking = True

    def changelocation(self):
        # I haven't programmed it to spawn outside the snake's body yet
        self.x = random.randint(0, SIZE) * SIZE - 200
        self.y = random.randint(0, SIZE) * SIZE - 200

    def drawself(self, turtle):
        # similar to the Square drawself, but blinks on and off
        if self.is_blinking:
            turtle.goto(self.x - SIZE // 2 - 1, self.y - SIZE // 2 - 1)
            turtle.begin_fill()
            for _ in range(4):
                turtle.forward(SIZE - SIZE // 10)
                turtle.left(90)
            turtle.end_fill()

    def changestate(self):
        # controls the blinking
        self.is_blinking = not self.is_blinking

class Snake:
    def __init__(self):
        self.headposition = [SIZE, 0]  # keeps track of where it needs to go next
        self.body = [Square(-SIZE, 0), Square(0, 0), Square(SIZE, 0)]  # body is a list of squares
        self.nextX = 1  # tells the snake which way it's going next
        self.nextY = 0
        self.crashed = False  # I'll use this when I get around to collision detection
        self.nextposition = [self.headposition[0] + SIZE * self.nextX, self.headposition[1] + SIZE * self.nextY]
        # prepares the next location to add to the snake

    def moveOneStep(self):
        if Square(self.nextposition[0], self.nextposition[1]) not in self.body: 
            # attempt (unsuccessful) at collision detection
            self.body.append(Square(self.nextposition[0], self.nextposition[1])) 
            # moves the snake head to the next spot, deleting the tail
            del self.body[0]
            self.headposition[0], self.headposition[1] = self.body[-1].x, self.body[-1].y 
            # resets the head and nextposition
            self.nextposition = [self.headposition[0] + SIZE * self.nextX, self.headposition[1] + SIZE * self.nextY]
        else:
            self.crashed = True  # more unsuccessful collision detection

    def moveup(self):  # pretty obvious what these do
        self.nextX, self.nextY = 0, 1

    def moveleft(self):
        self.nextX, self.nextY = -1, 0

    def moveright(self):
        self.nextX, self.nextY = 1, 0

    def movedown(self):
        self.nextX, self.nextY = 0, -1

    def eatFood(self):
        # adds the next spot without deleting the tail, extending the snake by 1
        self.body.append(Square(self.nextposition[0], self.nextposition[1]))
        self.headposition[0], self.headposition[1] = self.body[-1].x, self.body[-1].y
        self.nextposition = [self.headposition[0] + SIZE * self.nextX, self.headposition[1] + SIZE * self.nextY]

    def drawself(self, turtle):  # draws the whole snake when called
        for segment in self.body:
            segment.drawself(turtle)

class Game:
    def __init__(self):
        # game object has a screen, a turtle, a basic snake and a food
        self.screen = Screen()
        self.artist = Turtle(visible=False)
        self.artist.up()
        self.artist.speed("slowest")

        self.snake = Snake()
        self.food = Food(100, 0)
        self.counter = 0  # this will be used later
        self.commandpending = False  # as will this

        self.screen.tracer(0)  # follow it so far?

        self.screen.listen()
        self.screen.onkey(self.snakedown, "Down")
        self.screen.onkey(self.snakeup, "Up")
        self.screen.onkey(self.snakeleft, "Left")
        self.screen.onkey(self.snakeright, "Right")

    def nextFrame(self):
        self.artist.clear()

        if (self.snake.nextposition[0], self.snake.nextposition[1]) == (self.food.x, self.food.y):
            self.snake.eatFood()
            self.food.changelocation()
        else:
            self.snake.moveOneStep()

        if self.counter == 10:
            self.food.changestate()  # makes the food flash slowly
            self.counter = 0
        else:
            self.counter += 1

        self.food.drawself(self.artist)  # show the food and snake
        self.snake.drawself(self.artist)
        self.screen.update()
        self.screen.ontimer(lambda: self.nextFrame(), 100)

    def snakeup(self):
        if not self.commandpending: 
            self.commandpending = True
            self.snake.moveup()
            self.commandpending = False

    def snakedown(self):
        if not self.commandpending:
            self.commandpending = True
            self.snake.movedown()
            self.commandpending = False

    def snakeleft(self):
        if not self.commandpending:
            self.commandpending = True
            self.snake.moveleft()
            self.commandpending = False

    def snakeright(self):
        if not self.commandpending:
            self.commandpending = True
            self.snake.moveright()
            self.commandpending = False

game = Game()

screen = Screen()

screen.ontimer(lambda: game.nextFrame(), 100)

screen.mainloop()

Does this provide the kind of response for which you're looking?

Answer from cdlane on Stack Overflow
🌐
GitHub
github.com › yash-iiith › Tetris-Game-in-Python-without-Pygame- › blob › master › tetris.py
Tetris-Game-in-Python-without-Pygame-/tetris.py at master · yash-iiith/Tetris-Game-in-Python-without-Pygame-
This is a game of Tetris implemented in Python using OOP concepts which was done in 3rd semester as a part of SSAD course. - Tetris-Game-in-Python-without-Pygame-/tetris.py at master · yash-iiith/Tetris-Game-in-Python-without-Pygame-
Author   yash-iiith
🌐
GitHub
gist.github.com › sanchitgangwar › 2158089
Snakes Game using Python · GitHub
Snakes Game using Python. GitHub Gist: instantly share code, notes, and snippets.
Discussions

Snake game in Python using Turtle graphics - Stack Overflow
So I've been working on a few games in Python (battleships, tic-tac-toe etc.) and this week's project is Snake. I've got a basic set-up going; the snake can move and eats the food but I haven't More on stackoverflow.com
🌐 stackoverflow.com
Can you code a game from scratch in Python without using modules?
There's nothing in the core Python language that will let you create a window on the screen and add graphics to it. You need to interact with your system's windowing system which requires you to at least use some modules from the standard library. I have no idea if that is sufficient though -- there could be some C code that is required to hook into your system's graphics. More on reddit.com
🌐 r/learnpython
12
4
June 25, 2022
Python game design without Pygame - Stack Overflow
This topic is in response to a problem I've been having getting Pygame to be set up correctly on my computer. I have Windows 7, Python 3.3 and "64-bit" Windows (now I know what a bit and a byte ar... More on stackoverflow.com
🌐 stackoverflow.com
Is it possible to make games in Python without Pygame? - Stack Overflow
Is it possible to design a games in python without using an pygame ??? If it is then tell us about an little bit for an start-up..or else if there is any other platform to design a python game gave a More on stackoverflow.com
🌐 stackoverflow.com
🌐
Grant Jenks
grantjenks.com › docs › freegames
Free Python Games — Free Python Games 2.5.3 documentation
$ python3 -m freegames copy snake $ python3 snake.py · Python includes a built-in text editor named IDLE which can also execute Python code.
🌐
GitHub
gist.github.com › wynand1004 › ec105fd2f457b10d971c09586ec44900
A Simple Snake Game made in Python 3 · GitHub
A Simple Snake Game made in Python 3. GitHub Gist: instantly share code, notes, and snippets.
Top answer
1 of 3
7

Whenever you use while True: (sans break) in turtle code, you're defeating the event hander. You should instead use an ontimer() event to run your code compatibly with the event handler. Below is my rewrite of your code to do this along with some other functional and style tweaks:

from turtle import Turtle, Screen
import random
import time

SIZE = 20

class Square:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def drawself(self, turtle):
        """ draw a black box at its coordinates, leaving a small gap between cubes """

        turtle.goto(self.x - SIZE // 2 - 1, self.y - SIZE // 2 - 1)

        turtle.begin_fill()
        for _ in range(4):
            turtle.forward(SIZE - SIZE // 10)
            turtle.left(90)
        turtle.end_fill()

class Food:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.is_blinking = True

    def changelocation(self):
        # I haven't programmed it to spawn outside the snake's body yet
        self.x = random.randint(0, SIZE) * SIZE - 200
        self.y = random.randint(0, SIZE) * SIZE - 200

    def drawself(self, turtle):
        # similar to the Square drawself, but blinks on and off
        if self.is_blinking:
            turtle.goto(self.x - SIZE // 2 - 1, self.y - SIZE // 2 - 1)
            turtle.begin_fill()
            for _ in range(4):
                turtle.forward(SIZE - SIZE // 10)
                turtle.left(90)
            turtle.end_fill()

    def changestate(self):
        # controls the blinking
        self.is_blinking = not self.is_blinking

class Snake:
    def __init__(self):
        self.headposition = [SIZE, 0]  # keeps track of where it needs to go next
        self.body = [Square(-SIZE, 0), Square(0, 0), Square(SIZE, 0)]  # body is a list of squares
        self.nextX = 1  # tells the snake which way it's going next
        self.nextY = 0
        self.crashed = False  # I'll use this when I get around to collision detection
        self.nextposition = [self.headposition[0] + SIZE * self.nextX, self.headposition[1] + SIZE * self.nextY]
        # prepares the next location to add to the snake

    def moveOneStep(self):
        if Square(self.nextposition[0], self.nextposition[1]) not in self.body: 
            # attempt (unsuccessful) at collision detection
            self.body.append(Square(self.nextposition[0], self.nextposition[1])) 
            # moves the snake head to the next spot, deleting the tail
            del self.body[0]
            self.headposition[0], self.headposition[1] = self.body[-1].x, self.body[-1].y 
            # resets the head and nextposition
            self.nextposition = [self.headposition[0] + SIZE * self.nextX, self.headposition[1] + SIZE * self.nextY]
        else:
            self.crashed = True  # more unsuccessful collision detection

    def moveup(self):  # pretty obvious what these do
        self.nextX, self.nextY = 0, 1

    def moveleft(self):
        self.nextX, self.nextY = -1, 0

    def moveright(self):
        self.nextX, self.nextY = 1, 0

    def movedown(self):
        self.nextX, self.nextY = 0, -1

    def eatFood(self):
        # adds the next spot without deleting the tail, extending the snake by 1
        self.body.append(Square(self.nextposition[0], self.nextposition[1]))
        self.headposition[0], self.headposition[1] = self.body[-1].x, self.body[-1].y
        self.nextposition = [self.headposition[0] + SIZE * self.nextX, self.headposition[1] + SIZE * self.nextY]

    def drawself(self, turtle):  # draws the whole snake when called
        for segment in self.body:
            segment.drawself(turtle)

class Game:
    def __init__(self):
        # game object has a screen, a turtle, a basic snake and a food
        self.screen = Screen()
        self.artist = Turtle(visible=False)
        self.artist.up()
        self.artist.speed("slowest")

        self.snake = Snake()
        self.food = Food(100, 0)
        self.counter = 0  # this will be used later
        self.commandpending = False  # as will this

        self.screen.tracer(0)  # follow it so far?

        self.screen.listen()
        self.screen.onkey(self.snakedown, "Down")
        self.screen.onkey(self.snakeup, "Up")
        self.screen.onkey(self.snakeleft, "Left")
        self.screen.onkey(self.snakeright, "Right")

    def nextFrame(self):
        self.artist.clear()

        if (self.snake.nextposition[0], self.snake.nextposition[1]) == (self.food.x, self.food.y):
            self.snake.eatFood()
            self.food.changelocation()
        else:
            self.snake.moveOneStep()

        if self.counter == 10:
            self.food.changestate()  # makes the food flash slowly
            self.counter = 0
        else:
            self.counter += 1

        self.food.drawself(self.artist)  # show the food and snake
        self.snake.drawself(self.artist)
        self.screen.update()
        self.screen.ontimer(lambda: self.nextFrame(), 100)

    def snakeup(self):
        if not self.commandpending: 
            self.commandpending = True
            self.snake.moveup()
            self.commandpending = False

    def snakedown(self):
        if not self.commandpending:
            self.commandpending = True
            self.snake.movedown()
            self.commandpending = False

    def snakeleft(self):
        if not self.commandpending:
            self.commandpending = True
            self.snake.moveleft()
            self.commandpending = False

    def snakeright(self):
        if not self.commandpending:
            self.commandpending = True
            self.snake.moveright()
            self.commandpending = False

game = Game()

screen = Screen()

screen.ontimer(lambda: game.nextFrame(), 100)

screen.mainloop()

Does this provide the kind of response for which you're looking?

2 of 3
0

It probably is a challenge to make a speedy game this way (but that's not all bad). I think that listen() should go after the onkey()s.

You should also look at getting rid of all the duplicated code. It might seem easy short term to just copy/paste then alter. But if you have to make major changes (like after asking on a forum) it will be tedious and error prone to alter.

PS (EDIT) also your Snake.moveOneStep() method makes a new instance of Square just to check for self collision, this seems extravagant for the sake of elegance. Better to just keep a list of locations that python (ho, ho) can check through. (Quite apart from this probably not working. Try print(Square(1,2) in [Square(1,2)]))

def check_self_collision(self, x, y):
  for s in self.body:
    if s.x == x and s.y == y:
      return False
  return True

def moveOneStep(self):
    if self.check_self_collision(self.nextposition[0], self.nextposition[1]): 
        # attempt (unsuccessful) at collision detection
        self.body.append(Square(self.nextposition[0], self.nextposition[1])) 
🌐
AskPython
askpython.com › python › examples › easy-games-in-python
Easy Games in Python - AskPython
April 20, 2026 - These projects reinforce core Python skills: variables, loops, conditionals, functions, and input handling. No external game engines or complex setup required. You can build fun games in Python using only the standard library — no pygame or ...
Find elsewhere
🌐
Quora
quora.com › How-do-I-code-games-without-using-the-Pygame-library-in-Python
How to code games without using the Pygame library in Python - Quora
Answer (1 of 2): When I was in college in the dim an misty past, I played a game on printing terminals called Star Trek (1971 video game) - Wikipedia. It could also be played on video terminals, but we didn’t get those until the next year. The game was pretty engaging for something that used ...
🌐
ActiveState
code.activestate.com › recipes › 578816-the-game-of-tic-tac-toe-in-python
The Game of Tic Tac Toe in Python « Python recipes « ActiveState Code
January 31, 2014 - Classic game but lacking in graphics :P Check out Tic-tac-toe in Free Python Games at http://www.grantjenks.com/docs/freegames/ You can just do "python3 -m pip install freegames" and then "python3 -m freegames.tictactoe" That includes a complete visual interface in just 57 lines of Python code!
🌐
YouTube
youtube.com › clear code
Master Python by making 5 games [the new ultimate introduction to pygame] - YouTube
Thanks to Brilliant for the support, you can find them here: https://brilliant.org/ClearCode/ This video covers game development in Python. We will create a ...
Published   May 19, 2024
Views   99K
🌐
PyPI
pypi.org › project › gamesbyexample
gamesbyexample · PyPI
They fit into a single source code file and have no installer. This makes these games trivial to share by copy/pasting code to a pastebin site. Data/image/save files can be used, but the source should link to some examples in their comments. They only use the Python standard library.
      » pip install gamesbyexample
    
Published   Dec 30, 2020
Version   2020.12.30
🌐
Reddit
reddit.com › r/learnpython › can you code a game from scratch in python without using modules?
r/learnpython on Reddit: Can you code a game from scratch in Python without using modules?
June 25, 2022 -

I'm a beginner programmer and am curious about why modules like pygame seem to be the only way that people teach basic game development. I understand that these modules have extensive libraries and functions that streamline the development process, but I'm curious as to if there is a way to create a simple game without using any of these modules or if it is simply a necessity, in the same way that you can't run python code without installing python first. Any explanation would be greatly appreciated as I can not find any elsewhere.

Edit: Thank you all I couldn't find an explanation anywhere else

🌐
DEV Community
dev.to › unitybuddy › 5-python-games-with-source-code-3g2b
5+ Python Games With Source Code - DEV Community
October 24, 2021 - Hello, buddies! Python is a great programming language for Game development, which makes it more popular. Since Python is easy to use and understand, game developers choose Python for making (small) games just like Snake game, Air Strike, Ninja run, etc.
🌐
CopyAssignment
copyassignment.com › python-games-code-copy-and-paste
Python Games Code | Copy and Paste – CopyAssignment
August 23, 2022 - Jumbled Word Quiz Game Creating a Pong Game using Python Turtle Hangman Game using Python Snake Game in Python using Pygame Balloon Shooter Game using Python PyGame Complete PyGame Tutorial and Projects Create Blackjack Game using Python Flappy Bird In Python Pygame with source code Complete Racing Game In Python Using PyGame Complete Game In PyGame and Python Python Complete Setup for Pygame Snake Game with Python Turtle Graphics Star Wars Game with Python Turtle Car Race Game in PyGame Python: From Scratch Bouncing Ball Game Snake Game in Python using Pygame Rock Paper Scissor Game Using Pyt
🌐
Quora
quora.com › How-do-I-make-a-game-in-Python-copy-paste
How to make a game in Python copy paste - Quora
Answer (1 of 3): You have to decide what to copy and paste - this is not really a Python question; it is a software design question. what data do you need to ‘copy’, how does the user select what to copy, when the user pastes how do they identify where the data is pasted ?
🌐
Backlinkworks
blogs.backlinkworks.com › home › copy and paste your way to a fun python game with this simple code!
Copy and Paste Your Way to a Fun Python Game with This Simple Code! - Topics on SEO & Backlinks
November 8, 2023 - Simply copy and paste the above code into a Python IDE or text editor, and you’ll have a working Rock, Paper, Scissors game ready to go!
🌐
Stack Overflow
stackoverflow.com › questions › 48614942 › is-it-possible-to-make-games-in-python-without-pygame
Is it possible to make games in Python without Pygame? - Stack Overflow
You can always use PyOpenGL directly, but maybe it's a little rough to start. Other option I know it's Blender which has a lot of tools, mostly modelling and rendering but you can also make games and its scripting is in python.
🌐
Medium
pedroalvarad0.medium.com › how-to-code-the-game-of-life-in-python-without-pygame-31578de09aa9
How to code the Game Of Life in Python without Pygame | by Pedro Alvarado | Medium
May 14, 2022 - We do this with “time.sleep”. But before creating the delay we need to copy the “gameState” in to a new variable called “newGameState”. In this step we use the numpy copy function.
🌐
GeeksforGeeks
geeksforgeeks.org › python › create-a-snake-game-using-turtle-in-python
Create a Snake-Game using Turtle in Python - GeeksforGeeks
February 18, 2026 - Your All-in-One Learning Portal. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.