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
'⚙️ Python > 🎮 Pygame 실전' 카테고리의 다른 글
| [Pygame] 🐍 스네이크 게임 만들기 6강 | 먹이 처리 + 점수 (0) | 2026.01.06 |
|---|---|
| [Pygame] 🐍 스네이크 게임 만들기 5강 | 먹이 생성하기 (랜덤위치) (0) | 2026.01.05 |
| [Pygame] 🐍 스네이크 게임 만들기 4강 | 벽 충돌 처리하기 (게임 오버) (0) | 2026.01.04 |
| [Pygame] 🐍 스네이크 게임 만들기 2강 | 뱀 머리 그리기 (격자 좌표 이해) (0) | 2026.01.02 |
| [Pygame] 🐍 스네이크 게임 만들기 1강 | 게임 창과 기본 루프 (0) | 2026.01.01 |