SnakeGame.py source file section by section. Each accordion covers a distinct part of the program, with the actual code and an explanation of what it does.
Section 1: Imports and global variables (lines 1–13)
Section 1: Imports and global variables (lines 1–13)
The file begins with three standard library imports and three global variables that track game state.
| Name | Type | Purpose |
|---|---|---|
turtle | module | Provides the graphics window, drawing primitives, and Turtle objects for the snake, food, and score display. |
time | module | Used for time.sleep() to introduce a fixed delay between each frame. |
random | module | Used for random.randint() to place food at a random position after it is eaten. |
retraso | float | Frame delay in seconds. Set to 0.1, meaning the game targets roughly 10 frames per second. |
puntaje | int | Current score. Starts at 0, increments by 10 each time food is eaten, and resets to 0 on a collision. |
puntajeAlto | int | Session high score. Starts at 0 and is only updated upward — it never resets during a session. |
Section 2: Screen setup (lines 15–28)
Section 2: Screen setup (lines 15–28)
The game window is created and configured before any game objects are drawn.
| Call | Effect |
|---|---|
turtle.Screen() | Creates the single game window and returns a reference stored in screen. |
screen.setup(650, 650) | Sets the canvas to 650×650 pixels. The playable area is the inner ±300 pixel range on each axis. |
screen.bgcolor('black') | Sets the background color to black, which provides contrast for the light green snake and red food. |
screen.title(...) | Sets the text shown in the window title bar. |
screen.tracer(0) | Disables automatic screen updates. With tracer(0), nothing is drawn to the window until screen.update() is called explicitly. This prevents flickering during a frame and is required for smooth animation. |
Because
screen.tracer(0) is set here, every iteration of the main game loop must call screen.update() manually at the start of the loop to render the latest frame.Section 3: Snake object (lines 30–46)
Section 3: Snake object (lines 30–46)
The snake’s head is a single
Turtle object. The body segments are separate objects added later.| Attribute / Call | Purpose |
|---|---|
serpiente.shape('square') | Renders the head as a filled square, matching the grid-aligned 20-pixel movement steps. |
serpiente.color('lightgreen') | Light green color distinguishes the head from the darker green body segments. |
serpiente.penup() | Prevents the turtle from drawing lines as it moves. |
serpiente.goto(0, 0) | Places the head at the center of the canvas at startup. |
serpiente.direction = 'stop' | A custom attribute (not built-in to Turtle) used by the direction functions and movimiento() to track which way the snake is heading. Initial value 'stop' means the snake does not move until the player presses an arrow key. |
Section 4: Food object (lines 51–67)
Section 4: Food object (lines 51–67)
The food is a separate
When the snake eats the food, the game loop calls
Turtle object styled as a red circle.| Attribute / Call | Purpose |
|---|---|
comida.shape('circle') | Circle shape visually differentiates the food from the square snake segments. |
comida.color('red') | High-contrast red makes the food easy to spot on the black background. |
comida.goto(0, 100) | Places the food slightly above center at startup so it is not on top of the snake head. |
comida.speed(0) | Sets the turtle animation speed to maximum, so repositioning the food after it is eaten appears instantaneous. |
comida.goto(x, y) with random coordinates to move it to a new position.Section 5: Body list and score display (lines 69–93)
Section 5: Body list and score display (lines 69–93)
The snake’s body is tracked as a plain Python list, and a dedicated
Turtle object renders the score text.cuerpo is a list of turtle.Turtle objects. Each time the snake eats food, a new square Turtle (colored 'green') is appended. The game loop propagates positions through this list each frame so segments follow the head.texto call | Effect |
|---|---|
texto.hideturtle() | Hides the turtle cursor so only the written text is visible. |
texto.goto(0, -260) | Positions the score text below the 300-pixel play boundary, in the lower margin of the 650-pixel canvas. |
texto.write(...) | Renders the score string. The align="center" argument centers the text at the turtle’s position. texto.clear() is called before each update to erase the previous text before writing the new value. |
Section 6: Direction functions (lines 96–129)
Section 6: Direction functions (lines 96–129)
Four functions handle keyboard input. Each sets Each function follows the same pattern:
serpiente.direction but includes a guard to prevent reversing direction (which would cause an immediate self-collision).- Check whether the snake is currently moving in the directly opposite direction.
- Only update
serpiente.directionif the guard condition passes.
abajo() while the snake is moving 'up' does nothing — the guard serpiente.direction != 'up' is False, so the assignment is skipped. This prevents the player from instantly reversing into the snake’s own body.Section 7: Movement function (lines 131–168)
Section 7: Movement function (lines 131–168)
movimiento() translates the current direction string into a pixel offset applied to the snake head.movimiento() moves the head exactly once, so calling it once per game loop iteration produces consistent speed controlled by time.sleep(retraso).When serpiente.direction == 'stop', none of the four if branches match and the function returns without moving the head.Section 8: Event bindings (lines 170–184)
Section 8: Event bindings (lines 170–184)
Keyboard input is wired up after the functions are defined.
The key strings
| Call | Effect |
|---|---|
screen.listen() | Activates keyboard event detection on the game window. Without this call, onkeypress bindings have no effect. |
screen.onkeypress(arriba, "Up") | Calls arriba() each time the Up arrow key is pressed. |
screen.onkeypress(abajo, "Down") | Calls abajo() each time the Down arrow key is pressed. |
screen.onkeypress(derecha, "Right") | Calls derecha() each time the Right arrow key is pressed. |
screen.onkeypress(izquierda, "Left") | Calls izquierda() each time the Left arrow key is pressed. |
"Up", "Down", "Right", and "Left" are the Tkinter key names for the arrow keys. turtle uses Tkinter under the hood for event handling.Section 9: Main game loop (lines 187–359)
Section 9: Main game loop (lines 187–359)
The game runs in an infinite Each frame executes in this order:
while True: loop. Each iteration represents one frame.screen.update()— Flushes all pending drawing operations to the window. Required becausescreen.tracer(0)is set.- Wall collision check — If
xcor()orycor()is outside ±300, the game pauses for 2 seconds, hides and removes all body segments, returns the head to the origin withserpiente.home(), resetsserpiente.directionto'stop', clearscuerpo, resetspuntajeto0, and updates the score display.puntajeAltois not reset. - Food collision — If the Euclidean distance between the snake head and
comidais less than 20 pixels, food is relocated randomly within ±250 pixels, a new body segmentTurtleis created (dark green square) and appended tocuerpo,puntajeincreases by 10, andpuntajeAltois updated if the new score exceeds it. - Body propagation — Iterates
cuerpofrom the tail forward, moving each segment to the previous segment’s position. The first segment moves to the head’s current (pre-move) position. This runs beforemovimiento()so the head’s old position is captured correctly. movimiento()— Advances the snake head one step.- Self-collision check — Iterates all body segments and checks if any is within 20 pixels of the head. If so, the game resets identically to a wall collision (minus the 2-second pause).
time.sleep(retraso)— Pauses for0.1seconds, throttling the game to approximately 10 frames per second.
