지렁이 게임은 플레이어가 지렁이(또는 뱀)를 조종하여 화면에 보이는 먹이를 먹고 자라면서 크기를 키우고 점수를 계속 올리는 게임이며, 지렁이는 일정한 속도로 계속 움직일 때, 방향을 잘 조절하여 벽에 닿거나 자신의 몸에 닿지 않도록 유지하면서 가능한 오래 살아남는 게임이다. 앞서 pygame 버전의 지렁이 게임을 만들었고 이번에는 터틀 그래픽을 활용한 지렁이 게임이다.
Table of Contents
지렁이 게임 만들기(터틀 그래픽 버전)
![[파이썬 게임] 지렁이 게임 만들기 Snake Game (터틀 그래픽 버전) 2 지렁이 게임 터틀 그래픽 버전](https://www.shindeacon.co.kr/wp-content/uploads/2024/06/지렁이.gif)
1. 게임 규칙
- 움직임 : 지렁이는 지속적으로 움직이게 되며 플레이는 방향키를 이용하여 지렁이의 방향을 조정할 수 있다.
- 먹이 : 화면에 빨간색 먹이가 랜덤한 위치에 나타나며, 지렁이가 지나 갈 때 그 먹이를 먹으면 길이가 길어지고 점수도 올라 가게 된다.
- 충돌 : 벽이나 자신의 몸에 부딛히면 게임은 자동으로 종료된다.
- 점수 : 먹이를 먹을 때마다 점수가 올라가며, 충돌로 인한 게임이 종료가 되면 최고 점수를 기록하여 기록을 세울 수 있다. 참고로 지렁이는 먹이를 먹을 때마다 길이가 길어지면서 게임이 점점 어려워 진다.
2. 각 파트별 코드 설명
- 화면 설정 :
- screen이라는 터틀을 만들어 게임 화면을 설정한다.
- tracer(0)을 활용하여 화면 업데이트를 수동으로 조절한다.
- 지렁이의 머리와 먹이 설정 :
- head 터틀을 만들어 지렁이의 머리를 설정하고, 초기 위치와 방향을 지정한다.
- food 터틀을 만들어 먹이로 설정하고 초기 위치를 지정한다.
- 점수 표시 :
- score_turtle 객체를 만들어 현재 점수와 최고 점수를 화면에 표시한다.
- 사용하는 함수들 :
- 방향 전환 함수 (‘go_up’, ‘go_down’, ‘go_left’, ‘go_right’) : 사용자가 키보드를 눌러 지렁이의 방향을 전환 할 수 있게 한다.
- move 함수 : 지렁이의 머리를 현재 방향으로 이동시킨다.
- reset_game 함수 : 게임을 리셋하여 초기 상태로 되돌린다.
- update_score 함수 : 점수를 업데이트하여 화면에 표시한다.
- 키보드 입력 설정 :
- screen.listen() 을 호출 하여 키보드를 입력을 가능하게 해준다.
- 각 방향 전환 함수를 키보드에 연결한다.
- 게임 메인 루프 :
- 무한 루프를 사용하여 게임을 계속 진행한다.
- screen.update()를 호출하여 화면을 갱신한다.
- 벽에 부딛히거나 먹이를 먹었는지 체크하고, 지렁이의 몸을 이동시킨다.
- 일정 시간마다 time.sleep(delay)로 게임 속도를 조절한다.
3. 지렁이 게임 스크립트
import turtle
import time
import random
delay = 0.1
score = 0
high_score = 0
# 화면 설정
screen = turtle.Screen()
screen.title("Snake Game")
screen.bgcolor("black")
screen.setup(width=600, height=600)
screen.tracer(0) # 화면 업데이트를 수동으로 조절
# 뱀의 머리
head = turtle.Turtle()
head.speed(0)
head.shape("square")
head.color("white")
head.penup()
head.goto(0, 0)
head.direction = "stop"
# 먹이
food = turtle.Turtle()
food.speed(0)
food.shape("circle")
food.color("red")
food.penup()
food.goto(0, 100)
segments = []
# 점수 표시
score_turtle = turtle.Turtle()
score_turtle.speed(0)
score_turtle.color("white")
score_turtle.penup()
score_turtle.hideturtle()
score_turtle.goto(0, 260)
score_turtle.write("Score: 0 High Score: 0", align="center", font=("Courier", 24, "normal"))
# 함수들
def go_up():
if head.direction != "down":
head.direction = "up"
def go_down():
if head.direction != "up":
head.direction = "down"
def go_left():
if head.direction != "right":
head.direction = "left"
def go_right():
if head.direction != "left":
head.direction = "right"
def move():
if head.direction == "up":
y = head.ycor()
head.sety(y + 20)
if head.direction == "down":
y = head.ycor()
head.sety(y - 20)
if head.direction == "left":
x = head.xcor()
head.setx(x - 20)
if head.direction == "right":
x = head.xcor()
head.setx(x + 20)
def reset_game():
global score
time.sleep(1)
head.goto(0, 0)
head.direction = "stop"
for segment in segments:
segment.goto(1000, 1000)
segments.clear()
score = 0
score_turtle.clear()
score_turtle.write(f"Score: {score} High Score: {high_score}", align="center", font=("Courier", 24, "normal"))
def update_score():
score_turtle.clear()
score_turtle.write(f"Score: {score} High Score: {high_score}", align="center", font=("Courier", 24, "normal"))
# 키보드 입력
screen.listen()
screen.onkey(go_up, "Up")
screen.onkey(go_down, "Down")
screen.onkey(go_left, "Left")
screen.onkey(go_right, "Right")
# 게임 메인 루프
while True:
screen.update()
# 벽에 부딪힘 체크
if head.xcor() > 290 or head.xcor() < -290 or head.ycor() > 290 or head.ycor() < -290:
reset_game()
# 먹이에 닿았는지 체크
if head.distance(food) < 20:
x = random.randint(-290, 290)
y = random.randint(-290, 290)
food.goto(x, y)
# 새로운 세그먼트를 추가
new_segment = turtle.Turtle()
new_segment.speed(0)
new_segment.shape("square")
new_segment.color("grey")
new_segment.penup()
segments.append(new_segment)
# 점수 증가
score += 10
if score > high_score:
high_score = score
update_score()
# 몸 세그먼트를 반대로 이동
for index in range(len(segments)-1, 0, -1):
x = segments[index-1].xcor()
y = segments[index-1].ycor()
segments[index].goto(x, y)
# 머리를 첫 번째 세그먼트로 이동
if len(segments) > 0:
x = head.xcor()
y = head.ycor()
segments[0].goto(x, y)
move()
# 몸에 부딪힘 체크
for segment in segments:
if segment.distance(head) < 20:
reset_game()
time.sleep(delay)