본문 바로가기

Minding's Programming/Pygame

[Pygame] 02. 키보드로 조종하기

728x90
반응형

 

이 글은 아래에 있는 강의 영상을 보고 작성했다.

https://www.youtube.com/watch?v=QCKm6BK3IcE&list=PLz2iXe7EqJOMp5LozvYa0qca9E4OBkevW&index=2 

 


Pygame으로 게임 만들기 - 키보드로 조종하기

# pygame 임포트
import pygame
# pygame을 실행할때는 init(), 종료할때는 quit()을 꼭 적어줘야 함!
pygame.init()

#창 크기 지정
background = pygame.display.set_mode((480, 360))
#창 이름 지정
pygame.display.set_caption('PYGAME_1')

# boolean 함수를 생성해 while문 작성
play = True
while play:
    for event in pygame.event.get():
        if event.type == pygame.QUIT: #game의 event type이 QUIT 명령이라면
            play = False # while문을 종료시킴

pygame.quit()

기본적으로 pygame은 while문을 통해 게임이 실행되고, for문에서 event.get() 메소드를 통해 현재 상태를 파악한다.

현재 event.type이 어떤 상태이냐에 따른 반응을 if문을 통해 설정해줄 수 있다.

  • while문이 존재하지 않으면 display가 잠깐 실행되었다가 바로 꺼짐
  • quit(X 버튼)에 대한 명령이 따로 정해져있지 않아 '응답없음' 상태가 됨

Pygame의 event code 알아보기

# pygame을 실행할때는 init(), 종료할때는 quit()을 꼭 적어줘야 함!
pygame.init()

#창 크기 지정
background = pygame.display.set_mode((480, 360))
#창 이름 지정
pygame.display.set_caption('PYGAME_1')

# boolean 함수를 생성해 while문 작성
play = True
while play:
    for event in pygame.event.get():
        print(event.type) # event type을 출력시키면
        if event.type == pygame.QUIT: #game의 event type이 QUIT 명령이라면
            play = False # while문을 종료시킴

pygame.quit()

pygame의 event.type을 print()으로 출력시켜보자.

>>>
4352
4352
4352
4352
32774
32768
32785
770
32770
32776
32768
32783
...

키보드, 마우스 이동 등에 따라 수 많은 코드들이 출력된다.

Pygame은 각 연결 장치의 신호에 따라 고정된 코드가 출력되며, 해당 코드는 ASCII코드로 구성되어 있다.

print(pygame.K_0) # 0번키를 눌렀을때
print(pygame.K_DOWN) # 아래 방향키를 눌렀을 때

>>>
48
1073741905

이를 통해 아래와 같이 특정 키를 눌렀을 때 print()로 반응하게 만들 수도 있다.

# boolean 함수를 생성해 while문 작성
play = True
while play:
    for event in pygame.event.get():
        if event.type == pygame.QUIT: #game의 event type이 QUIT 명령이라면
            play = False # while문을 종료시킴
        if event.type == pygame.KEYDOWN: #game의 event type이 키보드를 누른 상태일 때
            if event.key == pygame.K_UP:
                print('UP')
            elif event.key == pygame.K_DOWN:
                print('DOWN')
            elif event.key == pygame.K_RIGHT:
                print('RIGHT')
            elif event.key == pygame.K_LEFT:
                print('LEFT')

pygame.quit()

>>>
DOWN
RIGHT
UP
LEFT
LEFT
  • 키 입력 메소드를 통해 ASCII 코드 외울 필요 없이 활용 가능하다. (pygame.K_UP과 같이)

Pygame 원 그려보기, 키보드로 원 조종하기

# pygame을 실행할때는 init(), 종료할때는 quit()을 꼭 적어줘야 함!
pygame.init()

#창 크기 지정
background = pygame.display.set_mode((480, 360))
#창 이름 지정
pygame.display.set_caption('PYGAME_1')

# 화면 가운데 부터 시작하도록 x, y 좌표 설정
x_pos = background.get_size()[0]//2 # 240
y_pos = background.get_size()[1]//2 # 180

# boolean 함수를 생성해 while문 작성
play = True
while play:
    for event in pygame.event.get():
        if event.type == pygame.QUIT: #game의 event type이 QUIT 명령이라면
            play = False # while문을 종료시킴
        if event.type == pygame.KEYDOWN: #game의 event type이 키보드를 누른 상태일 때
            if event.key == pygame.K_UP:
                print('UP')
                y_pos = y_pos - 10 # pygame에서는 위로 올라갈수록 y값이 감소한다.
            elif event.key == pygame.K_DOWN:
                print('DOWN')
                y_pos = y_pos + 10
            elif event.key == pygame.K_RIGHT:
                print('RIGHT')
                x_pos = x_pos + 10
            elif event.key == pygame.K_LEFT:
                print('LEFT')
                x_pos = x_pos - 10
                
    # 항상 배경 - 이미지(도형) 순으로 코드를 작성해야 함! (반대로 하면 이미지가 배경에 덮여버림)
    background.fill((255,255,255)) # 배경색 : 흰색
    pygame.draw.circle(background, (255,0,0), (x_pos, y_pos), 5) # 4개의 인자 순서대로 (위치, 색깔, 중심점, 반지름)
    pygame.display.update() # 현재 화면 상태를 업데이트

