Fifth Python Project: Snake Game - 2

 

 

Requirements (The highlighted parts are the ones covered this time):

1. Create a snake body
2. Move the snake
3. Control the snake
4. Detect collision with food
5. Create a scoreboard
6. Detect collision with wall (The game should display "Game Over" and the snake should stop moving)
7. Detect collision with tail (The game should end when the snake's head touches its own body)

 

 

main.py

from turtle import Screen
from snake import Snake
from food import Food
import time
from scoreboard import Scoreborad

screen = Screen()
screen.setup(width=600, height=600)
screen.bgcolor("black")
screen.title("Snake Game")
screen.tracer(0)


snake = Snake()
food = Food()
scoreborad = Scoreborad()

screen.listen()
screen.onkey(snake.up, "Up")
screen.onkey(snake.down,"Down")
screen.onkey(snake.left, "Left")
screen.onkey(snake.right, "Right")

game_is_on = True
while game_is_on:  
    screen.update()
    time.sleep(0.07)
    
    if snake.head.distance(food) < 15:
        food.refresh()
        snake.extend()
        scoreborad.get_score()
        
    if snake.head.xcor() > 280 or snake.head.xcor() < -280 or snake.head.ycor() > 280 or snake.head.ycor() < -280:
        game_is_on = False
        scoreborad.game_over()
        
        
    for segment in snake.segments[1:]:
  # slicing in list              ----
		if snake.head.distance(segment) < 10:
            game_is_on = False
            scoreborad.game_over()
    snake.move()








screen.exitonclick()

 

 

scoreboard.py

from turtle import Turtle
ALINGNMENt = "center"
FONT = ("Arial", 20, "normal")

class Scoreborad(Turtle):
    
    def __init__(self):
        super().__init__()
        self.score = 0
        self.color("white")
        self.penup()
        self.goto(0,260)
        self.hideturtle() 
        self.update_socreboard()
        
    def update_socreboard(self):
        self.write(f"Score: {self.score}", align=ALINGNMENt, font=FONT)
         
    def game_over(self):
        self.goto(0,0)
        self.write("GAME OVER", align=ALINGNMENt, font=FONT)
         
    def get_score(self):
        self.clear()
        self.score += 1
        self.update_socreboard()

 

 

food.py

from turtle import Turtle
import random

class Food(Turtle):
    
    def __init__(self):
        super().__init__()
        self.shape("circle")
        self.penup()
        self.shapesize(stretch_len=0.5, stretch_wid=0.5)
        self.color("blue")
        self.speed("fastest")
        self.refresh()

    def refresh(self):
        random_x = random.randint(-270, 270)
        random_y = random.randint(-270, 270)
        self.goto(random_x, random_y)

 

 

snake.py

from turtle import Turtle

STARTING_POSITIONS = [(0, 0), (-20, 0), (-40, 0)]
MOVE_DISTANCE = 20
UP = 90
DOWN = 270
LEFT = 180
RIGHT = 0

class Snake:
    
    def __init__(self):
        self.segments = []
        self.create_snake()
        self.head = self.segments[0]

    def create_snake(self):
        for position in STARTING_POSITIONS:
            self.add_segment(position)
            
    def add_segment(self, position):
            new_segment = Turtle(shape="square")
            new_segment.color("white")
            new_segment.penup()
            new_segment.goto(position)
            self.segments.append(new_segment)  
            
    def extend(self):
        self.add_segment(self.segments[-1].position())               
    
    def move(self):
        for segment_num in range(len(self.segments)-1, 0,-1):
            new_x = self.segments[segment_num - 1].xcor()
            new_y = self.segments[segment_num - 1].ycor()
            self.segments[segment_num].goto(new_x, new_y)
        self.head.forward(MOVE_DISTANCE)
        
    def up(self):
        if self.head.heading() != DOWN:
            self.head.setheading(UP)
    
    def down(self):
        if self.head.heading() != UP:
            self.head.setheading(DOWN)
    
    def left(self):
        if self.head.heading() != RIGHT:
            self.head.setheading(LEFT)
           
    def right(self):
        if self.head.heading() != LEFT:
            self.head.setheading(RIGHT)

 

 

Realization:

1. I realized the benefits of class inheritance in coding by applying it to game development,

    after only learning it theoretically in college.

2. I learned how to write cleaner code by utilizing slicing in lists.