https://github.com/yeschan119/mini-projects/tree/main/snake
실행 결과

code
from turtle import Screen, Turtle
from snake import Snake
from food import Food
from scoreboard import Scoreboard
import time
#name game
#make 2 steps
# first step
## make a snake
## move a snake
## control the snake
# second step
## detect collision with food
## create a scoreboard
## detect collision with wall
## detect collision with tail
screen = Screen() #display the screen
screen.setup(width=700, height=700)
screen.bgcolor("black")
screen.title("My Snake Game")
#step 1 create a snake
screen.tracer(20)
snake = Snake()
food = Food()
score = Scoreboard()
#wait for the command from keyboard
screen.listen()
#control the snake with keyboard
screen.onkey(snake.up, "Up")
screen.onkey(snake.down, "Down")
screen.onkey(snake.left, "Left")
screen.onkey(snake.right, "Right")
#step 2 move a snake
game_is_on = True
while game_is_on:
    screen.update()
    time.sleep(0.1)
    snake.move()
    
    #detect collision with food
    if snake.head.distance(food) < 14:
        food.refresh()
        snake.extend()
        score.increase_score()
        
    #detect collision with wall
    #xcor(), ycor()는 해당 turtle객체가 있는 좌표를 리턴
    if snake.head.xcor() > 340 or snake.head.xcor() < -340 or snake.head.ycor() > 340 or snake.head.ycor() < -340:
        game_is_on = False
        score.game_over()
    
    #detect collision with tail
    #if head collides with any segment in the tail, trigger game_over
    for segment in snake.snake_body[1:]:
        if snake.head.distance(segment) < 10:
            game_is_on = False
            score.game_over()
    
#not to disappear the screen
screen.exitonclick()
from turtle import Screen, Turtle
#뱀의 몸을 만들어 주는 API
STARTING_POSITION = [(0, 0), (-20, 0), (-40, 0)]
UP = 90
DOWN = 270
LEFT = 180
RIGHT = 0
MOVE_DISTANCE = 20
class Snake:
    def __init__(self):
        self.snake_body = []
        self.create_snake()
        self.head = self.snake_body[0]
    
    #starting position에 세 개의 점을 찍고 세점을 연결하여 뱀을 생성
    #snake_body리스트가 곧 뱀의 몸체임
    def create_snake(self):
        for pos in STARTING_POSITION:
            self.add_segment(pos)
    
    def add_segment(self, position):
        segment = Turtle(shape="square")
        segment.shapesize(0.8, 0.8)
        segment.color("white")
        segment.penup()  #penup() 메서드는 0, 0에서 이동할 때 이동경로에 따라 그어지는 선을 없앨 때 사용
        segment.goto(position) #goto()는 주어진 좌표로 이동
        self.snake_body.append(segment)
        
    def extend(self):
        #add a new segment to the snake
        self.add_segment(self.snake_body[-1].position())
        
    #전체적으로 움직이는 방법은 다음과 같다.
    #3번이 2번 자리로, 2번이 1번 자리로, 1번은 원하는 자리로
    #이런식으로 움직여야 1번을 머리로 하여, 머리가 움직이는 방향으로 몸이 따라옴
    def move(self):
        for seg_num in range(len(self.snake_body)-1, 0, -1):
            new_x = self.snake_body[seg_num-1].xcor()
            new_y = self.snake_body[seg_num-1].ycor()
            self.snake_body[seg_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)
from turtle import Turtle
import random
#뱀의 먹이를 재현하는 API
#뱀의 머리가 먹이와 부딪힐 때 먹는 것으로 보고 하나가 먹히면 랜덤으로 임의의 장소에 먹이가 생성
class Food(Turtle):
    
    def __init__(self):
        super().__init__()
        self.shape("turtle")
        self.penup()
        self.shapesize(stretch_len=0.6, stretch_wid=0.6) #shapesize는 default가 20  x 20인데 10  x 10으로 하고 싶다는 것
        self.color("blue")
        self.speed("fastest")
        self.refresh()
        
    def refresh(self):
        random_x = random.randint(-310, 310)
        random_y = random.randint(-310, 310)
        self.goto(random_x, random_y)
from turtle import Turtle
#뱀이 먹이를 먹을 때마다 점수가 올라가도록 하는 API
ALINEMENT = "center"
FONT = ("Arial", 22, "normal")
class Scoreboard(Turtle):
    def __init__(self):
        super().__init__()
        self.score = 0
        self.color("white")
        self.penup()
        self.goto(0, 315)
        self.hideturtle()   #hideturtle()을 해주면  turtle객체를 가져다 쓰면서 turtle이 화면이 안보이게 함
        self.update_scoreboard()
    
    def update_scoreboard(self):
        self.write(f"Score: {self.score}", align=ALINEMENT, font=FONT) 
    def increase_score(self):
        self.score += 1
        self.clear()  #점수가 바뀔때마다 clear해주지 않으면 덮어써지는 게 보임
        self.update_scoreboard()
        
    def game_over(self):
        self.goto(0,0)
        self.write("GAME OVER", align=ALINEMENT, font=FONT)