본문 바로가기

[Pygame] 🐍 스네이크 게임 만들기 6강 | 먹이 처리 + 점수

@도마22026. 1. 6. 19:00
728x90


6강에서 할 일

6강에서는 드디어 “게임다운 루프”를 만듭니다.

  • 뱀 머리가 먹이에 닿으면 “먹었다”로 판정합니다
  • 점수를 1씩 올립니다
  • 먹이를 새로운 위치에 다시 생성합니다(뱀 머리와 겹침 방지)
  • 화면에 점수를 표시합니다

1) 점수 변수를 만듭니다

점수는 게임 시작 시 0으로 둡니다.
게임 루프 밖에 추가합니다.

score = 0

2) 점수 표시용 폰트를 준비합니다

파이게임에서 텍스트를 출력하려면 폰트 객체가 필요합니다.
게임 루프 밖에 추가합니다.

font = pygame.font.SysFont(None, 36)
  • None은 기본 폰트를 사용한다는 뜻입니다
  • 36은 글자 크기입니다

점수는 흰색이 보기 좋습니다. 흰색도 정의합니다.

WHITE = (255, 255, 255)

3) “먹이 재생성”을 함수로 만듭니다

먹이를 생성하는 코드는 앞으로 자주 씁니다.

  • 게임 시작할 때 1번
  • 먹이를 먹을 때마다 1번

그래서 함수로 빼두면 코드가 깔끔합니다.
게임 루프 위쪽(설정 부분)에 추가합니다.

def spawn_food(snake_x, snake_y):
    while True:
        x = random.randint(0, GRID_SIZE - 1)
        y = random.randint(0, GRID_SIZE - 1)
        if x != snake_x or y != snake_y:
            return x, y

이 함수는:

  • 뱀 머리 위치를 받아서
  • 겹치지 않는 먹이 좌표를 만들어서
  • (x, y) 형태로 반환합니다

4) 기존 먹이 생성 코드를 함수로 교체합니다

5강에서 만들었던 while True: 먹이 생성 부분을 지우고, 아래처럼 바꿉니다.

food_x, food_y = spawn_food(snake_x, snake_y)

5) “먹었는지” 판정합니다

먹었다는 조건은 간단합니다.

  • 뱀 머리 좌표 == 먹이 좌표

이 판정은 이동이 끝난 직후에 처리해야 자연스럽습니다.
즉, “뱀이 한 칸 움직인 다음” 먹이를 먹는 방식입니다.

이동 처리 블록 안(벽 충돌 검사 아래)에 추가합니다.

if snake_x == food_x and snake_y == food_y:
    score += 1
    food_x, food_y = spawn_food(snake_x, snake_y)

먹으면:

  • 점수가 1 증가합니다
  • 먹이가 새로운 위치로 이동합니다

6) 점수를 화면에 출력합니다

점수는 매 프레임 다시 그려야 화면에 유지됩니다.
그래서 그리기 파트(배경 칠한 다음)에 추가합니다.

score_text = font.render(f"Score: {score}", True, WHITE)
screen.blit(score_text, (10, 10))
  • render()로 글자를 이미지처럼 만든 뒤
  • blit()로 화면에 붙입니다
  • 좌측 상단 (10, 10)에 표시합니다

※ 점수 영역이 뱀 이동 구역과 겹칠 수 있지만, 지금 단계에서는 괜찮습니다.
나중에 UI 영역을 따로 두는 개선도 가능합니다.


6강 정리

이번 강의에서 완성된 기능입니다.

  • 뱀 머리가 먹이에 닿으면 점수가 증가합니다
  • 먹이는 먹을 때마다 새 위치에 다시 생성됩니다
  • 점수가 화면에 표시됩니다

전체 코드

더보기
import pygame
import sys
import random

pygame.init()

# =========================
# 기본 설정
# =========================
CELL_SIZE = 40
GRID_SIZE = 10
SCREEN_SIZE = CELL_SIZE * GRID_SIZE

BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
YELLOW = (255, 255, 0)
WHITE = (255, 255, 255)

# =========================
# 화면 설정
# =========================
screen = pygame.display.set_mode((SCREEN_SIZE, SCREEN_SIZE))
pygame.display.set_caption("10x10 Snake Game")

clock = pygame.time.Clock()

# =========================
# 점수 및 폰트
# =========================
score = 0
font = pygame.font.SysFont(None, 36)

# =========================
# 먹이 생성 함수
# =========================
def spawn_food(snake_x, snake_y):
    while True:
        x = random.randint(0, GRID_SIZE - 1)
        y = random.randint(0, GRID_SIZE - 1)
        if x != snake_x or y != snake_y:
            return x, y

# =========================
# 뱀 초기 위치 (격자 좌표)
# =========================
snake_x = 5
snake_y = 5

# =========================
# 방향 설정
# =========================
direction = "RIGHT"
next_direction = direction

# =========================
# 이동 제어
# =========================
move_delay = 1
move_counter = 0

# =========================
# 먹이 초기 생성
# =========================
food_x, food_y = spawn_food(snake_x, snake_y)

# =========================
# 게임 루프
# =========================
while True:
    # 이벤트 처리
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

        # 방향키 입력
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP and direction != "DOWN":
                next_direction = "UP"
            elif event.key == pygame.K_DOWN and direction != "UP":
                next_direction = "DOWN"
            elif event.key == pygame.K_LEFT and direction != "RIGHT":
                next_direction = "LEFT"
            elif event.key == pygame.K_RIGHT and direction != "LEFT":
                next_direction = "RIGHT"

    # 이동 타이밍
    move_counter += 1
    if move_counter >= move_delay:
        move_counter = 0

        direction = next_direction

        if direction == "UP":
            snake_y -= 1
        elif direction == "DOWN":
            snake_y += 1
        elif direction == "LEFT":
            snake_x -= 1
        elif direction == "RIGHT":
            snake_x += 1

        # 벽 충돌
        if (
            snake_x < 0 or snake_x >= GRID_SIZE or
            snake_y < 0 or snake_y >= GRID_SIZE
        ):
            pygame.quit()
            sys.exit()

        # 먹이 먹기 판정
        if snake_x == food_x and snake_y == food_y:
            score += 1
            food_x, food_y = spawn_food(snake_x, snake_y)

    # 배경
    screen.fill(BLACK)

    # 점수 표시
    score_text = font.render(f"Score: {score}", True, WHITE)
    screen.blit(score_text, (10, 10))

    # 뱀 그리기
    snake_rect = pygame.Rect(
        snake_x * CELL_SIZE,
        snake_y * CELL_SIZE,
        CELL_SIZE,
        CELL_SIZE
    )
    pygame.draw.rect(screen, GREEN, snake_rect)

    # 먹이 그리기
    food_rect = pygame.Rect(
        food_x * CELL_SIZE,
        food_y * CELL_SIZE,
        CELL_SIZE,
        CELL_SIZE
    )
    pygame.draw.rect(screen, YELLOW, food_rect)

    # 화면 갱신
    pygame.display.update()

    # FPS
    clock.tick(10)

728x90
도마2
@도마2 :: 도마의 코드노트

초보자를 위한 코딩 강의를 정리합니다. 파이썬부터 C#, Unity 게임 제작까지 차근차근 기록합니다. — 도마

목차