이전 2개의 포스팅을 통해 게임 화면은 구성했고,
우리가 원하는대로 별주부를 움직여보는 코드를 구성할 예정이다.
이전 포스팅에서 while 문 안에 있는 pygame.event.get() 를 통해
키보드나 마우스의 움직임을 입력 받을 수 있다고 하였는데,
2024.02.03 - [Python/pygame] - python 게임만들기 - 기초 작업
python 게임만들기 - 기초 작업
앞선 포스팅에서 간략히 소개한 내용과 같이 python에는 게임을 만들기에 유용한 pygame 이라는 좋은 모듈이 있다. 그런데 아무리 좋은 모듈도 사용법을 모르면 쓸모가 없는 법. 하나씩 우리가 원하
to-all-rounder.tistory.com
while 문 안에 키보드 입력을 확인하는 코드를 추가해 보자.
1. 키보드 입력
- 일반적으로 키보드 같은 버튼을 우리는 누른다고 생각한다.
(나중에 추가 설명을 하겠지만, 누르는 것과 눌렀다가 떼는 것은 엄연히 다른 행동(event)이다.)
- 그런 키보드를 누르는 이벤트를 확인하는 것이 오늘의 포스팅 목적이다.
- 아래와 같이 for 반복문 으로 event.type 가 키보드를 누른 상태인지 확인을 하고,
입력된 event.key 가 키보드의 위쪽 화살표 이면 별주부의 세로 위치 값(turtle_pos_y) 을 1 픽셀씩 감소한다.
- 아래쪽 화살표도 동일하게 적용한 뒤, 변경된 사항을 pygame 화면(surface) 에 적용해 주기 위해 pygame.display.update() 를 진행해 주면 캐릭터가 움직이게 된다.
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
turtle_pos_y -= 1
if event.key == pygame.K_DOWN:
turtle_pos_y += 1
background.blit(turtle_img, (turtle_pos_x, turtle_pos_y))
pygame.display.update()
- 그런데 이렇게 입력하게 되면 생각지 못한 장애가 2가지 발생하는데,
1) 이동할 때 마다 배경이 뭉게진다는 것과
2) 키보드를 누를 때에는 적용이 되는데, 화살표를 계속 누르고 있을 때 위치가 반영이 되지 않는 것이다.
2. 코드 수정하기
- 위의 2가지 증상을 처리하기 위한 방법을 찾아보면
1) 계속 누르면 이동하기
- 해당 증상은 생각보다 쉽게 수정할 수 있다.
- 이동한 별주부의 위치를 반영하기 전 배경화면을 먼저 그려주면 된다.
- 배경 이미지를 blit 해주는 한 줄의 코드 추가만으로 해당 내용은 처리되며,
이동을 하더라도 검은 잔상과 같은 이미지가 남지 않게 된다.
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
turtle_pos_y -= 1
if event.key == pygame.K_DOWN:
turtle_pos_y += 1
# 화면 갱신 하기
background.blit(background_img_resize,(0,0))
background.blit(turtle_img, (turtle_pos_x, turtle_pos_y))
pygame.display.update()
2) 연속적으로 위치 이동하기
- 키보드를 누르고 있을 때 계속 위치의 변화를 주기 위해 캐릭터의 위치 값에 event를 바로 적용시키는 대신
이동과 관련된 새로운 변수를 선언한다.
running = True # 동작 상태
to_x = 0
to_y = 0
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# 키보드에서 입력을 할 때
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
to_y -= 1
if event.key == pygame.K_DOWN:
to_y += 1
# 키보드에서 입력을 멈췄을 때
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP:
to_y = 0
if event.key == pygame.K_DOWN:
to_y = 0
# 캐릭터 이동
turtle_pos_x += to_x
turtle_pos_y += to_y
# 화면 갱신 하기
background.blit(background_img_resize,(0,0))
background.blit(turtle_img, (turtle_pos_x, turtle_pos_y))
pygame.display.update()
- 서두에 사람들이 키보드를 누른다고만 잘못 생각한다고 말한 부분이 있듯이
실제는 키보드는 누르는 동작(KEYDOWN) 과 키보드를 떼는 동작(KEYUP)이 있다.
(주황색 영역과 노란색 영역)
- 이 두가지를 분리하여 키보드를 누를 때에는 가로 또는 세로로 이동을 할 to_x, to_y 변수 값을 변경하고,
키보드에서 손을 떼게되면 to_y를 다시 0으로 초기화한다.(초록색 영역)
- 해당 기능을 추가하면 이제 키보드를 누르고 있어도 자연스럽게 별주부가 연속으로 움직이는 것을 확인할 수 있는데,
이제 가로로 이동할 수 있도록 K_LEFT와 K_RIGHT가 포함한 전체 코드를 작성해보면 아래와 같다.
3. 완성 코드 (+FPS 설정)
import pygame
pygame.init()
SCREEN_WIDTH = 1024
SCREEN_HEIGHT = 780
background = pygame.display.set_mode((SCREEN_WIDTH,SCREEN_HEIGHT))
pygame.display.set_caption('Exciting Pygame by ToAllrounder')
# 배경 화면 나타내기
background_img = pygame.image.load(r'image/sea_backgound.png')
#print(f'backgound_img.get_size() 값 : {background_img.get_size()}')
#print(f'backgound_img.get_rect() 값 : {background_img.get_rect()}')
background_img_resize = pygame.transform.scale(background_img,(SCREEN_WIDTH, SCREEN_HEIGHT))
background.blit(background_img_resize,(0,0))
# pygame.display.update() # 별주부 추가 후 update를 위해 생략
# 별주부 추가하기
turtle_img = pygame.image.load(r'image/rabbit_turtle.png')
#print(f'turtle_img.get_size() 값 : {turtle_img.get_size()}')
#print(f'turtle_img.get_rect() 값 : {turtle_img.get_rect()}')
turtle_pos_x = SCREEN_WIDTH / 2 - turtle_img.get_size()[0] / 2
turtle_pos_y = SCREEN_HEIGHT / 2 - turtle_img.get_size()[1] / 2
background.blit(turtle_img, (turtle_pos_x, turtle_pos_y))
# pygame.display.update() # 상어 추가 후 update를 위해 생략
# 상어 추가하기
shark_img = pygame.image.load(r'image/shark.png')
shark_pos_x = SCREEN_WIDTH - shark_img.get_size()[0] / 4
shark_pos_y = SCREEN_HEIGHT / 4 - shark_img.get_size()[1] / 2
background.blit(shark_img, (shark_pos_x, shark_pos_y))
pygame.display.update()
running = True # 동작 상태
to_x = 0
to_y = 0
fps = pygame.time.Clock()
while running:
set_fps = fps.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# 키보드에서 입력을 할 때
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
to_y -= 1
if event.key == pygame.K_DOWN:
to_y += 1
if event.key == pygame.K_LEFT:
to_x -= 1
if event.key == pygame.K_RIGHT:
to_x += 1
# 키보드에서 입력을 멈췄을 때
if event.type == pygame.KEYUP:
if event.key == pygame.K_UP:
to_y = 0
if event.key == pygame.K_DOWN:
to_y = 0
if event.key == pygame.K_LEFT:
to_x = 0
if event.key == pygame.K_RIGHT:
to_x = 0
# 캐릭터 이동
turtle_pos_x += to_x * set_fps
turtle_pos_y += to_y * set_fps
# 화면 갱신 하기
background.blit(background_img_resize,(0,0))
background.blit(turtle_img, (turtle_pos_x, turtle_pos_y))
pygame.display.update()
pygame.quit()
- 코드를 작성하고 난 뒤 조작을 해봤더니 정상적으로 움직이지만...조작에 대한 답답함이 있었다.
- 그리고 추가로 fps 를 설정해주었는데, fps는 frame per second 의 약자로 1초당 몇개의 frame(화면)을 보여줄지를 설정하는 값이다.
- 애니메이션이나 영화, 게임 등에서 자주 접해본 단어일텐데, 해당 값이 높을수록 더 자연스러운 움직임이 가능하다.
- 우리는 pygame.time.Clock()를 통해 fps.tick(60) 을 설정하여 60 fps를 지정하고,
해당 동작이 캐릭터의 움직임과 연동될 수 있도록 해당 값을 곱해주었다.
(속도를 조절하는 기능 외에도 컴퓨터 간의 기본 fps가 다를 경우 게임의 속도가 차이날 수 있으나, fps.tick()을 고정함으로써 어떤 컴퓨터에서는 동일한 속도로 동작하게 되었다.)
'Python > pygame' 카테고리의 다른 글
02-python 게임 만들기-이미지 불러오기 (1) | 2024.02.06 |
---|---|
01-python 게임 만들기 - 시작(콘티) (0) | 2024.02.05 |
python 게임만들기 - 기초 작업 (0) | 2024.02.03 |
게임만들기-오프닝(베스킨라빈스 게임) (0) | 2024.02.01 |