스네이크 게임

스네이크 게임 제작기 3

잡코신 2024. 3. 20. 18:00
728x90
반응형

지난 시간

지난번엔 스네이크 게임의 기본 로직을 완성했다.

이번엔 지난번에 만든 로직을 바탕으로 게임 처럼 만들것이다.

스네이크 게임 만들기

게임을 실행시키면 바로 지렁이가 이동하기 시작하여 바로 키를 이동해줘야 하게 게임 시작되어 불편했다.

if __name__ == "__main__":    
    game_over = True  # 게임 종료 
    game_started = False # 게임 시작 변수
    
    while True:  # 무한 루프
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_r:
                    # 'R' 키를 눌렀을 때 게임을 재시작
                    game_started = True
                    snake = Snake()
                    apple = Apple()
                    score = 0
                    game_over = False  # 게임 종료 상태 해제
                elif event.key == pygame.K_UP:
                    snake.change_direction('up')
                elif event.key == pygame.K_DOWN:
                    snake.change_direction('down')
                elif event.key == pygame.K_LEFT:
                    snake.change_direction('left')
                elif event.key == pygame.K_RIGHT:
                    snake.change_direction('right')

 

 

구분하기 쉽게 메인을 만들어주고 R키를 눌렀을 때 게임이 시작되게 한다.

저번엔 화살표밖에 사용하지 않아서 넘어갔지만 다양한 키를 사용해야하기에

pygame의 event.type과 event.key에 대해 알아보도록 하겠다.

Event Type 동작 specific attributes
QUIT 윈도우의 x 버튼, 창 닫기 버튼 눌림 none
ACTIVEEVENT 마우스가 화면에 들어가거나 나가면 발생


gain : 0 - 마우스가 화면에 들어올때
gain : 1 - 마우스가 화면에서 나갔을 때


state : 1 - 창이 활성화
state : 2 - 창이 비활성화
state : 6 - 비활성화된 창이 활성화 될때
gain, state
KEYDOWN 키가 눌렸을 때 key, mod, unicode, scancode
KEYUP 키가 올라갔을 때 key, mod
MOUSEMOTION 마우스 움직일때 pos, rel, buttons
MOUSEBUTTONUP 마우스 버튼 뗄 때 pos, button
MOUSEBUTTONDOWN 마우스 버튼 눌렀을 때 pos, button
JOYAXISMOTION 조이스틱 축이 변경될 때 joy, axis, value
JOYBALLMOTION 조이스틱 볼이 움직일 때 joy, ball, rel
JOYHATMOTION 조이스틱 hat이 변경될 때 joy, hat, value
JOYBUTTONUP 조이스틱 버튼 뗄 때 joy, button
JOYBUTTONDOWN 조이스틱 버튼 눌렀을 때 joy, button
VIDEORESIZE pygame.display.set_mode(size, mode)에서 mode를 pygame.RESIZABLE 일 경우.
윈도우 창 크기 변경 될 때
size, w, h
VIDEOEXPOSE 화면에 직접 그리는 하드웨어 디스플레이는 창의 일부를 다시 그려야 할 때 pygame.VIDEOEXPOSE 이벤트를 받음 none
USEREVENT 사용자 설정 이벤트 code

위 표가 대략적인 event.type들이다. 

Event Key 동작
K_숫자 키보드 자판 위의 숫자
K_알파벳 키보드 자판 알파벳
K_F숫자 키보드 숫자 위 Function
K_KP숫자, K_KP_숫 키보드 옆 키패트 숫자
K_ + SPACE, TAB, RCTRL, LCTRL...등 기타 특수 키

위 표가 대략적인 event.key 들이다.

 

다른 키나 타입을 보고 싶다면

이렇게 constants.pyi 파일로 넘어가면 모든걸 볼 수 있다.

	if not game_over:
            # 게임 로직 처리
        else:
            # R키를 누르면 재시작 메세지 화면에 배치
            font = pygame.font.Font(None, 36)
            text_restart = font.render("Press 'R' to Start", True, GREEN)
            text_restart_rect = text_restart.get_rect(center=(screen_width // 2, screen_height // 2 - 50))
            screen.blit(text_restart, text_restart_rect)

            # 게임 시작 상태일 때 화면에 "Game Over" 메시지와 사과를 먹은 개수 출력
            if game_started:
                text_game_over = font.render("Game Over", True, RED)
                text_game_over_rect = text_game_over.get_rect(center=(screen_width // 2, screen_height // 2 + 50))
                screen.blit(text_game_over, text_game_over_rect)

                text_score = font.render("Score: {}".format(score), True, GREEN)
                text_score_rect = text_score.get_rect(center=(screen_width // 2, screen_height // 2))
                screen.blit(text_score, text_score_rect)

R키를 누르면 시작한다는 문구를 넣어준다.

그리고 게임오버했을 때 게임오버 메세지와 먹은 사과 개수인 score을 표시해준다.

 

스네이크 게임(ver.3) 플레이하기

import pygame
import random
import sys

# 색깔 상수 정의
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
RED = (255, 0, 0)

# 게임 화면 크기 설정
screen_width = 800
screen_height = 600
cell_size = 20

# 지렁이 클래스 정의
class Snake:
    def __init__(self):
        self.segments = [
            (screen_width // 2, screen_height // 2),
            (screen_width // 2 - cell_size, screen_height // 2),
            (screen_width // 2 - 2 * cell_size, screen_height // 2)
        ]
        self.direction = random.choice(['up', 'down', 'left', 'right'])
        self.grow = False  # 사과를 먹으면 True로 설정하여 몸이 늘어나도록 함

    def move(self):
        x, y = self.segments[0]
        if self.direction == 'up':
            y -= cell_size
        elif self.direction == 'down':
            y += cell_size
        elif self.direction == 'left':
            x -= cell_size
        elif self.direction == 'right':
            x += cell_size
        self.segments.insert(0, (x, y))
        if not self.grow:  # grow가 False일 때는 꼬리를 제거하여 몸이 늘어나지 않도록 함
            self.segments.pop()
        else:
            self.grow = False

    def change_direction(self, direction):
        if direction == 'up' and self.direction != 'down':
            self.direction = 'up'
        elif direction == 'down' and self.direction != 'up':
            self.direction = 'down'
        elif direction == 'left' and self.direction != 'right':
            self.direction = 'left'
        elif direction == 'right' and self.direction != 'left':
            self.direction = 'right'

    def draw(self, screen):
        for segment in self.segments:
            pygame.draw.rect(screen, GREEN, (segment[0], segment[1], cell_size, cell_size))

# 사과 클래스 정의
class Apple:
    def __init__(self):
        self.position = (random.randint(0, screen_width // cell_size - 1) * cell_size,
                         random.randint(0, screen_height // cell_size - 1) * cell_size)

    def draw(self, screen):
        pygame.draw.rect(screen, RED, (self.position[0], self.position[1], cell_size, cell_size))

if __name__ == "__main__":
    # 게임 초기화
    pygame.init()
    screen = pygame.display.set_mode((screen_width, screen_height))
    pygame.display.set_caption("지렁이 게임")

    clock = pygame.time.Clock()

    snake = Snake()
    apple = Apple()

    score = 0

    # 게임 루프
    game_over = True  # 게임 종료 
    game_started = False # 게임 시작 변수

    while True:  # 무한 루프
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_r:
                    game_started = True
                    snake = Snake()
                    apple = Apple()
                    score = 0
                    game_over = False  # 게임 종료 상태 해제
                elif event.key == pygame.K_UP:
                    snake.change_direction('up')
                elif event.key == pygame.K_DOWN:
                    snake.change_direction('down')
                elif event.key == pygame.K_LEFT:
                    snake.change_direction('left')
                elif event.key == pygame.K_RIGHT:
                    snake.change_direction('right')

        if not game_over:
            # 게임 로직 처리

            if (snake.segments[0][0] < 0 or snake.segments[0][0] >= screen_width or
                    snake.segments[0][1] < 0 or snake.segments[0][1] >= screen_height or
                    snake.segments[0] in snake.segments[1:]):
                # 게임 오버 조건
                game_over = True

            snake.move()

            if snake.segments[0] == apple.position:
                score += 1
                apple = Apple()
                snake.grow = True  # 사과를 먹으면 grow를 True로 설정하여 몸이 늘어나도록 함

            screen.fill(BLACK)

            snake.draw(screen)
            apple.draw(screen)
        else:
            # R키를 누르면 재시작
            font = pygame.font.Font(None, 36)
            text_restart = font.render("Press 'R' to Start", True, GREEN)
            text_restart_rect = text_restart.get_rect(center=(screen_width // 2, screen_height // 2 - 50))
            screen.blit(text_restart, text_restart_rect)

            # 게임 시작 상태일 때 화면에 "Game Over" 메시지와 사과를 먹은 개수 출력
            if game_started:
                text_game_over = font.render("Game Over", True, RED)
                text_game_over_rect = text_game_over.get_rect(center=(screen_width // 2, screen_height // 2 + 50))
                screen.blit(text_game_over, text_game_over_rect)

                text_score = font.render("Score: {}".format(score), True, GREEN)
                text_score_rect = text_score.get_rect(center=(screen_width // 2, screen_height // 2))
                screen.blit(text_score, text_score_rect)

        pygame.display.flip()
        clock.tick(10)

    pygame.quit()

최종 코드이다. 이제 실행시켜보자.

시작화면
게임 오버 화면

이제 언제든 r를 누르면 재시작 되고 스코어를 보여주는 게임오버화면이 존재하는 스네이크 게임이 완성됐다.

 

Next

이제 게임이 완성되었으니 완성도를 높여보겠다.

728x90
반응형

'스네이크 게임' 카테고리의 다른 글

스네이크 게임 제작기 4  (0) 2024.04.10
스네이크 게임 제작기 2  (0) 2024.03.13
스네이크 게임 제작기 1  (1) 2024.03.06