pygame.quit()

화면에 원을 그려주기 위해서 x, y 좌표값 변수인 x_pos, y_pos를 선언해주었다.

방향키를 누를 때마다 해당 좌표값이 변하도록 만들어 주었고, draw.circle()을 통해 원을 그릴 수 있다.

원의 위치가 바뀔 때마다 display.update()를 통해 화면을 업데이트해준다.

 

  • pygame은 중심점의 좌표가 (0,0)이 아닌, 왼쪽 가장자리가 (0,0)이다.
  • 즉, 왼쪽 가장자리로부터 오른쪽으로 갈수록 x좌표값 증가 / 아래쪽으로 갈수록 y좌표값이 증가한다.
  • 항상 배경 - 이미지(도형) 순으로 코드를 작성해야 함! (반대로 하면 이미지가 배경에 덮여버림)
  • display.update()를 해주지 않으면 화면이 바뀌지 않으니 주의
  • 위 코드에서는 방향키를 꾹 눌렀을때의 반응이 나타나지 않음. (끊어서 눌러줘야 함)

시연 영상


키보드 꾹 누른 상태 유지하기

그러나 위 코드에서는 우리가 즐기는 게임처럼 키보드가 꾹 놀려지지 않는 모습을 알 수 있다.

키보드가 눌러진 상태 그대로 화면에 반응하기 위해서는 아래와 같은 코드 수정이 필요하다.

# pygame을 실행할때는 init(), 종료할때는 quit()을 꼭 적어줘야 함!
pygame.init()

#창 크기 지정
background = pygame.display.set_mode((480, 360))
#창 이름 지정
pygame.display.set_caption('PYGAME_1')

# pygame 내장기능 통해 fps 지정
fps = pygame.time.Clock()

# 화면 가운데 부터 시작하도록 x, y 좌표 설정
x_pos = background.get_size()[0]//2 # 240
y_pos = background.get_size()[1]//2 # 180


to_x = 0
to_y = 0

# boolean 함수를 생성해 while문 작성
play = True
while play:
    deltatime = fps.tick(60) # fps 지정해주지 않으면 원이 너무 빨리 움직임
    for event in pygame.event.get():
        if event.type == pygame.QUIT: #game의 event type이 QUIT 명령이라면
            play = False # while문을 종료시킴
        if event.type == pygame.KEYDOWN: #game의 event type이 키보드를 누른 상태일 때
            if event.key == pygame.K_UP:
                to_y = -1 # 좌표를 직접 변화시키지 않고 변수에 저장해 두었다가
            elif event.key == pygame.K_DOWN:
                to_y = 1
            elif event.key == pygame.K_RIGHT:
                to_x = 1
            elif event.key == pygame.K_LEFT:
                to_x = -1
        if event.type == pygame.KEYUP:
            # 키 별로 변수값을 나눠 두 개의 방향키를 동시에 눌러도 문제 없도록 함
            if event.key == pygame.K_UP:
                to_y = 0
            elif event.key == pygame.K_DOWN:
                to_y = 0
            elif event.key == pygame.K_RIGHT:
                to_x = 0
            elif event.key == pygame.K_LEFT:
                to_x = 0
                
    # 변수 저장값을 좌표에 누적해주는 방식으로 접근
    x_pos += to_x
    y_pos += to_y
                
    # 항상 배경 - 이미지(도형) 순으로 코드를 작성해야 함! (반대로 하면 이미지가 배경에 덮여버림)
    background.fill((255,255,255)) # 배경색 : 흰색
    pygame.draw.circle(background, (255,0,0), (x_pos, y_pos), 5) # 4개의 인자 순서대로 (위치, 색깔, 중심점, 반지름)
    pygame.display.update() # 현재 화면 상태를 업데이트

pygame.quit()
  • 키보드가 눌릴때마다 좌표 반영해 원을 그리는 것이 아닌, 지속해서 좌표값을 업데이트 할 수 있도록 변수를 만들어줌
  • 각 방향키 별로 if문을 따로 작성해주어야 두 개의 방향키를 동시에 눌렀다가 하나만 떼어도 잘 반응함

시연 영상

 

위 영상과 달리 자연스럽게 원이 움직이는 모습을 볼 수 있다.

728x90