Created
August 25, 2024 21:48
-
-
Save timotree3/ed2af3b5bc7c209bf5723d7c04a35cc2 to your computer and use it in GitHub Desktop.
Snake with Python Turtle Graphics
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from turtle import Turtle, bgcolor, setup, delay, onkey, listen, ontimer, title | |
import random | |
CELL_SIZE = 25 | |
headTurtle = Turtle() | |
appleTurtle = Turtle() | |
textTurtle = Turtle() | |
setup(25 * 17 + 7, 25 * 17 + 7) | |
title("Snake!") | |
bgcolor(0, 1, 0) | |
headTurtle.shape("square") | |
headTurtle.color(0, 0, 1) | |
headTurtle.penup() | |
headTurtle.shapesize(25/20, 25/20) | |
appleTurtle.shape("circle") | |
appleTurtle.color(1, 0, 0) | |
appleTurtle.penup() | |
appleTurtle.shapesize(25/20, 25/20) | |
textTurtle.penup() | |
textTurtle.hideturtle() | |
delay(0) | |
def initialize(): | |
global gameStarted, heading, segments, stamps, initialSnakeLength, snakeLength, lastWent | |
gameStarted = False | |
segments = [(0, 0)] | |
stamps = [] | |
initialSnakeLength = 3 | |
snakeLength = 3 | |
lastWent = None | |
initialize() | |
def spawnApple(): | |
global apple | |
while True: | |
apple = (random.randint(-8, 8), random.randint(-8, 8)) | |
if apple not in segments: | |
drawApple() | |
return | |
# We draw everything with an offset of 4 pixels up and the to left because the screen is off-center by default | |
def myGoto(turtle, x, y): | |
turtle.goto(x-4, y+4) | |
def drawApple(): | |
appleTurtle.showturtle() | |
myGoto(appleTurtle, apple[0] * CELL_SIZE, apple[1] * CELL_SIZE) | |
def clearApple(): | |
appleTurtle.hideturtle() | |
def upArrow(): | |
global heading | |
if lastWent != "down": | |
heading = "up" | |
startGame() | |
def leftArrow(): | |
global heading | |
if lastWent != "right": | |
heading = "left" | |
startGame() | |
def rightArrow(): | |
global heading | |
if lastWent != "left": | |
heading = "right" | |
startGame() | |
def downArrow(): | |
global heading | |
if lastWent != "up": | |
heading = "down" | |
startGame() | |
onkey(upArrow, "Up") | |
onkey(leftArrow, "Left") | |
onkey(rightArrow, "Right") | |
onkey(downArrow, "Down") | |
listen() | |
def moveHead(x, y): | |
myGoto(headTurtle, x * CELL_SIZE, y * CELL_SIZE) | |
spawnApple() | |
moveHead(0, 0) | |
def startGame(): | |
global gameStarted | |
if gameStarted: | |
return | |
gameStarted = True | |
textTurtle.clear() # Clear the game over text | |
textTurtle.hideturtle() # Hide the turtle again because clear() resets that | |
drawApple() | |
processTurn() | |
def processTurn(): | |
global snakeLength, gameStarted, lastWent | |
currentHead = segments[-1] | |
if heading == "up": | |
newHead = (currentHead[0], currentHead[1] + 1) | |
elif heading == "left": | |
newHead = (currentHead[0] - 1, currentHead[1]) | |
elif heading == "right": | |
newHead = (currentHead[0] + 1, currentHead[1]) | |
else: | |
newHead = (currentHead[0], currentHead[1] - 1) | |
lastWent = heading | |
if newHead[0] < -8 or newHead[0] > 8 or newHead[1] < -8 or newHead[1] > 8: | |
gameOver() | |
return | |
if newHead == apple: | |
snakeLength += 1 | |
clearApple() | |
# Delete the oldest segments to make sure the snake stays the right length | |
while len(segments) > snakeLength - 1: | |
segments.pop(0) | |
if newHead in segments: | |
gameOver() | |
return | |
segments.append(newHead) | |
# stamp() creates a copy of the snake head so it stays there when it moves | |
stamps.append(headTurtle.stamp()) | |
while len(stamps) > snakeLength - 1: | |
headTurtle.clearstamp(stamps.pop(0)) | |
moveHead(newHead[0], newHead[1]) | |
if newHead == apple: | |
spawnApple() | |
# we can't use time.sleep because turtle can't process input while sleeping | |
ontimer(processTurn, 200) | |
def gameOver(): | |
clearApple() | |
points = snakeLength - initialSnakeLength | |
textTurtle.goto(0, 40) | |
textTurtle.color(.8, .6, .8) | |
textTurtle.write(f"game over! points: {points}", | |
align="center", font=('Arial', 20, 'normal')) | |
# Reset everything for the next game | |
for stamp in stamps: | |
headTurtle.clearstamp(stamp) | |
initialize() | |
moveHead(0, 0) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment