본문 바로가기

Code-note

[프로젝트] snake 게임 만들기 -python

뱀이 움직이며 밥 먹는 게임! 가장 간단한 형태로 만들어보기

아무튼 뱀 입니다. (빨간건 밥)

 

import turtle
import time
import random

delay = 0.1  # 게임 속도 조절 변수

# 점수 변수
score = 0
high_score = 0

# 문제 1: 화면 설정 및 초기화
wn = turtle.Screen()  # Screen 객체를 생성합니다.
wn.title("Snake Game")  # 창의 제목을 설정합니다.
wn.bgcolor("skyblue")  # 배경색을 설정합니다.
wn.setup(width=600, height=600)  # 창의 크기를 설정합니다.
wn.tracer(0)  # 화면 업데이트를 멈춥니다.

# 기본 설정 세팅

# 문제 2: Snake의 머리 생성
head = turtle.Turtle()  # 터틀 객체를 생성합니다.
head.speed(0)  # 애니메이션 속도를 설정합니다.
head.shape("square")  # 머리 모양을 설정합니다.
head.color("black")  # 머리 색상을 설정합니다.
head.penup()  # 이동할 때 선을 그리지 않도록 합니다.
head.goto(0, 0)  # 초기 위치를 설정합니다. 중앙에 위치합니다.
head.direction = "stop"  # 초기 방향을 멈춤으로 설정합니다.

# 문제 3: Snake의 음식 생성
food = turtle.Turtle()  
food.speed(0)  
food.shape("circle") 
food.color("red")  
food.penup()
food.goto(0, 100)  

segments = []  # Snake의 몸통을 저장할 리스트를 초기화합니다.

# 문제 4: 점수판 생성 및 초기화
pen = turtle.Turtle()  # 터틀 객체를 생성합니다.
pen.speed(0)  # 애니메이션 속도를 설정합니다.
pen.shape("square")  # 모양을 설정합니다.
pen.color("black")  # 색상을 설정합니다.
pen.penup()  # 이동할 때 선을 그리지 않도록 합니다.
pen.hideturtle()  # 터틀을 숨깁니다.
pen.goto(0, 260)  # 위치를 설정합니다. 화면 상단 중앙에 위치합니다.
pen.write("Score: 0  High Score: 0", align="center", font=("Courier", 24, "normal"))  # 초기 점수를 화면에 표시합니다.

# 기본 오브젝트 생성 : 뱀 머리, 점수판

# 문제 5: Snake 이동 함수 작성
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()  # 현재 y 좌표를 가져옵니다.
        head.sety(y + 20)  # y 좌표를 20 증가시켜 위로 이동합니다.

    if head.direction == "down":  # 방향이 아래쪽이면
        y = head.ycor()  # 현재 y 좌표를 가져옵니다.
        head.sety(y - 20)  # y 좌표를 20 감소시켜 아래로 이동합니다.

    if head.direction == "left":  # 방향이 왼쪽이면
        x = head.xcor()  # 현재 x 좌표를 가져옵니다.
        head.setx(x - 20)  # x 좌표를 20 감소시켜 왼쪽으로 이동합니다.

    if head.direction == "right":  # 방향이 오른쪽이면
        x = head.xcor()  # 현재 x 좌표를 가져옵니다.
        head.setx(x + 20)  # x 좌표를 20 증가시켜 오른쪽으로 이동합니다.

# 문제 6: 키보드 입력 연결
wn.listen()  # 키보드 입력을 기다립니다.
wn.onkey(go_up, "w")  # 'w' 키를 누르면 go_up 함수가 호출됩니다.
wn.onkey(go_down, "s")  # 's' 키를 누르면 go_down 함수가 호출됩니다.
wn.onkey(go_left, "a")  # 'a' 키를 누르면 go_left 함수가 호출됩니다.
wn.onkey(go_right, "d")  # 'd' 키를 누르면 go_right 함수가 호출됩니다.

# 이동 함수/키 설정

# 문제 7: 메인 게임 루프
while True:
    wn.update()  # 화면을 업데이트합니다.

    # 문제 7.1: 경계 충돌 체크
    # Snake의 머리가 화면 경계를 넘어가면 게임을 초기화합니다.
    if head.xcor() > 290 or head.xcor() < -290 or head.ycor() > 290 or head.ycor() < -290:
        time.sleep(1)  # 1초 대기합니다.
        head.goto(0, 0)  # 머리를 초기 위치로 이동합니다.
        head.direction = "stop"  # 방향을 멈춤으로 설정합니다.

        # 몸통 세그먼트를 숨깁니다.
        for segment in segments:
            segment.goto(1000, 1000)  # 화면 밖으로 이동합니다.

        # 몸통 세그먼트 리스트를 초기화합니다.
        segments.clear()

        # 점수를 초기화합니다.
        score = 0
        delay = 0.1

        pen.clear()  # 점수판을 지웁니다.
        pen.write("Score: {}  High Score: {}".format(score, high_score), align="center", font=("Courier", 24, "normal"))  # 점수를 업데이트하여 화면에 표시합니다.

    # 문제 7.2: 음식과의 충돌 체크
    # Snake의 머리가 음식과 충돌하면 음식을 랜덤 위치로 이동하고, 몸통 세그먼트를 추가합니다.
    if head.distance(food) < 20:
        x = random.randint(-290, 290)  # x 좌표를 랜덤으로 설정합니다.
        y = random.randint(-290, 290)  # y 좌표를 랜덤으로 설정합니다.
        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)  # 세그먼트 리스트에 추가합니다.

        delay -= 0.001  # 속도를 증가시킵니다.

        score += 10  # 점수를 증가시킵니다.

        if score > high_score:  # 최고 점수보다 현재 점수가 높으면
            high_score = score  # 최고 점수를 업데이트합니다.

        pen.clear()  # 점수판을 지웁니다.
        pen.write("Score: {}  High Score: {}".format(score, high_score), align="center", font=("Courier", 24, "normal"))  # 점수를 업데이트하여 화면에 표시합니다.

    # 문제 7.3: 몸통 세그먼트 이동
    # 각 세그먼트를 바로 앞의 세그먼트 위치로 이동시킵니다.
    for index in range(len(segments)-1, 0, -1):
        x = segments[index-1].xcor()  # 앞 세그먼트의 x 좌표를 가져옵니다.
        y = segments[index-1].ycor()  # 앞 세그먼트의 y 좌표를 가져옵니다.
        segments[index].goto(x, y)  # 현재 세그먼트를 앞 세그먼트 위치로 이동합니다.

    # 첫 번째 세그먼트를 머리 위치로 이동시킵니다.
    if len(segments) > 0:
        x = head.xcor()  # 머리의 x 좌표를 가져옵니다.
        y = head.ycor()  # 머리의 y 좌표를 가져옵니다.
        segments[0].goto(x, y)  # 첫 번째 세그먼트를 머리 위치로 이동합니다.

    move()  # Snake를 이동시킵니다.

    # 문제 7.4: 몸통과의 충돌 체크
    # Snake의 머리가 몸통과 충돌하면 게임을 초기화합니다.
    for segment in segments:
        if segment.distance(head) < 20:
            time.sleep(1)  # 1초 대기합니다.
            head.goto(0, 0)  # 머리를 초기 위치로 이동합니다.
            head.direction = "stop"  # 방향을 멈춤으로 설정합니다.

            # 몸통 세그먼트를 숨깁니다.
            for segment in segments:
                segment.goto(1000, 1000)  # 화면 밖으로 이동합니다.

            segments.clear()  # 몸통 세그먼트 리스트를 초기화합니다.

            # 점수를 초기화합니다.
            score = 0
            delay = 0.1

            pen.clear()  # 점수판을 지웁니다.
            pen.write("Score: {}  High Score: {}".format(score, high_score), align="center", font=("Courier", 24, "normal"))  # 점수를 업데이트하여 화면에 표시합니다.

    time.sleep(delay)  # 게임 속도를 조절합니다.

wn.mainloop()  # 메인 루프를 실행합니다.

# 메인 실행 함수

 

# 해당 코드는 오즈코딩스쿨의 프로젝트 과제의 일부 입니다.