본문 바로가기

[Pygame] 🐍 스네이크 게임 만들기 3강 | 키보드 입력으로 뱀 머리 이동하기

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


 


3강에서 할 일

3강에서는 키보드 입력(방향키) 으로 뱀 머리가 격자 한 칸씩 움직이도록 만듭니다.

  • 방향 변수를 만듭니다
  • 방향키 입력을 받아 방향을 바꿉니다
  • 매 프레임이 아니라, “틱(tick)”마다 한 칸 이동하게 합니다
  • 반대 방향(즉시 유턴)은 막습니다 (안 막으면 다음 강의들에서 사고 납니다)

1) 뱀은 “방향”을 가지고 움직입니다

뱀의 위치(snake_x, snake_y)는 이미 있습니다.
이제 뱀이 어디로 움직일지 저장할 방향 변수를 만듭니다.

시작 방향은 오른쪽으로 합니다.

direction = "RIGHT"

또, 키를 눌렀을 때 바로 방향이 바뀌도록 “다음 방향”도 둡니다.

next_direction = direction

2) 방향키 입력을 받습니다

방향키를 누르면 next_direction을 바꿉니다.
그리고 즉시 유턴(반대 방향) 은 막습니다.

  • RIGHT 상태에서 LEFT로 바로 변경 ❌
  • LEFT 상태에서 RIGHT로 바로 변경 ❌
  • UP 상태에서 DOWN으로 바로 변경 ❌
  • DOWN 상태에서 UP으로 바로 변경 ❌

이걸 안 막으면, 몸이 생긴 뒤에 자폭 로직이 꼬입니다.

이벤트 루프 안에 아래 코드를 넣습니다.

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"

여기서 중요한 점은:

  • 키 입력은 next_direction만 바꿉니다
  • 실제 direction 적용은 “이동하기 직전”에 합니다

3) 한 칸 이동 로직을 만듭니다

이제 매 반복마다 뱀을 움직이면 너무 빨라집니다.
우리는 clock.tick(10)을 쓰고 있어서 초당 10번 루프가 도는 상태입니다.

그래서 “루프가 돌 때마다 이동”이 아니라, 이동 타이밍을 따로 관리합니다.

이동 카운터 만들기

루프 밖에 변수를 추가합니다.

move_delay = 1
move_counter = 0
  • move_counter는 루프가 몇 번 돌았는지 세는 값입니다
  • move_delay는 몇 번에 한 번 움직일지 정합니다
    (현재는 1로 두고, 이후 속도 조절 때 활용합니다)

이동은 루프 안에서 처리합니다

루프 안에서 카운터를 올리고, 조건이 맞으면 이동합니다.

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

이제 방향에 따라 좌표가 바뀌고, 화면에 그리는 부분이 그 좌표를 따라갑니다.


4) 지금 단계에서 발생하는 현상

현재는 “벽 충돌 처리”를 아직 안 했습니다.
그래서 뱀이 맵 밖으로 나가면 화면에서 사라집니다.

이건 정상입니다.
벽 충돌은 다음 강의(4강)에서 처리합니다.


3강 정리

이번 강의에서 배운 내용입니다.

  • 방향(direction)과 다음 방향(next_direction)을 나눕니다
  • 방향키 입력으로 next_direction을 바꿉니다
  • 반대 방향 전환을 막습니다
  • direction에 따라 snake_x, snake_y를 한 칸씩 변경합니다

전체 코드

더보기
import pygame
import sys

pygame.init()

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

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

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

clock = pygame.time.Clock()

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

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

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

# =========================
# 게임 루프
# =========================
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

    # 배경
    screen.fill(BLACK)

    # 격자 → 픽셀 변환
    pixel_x = snake_x * CELL_SIZE
    pixel_y = snake_y * CELL_SIZE

    # 뱀 머리 그리기
    snake_rect = pygame.Rect(pixel_x, pixel_y, CELL_SIZE, CELL_SIZE)
    pygame.draw.rect(screen, GREEN, snake_rect)

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

    # FPS
    clock.tick(10)

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

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

목차