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)