본문 바로가기

programming/pygame

[pygame] 파이썬으로 게임 만들기 - 스네이크

[pygame] 파이썬으로 게임 만들기 - 스네이크

 

안녕하세요. 심심한 코딩쟁이입니다.

 

오늘은 pygame을 활용해 스네이크 게임을 만들어보려고합니다.

 

고전게임 중 하나인 스네이크의 룰 또한 다들 아실테니 바로 만나보시죠.

 

pygame-logo
파이게임


스네이크 전체 코드

 

코드에 주석을 달아두었습니다.

 

이해를 위해 천천히 한줄 한줄 읽어보시기 바랍니다.

 

import pygame as pg
from random import randrange

# 랜덤한 위치 좌표를 반환해주는 함수
def get_random_position():
    return [randrange(*RANGE), randrange(*RANGE)]

WINDOW = 500
TILE_SIZE = 20

# randrange 에 들어가면 TILE_SIZE//2 부터 WINDOW - TILE_SIZE//2 바로 앞까지
# TILE_SIZE를 간격으로 난수가 반환됨
RANGE = (TILE_SIZE // 2, WINDOW - TILE_SIZE // 2, TILE_SIZE)

# 뱀 생성
snake = pg.rect.Rect([0, 0, TILE_SIZE - 2, TILE_SIZE - 2])
snake.center = get_random_position()
length = 1

# 뱀 꼬리 생성
tail = [snake.copy()]

# 뱀의 방향 설정
snake_dir = (0, 0)

# 게임 속도 조절을 위한 변수들
time, time_step = 0, 100

# 뱀이 먹을 음식
food = snake.copy()
food.center = get_random_position()

# 
screen = pg.display.set_mode([WINDOW] * 2)
clock = pg.time.Clock()

# 현재의 이동방향과 반대되는 방향으로 이동하지 못하도록 만들 딕셔너리
dont = {pg.K_w: 1, pg.K_s: 1, pg.K_a: 1, pg.K_d: 1}

while True:
    for event in pg.event.get():
        # 닫기 버튼 (X)를 누르면 종료됨
        if event.type == pg.QUIT:
            exit()
        # 키가 눌렸을 때 w,a,s,d 중 하나를 눌렀다면 뱀이 움직임
        if event.type == pg.KEYDOWN:
            # w를 아무리 눌러도 dont 딕셔너리의 값이 0일 경우(직전에 s를 눌렀음)에는 위로 못 움직임
            if event.key == pg.K_w and dont[pg.K_w]:
                snake_dir = (0, -TILE_SIZE)
                dont = {pg.K_w: 1, pg.K_s: 0, pg.K_a: 1, pg.K_d: 1}
            # s를 아무리 눌러도 dont 딕셔너리의 값이 0일 경우(직전에 w를 눌렀음)에는 위로 못 움직임
            if event.key == pg.K_s and dont[pg.K_s]:
                snake_dir = (0, TILE_SIZE)
                dont = {pg.K_w: 0, pg.K_s: 1, pg.K_a: 1, pg.K_d: 1}
            # a를 아무리 눌러도 dont 딕셔너리의 값이 0일 경우(직전에 d를 눌렀음)에는 위로 못 움직임
            if event.key == pg.K_a and dont[pg.K_a]:
                snake_dir = (-TILE_SIZE, 0)
                dont = {pg.K_w: 1, pg.K_s: 1, pg.K_a: 1, pg.K_d: 0}
            # d를 아무리 눌러도 dont 딕셔너리의 값이 0일 경우(직전에 a를 눌렀음)에는 위로 못 움직임
            if event.key == pg.K_d and dont[pg.K_d]:
                snake_dir = (TILE_SIZE, 0)
                dont = {pg.K_w: 1, pg.K_s: 1, pg.K_a: 0, pg.K_d: 1}
    
    # 화면을 검정색으로 채움
    screen.fill('black')
    
    # 뱀이 자기 몸에 닿는 경우에 True 값을 가짐
    self_eating = pg.Rect.collidelist(snake, tail[:-1]) != -1
    
    # 뱀이 맵을 넘어가거나 자기 자신의 몸에 닿을 경우 재시작
    if snake.left < 0 or snake.right > WINDOW or snake.top < 0 or snake.bottom > WINDOW or self_eating:
        snake.center, food.center = get_random_position(), get_random_position()
        length, snake_dir = 1, (0, 0)
        tail = [snake.copy()]
        dont = {pg.K_w: 1, pg.K_s: 1, pg.K_a: 1, pg.K_d: 1}
        time_step = 100
    
    # 뱀이 먹이를 먹었을 때 음식의 위치가 재배지되고 길이가 1 늘어남
    if snake.center == food.center:
        food.center = get_random_position()
        length += 1
        # 먹이를 먹을 수록 점점 게임속도가 빨라짐
        if time_step > 40:
            time_step -= 1
         
    # 음식 그려줌
    pg.draw.rect(screen, 'yellow', food)
    
    # 뱀 그려줌
    [pg.draw.rect(screen, 'green', body) for body in tail]
    
    # 게임의 속도 조절 및 뱀 꼬리가 길어지는 것을 확인하는 주기를 설정
    time_now = pg.time.get_ticks()
    
    if time_now - time > time_step:
        time = time_now
        snake.move_ip(snake_dir) # snake_dir은 벡터값이며 벡터값대로 이동
        tail.append(snake.copy())
        tail = tail[-length:]

    pg.display.flip()
    # flip()은 전체를 업데이트할 때 사용하고
    # update()는 특정 부분을 업데이트할 때 사용하는데 함수 안에 아무것도
    # 주어지지 않을 경우 전체를 업데이트함
    # 따라서 pg.display.update() 이렇게도 사용 가능함
    
    # fps 60으로 설정
    clock.tick(60)

실행 화면

 

게임을 실행한 모습입니다.

 

 

play
게임 실행 화면


게임 방법

 

우리가 평상시에 방향키로 많이 사용하는

 

w,a,s,d 키를 이용해 방향전환을 할 수 있습니다.

 

단, 위로 가다가 바로 아래로 가는 역동작은 불가능 합니다.


 

여기까지 파이썬으로 게임 만들기 스네이크 편이었습니다.

 

코드에 궁금하신부분이 있으시면 댓글로 남겨주세요. 성심성의껏 답변드리겠습니다.

 

다음에도 재미있는 게임을 구현해서 포스팅하도록 하겠습니다.

 

감사합니다.

 
 
반응형