plitri

검색어 '학습'로 9개의 글을 찾았습니다.

  1. 2017.09.01 [Godot RPG] 3. 플레이어 움직이기 
  2. 2017.08.25 [Godot RPG] 2-Extra. 인스펙터에서 알아보는 상속 
  3. 2017.08.25 [Godot RPG] 2. 씬, 플레이어 추가 
  4. 2017.08.24 [Godot RPG] 1. 설치 및 프로젝트 생성 
  5. 2017.08.22 [Godot RPG] 0. 서문 
  6. 2017.08.21 [Godot] 루프에서 wait 함수 사용하기 
  7. 2017.03.11 [Godot] GUI를 카메라에 영향받지 않도록 하기 
  8. 2017.03.11 [Godot] C2의 scale-in 구현 (반응형) 
  9. 2017.03.10 [Godot] Patch9Frame 

[Godot RPG] 3. 플레이어 움직이기

본 글은 연작입니다.


  • ← 이전 글
  • 이 글은… ..헉…헉… 1, 2번 동영상에 해당합니다? 아마도요.

이번에는 플레이어를 움직여봅시다. 플레이어를 움직이려면 플레이어 노드에 스크립트를 붙여야 합니다.

고도 엔진에서의 게임 동작은 모두 스크립트로 작성합니다. 고도 엔진의 스크립트는 자체 언어인 GDScript로 작성합니다. [각주:1]

먼저 플레이어에 스크립트를 주가해봅시다.

노드에 스크립트 붙이기

  1. 플레이어 노드에 마우스 우클릭하여 스크립트 붙이기를 선택합니다.

  1. 일단은 game/scene/start_room/player.gd 에 생성[각주:2]합시다.

  • 나머지 부분은 진행하면서 차차 이해하실 것 같으니 넘어가겠습니다.
  • 내장 스크립트 를 선택하면 (아마도) 씬 파일 (이 경우 start_room.tscn) 에 스크립트가 같이 저장됩니다. 외부 편집기에서 열기 어려우므로 왠만하면 체크하지 않습니다.

기본 코드 살펴보기

스크립트를 생성하면 자동으로 편집기가 스크립트 화면으로 바뀔 것입니다.

화면을 살펴봅시다.

  • Script 모드로 편집기가 바뀌어있으며 (위쪽),
  • 열린 파일은 player.gd 입니다. (왼쪽). 또한
  • 가운데에 편집할 스크립트가 열려있습니다. 기본적인 내용이 들어있네요.

무슨 내용인지 한 줄 한 줄씩 살펴봅시다.

01: extends KinematicBody2D

KinematicBody2D의 기능을 확장(extends) 합니다. 이 문장이 있으면 이 스크립트에서 KinematicBody2D의 기능을 사용할 수 있습니다.

extends 는 GDScript에서 미리 정해진 단어입니다. 이러한 단어는 다른 용도로 사용할 수 없으니 주의합시다.[각주:3]

03~05: # 주석

#로 시작하는 줄은 주석입니다. 어디든지 # 를 붙이면 그 오른쪽은 모두 프로그램이 아니라 메모가 됩니다. 좋은 프로그래머라면 미래의 자신과 팀원을 위해 주석을 신경써서 달겠죠?

07: func _ready():

_ready 라는 이름의 함수 (function의 func 입니다.) 를 만들었습니다. 함수는 일련의 프로그램을 하나의 덩어리로 묶어둔 것입니다.

이런 함수가 있다! 라고 정의할 때는 func 함수이름(건네줄 값들) 로 정의하고, 함수를 실행해줘! 할 때에는 함수이름(건네줄 값들)` 과 같이 씁니다. 실제로 써보면 알기 쉽겠죠. 바로 다음 섹션에서 해보겠습니다.

_ready 라는 함수는 미리 엔진에서 정의한 함수인데요[각주:4], 자세한 내용은 코드를 작성하면서 알아보겠습니다.

08: pass

아무것도 안 합니다! 사실 이 pass 구문은 위의 func _ready() 에서 실행할 부분입니다. 앞에 들여쓰기가 보이시나요? GDScript는 프로그램에 영역을 지정하기 위해 들여쓰기를 씁니다! 들여쓰기에 항상 조심합시다.

pass는 들여쓰기를 통해 구역을 만들 필요가 있는 곳을 임시로 메꿔놓기 위해 사용됩니다.

Hello World!

func _ready(): 의 본문에 print("안녕 세상아!") 라고 써봅시다.

혹시 들여쓰기를 하지 않았거나

오른쪽 괄호를 빼먹은 등

코드에 문제가 있다면 빨간색으로 표시되고 편집기 아래에 에러 메시지가 나오니 잘 살펴봅시다.


이렇게 작성하면 플레이어를 초기화할 때 아래 출력란에 안녕 세상아! 를 출력하게 됩니다. 한 번 실행해볼까요?

어떻게 이렇게 되는걸까요?

먼저 _ready 함수는 (플레이어) 노드가 씬에 삽입되어 준비가 완료되었을 때 엔진이 실행(호출)해줍니다. 처음에 호출되는 함수라 이 함수에는 보통 이 노드의 초기화 작업을 써넣게 됩니다.

게임이 실행되고 플레이어가 준비되면 _ready 함수의 본문인 print("안녕 세상아!") 가 실행되겠죠?

  • 함수를 실행할 때에는 func을 적지 않고, 함수를 만들 때는 func을 적습니다.
  • print 함수는 출력 화면에 전달해준 값을 출력하는 함수입니다.
  • 전달해준 값은 문자열 "안녕 세상아!" 입니다. GDScript에서 프로그램 코드가 아닌 문자임을 나타낼 때에는 원하는 내용을 쌍따옴표 " 로 둘러쌉니다.

GDScript를 써보는 건 충분히 했으니 이제 드디어 플레이어를 움직여봅시다. 아직 좀 더 해야할 일이 남았어요.

set_process() 함수

플레이어가 준비가 되었을 때 단 한 번만 움직이지는 않을겁니다. 게임이 진행되면서 플레이어가 지속적으로 움직이려면 엔진에게 플레이어 스크립트를 처리해달라고 요청해야합니다. 그런 요청을 하는 함수가 set_process 입니다.

_ready 함수의 본문 마지막줄에 set_process(true)를 입력합니다.

위와 마찬가지로 들여쓰기가 _ready 함수의 다른 코드와 다르거나 코드에 문제가 있으면 에러가 날 겁니다. 잘 읽어보고 수정합시다.

set_process(true) 라는 문장은 set_process라는 함수를 호출하되, true라는 값을 건네주어 실행합니다. 이 함수가 true, 즉 “참” 값으로 호출되면 고도 엔진은 이 스크립트를 처리하기 시작할 겁니다. false를 건네주어 실행하면 더 이상 처리하지 않겠죠.

어떻게 처리하냐구요? 구체적으로는 이 후로 엔진이 _process 라는 함수를 매 번 자동으로 실행해줍니다.

func _process(delta) 함수 만들기

_ready 함수 밑에 _process라는 함수를 만들어봅시다. 아래와 같이 써주세요.

delta가 뭔지는 나중에 설명하겠습니다. 함수를 정의할 때 괄호 안에 원하는 이름을 적으면 그 이름으로 호출할 때 건네준 값을 받아올 수 있습니다. delta 로는 이전에 _process 함수를 호출했을 때와 지금 호출할 때의 시간 간격을 건네받습니다. ← 이 부분은 다음에 써먹을겁니다. 임시로…

혹시 콜론 : 기호를 빼먹지 않았나요? GDScript에서는 새로운 영역을 만들 때 항상 콜론 : 기호를 씁니다. : 아래에서는 같은 영역이라면 항상 한 단계 더 들여씁니다. 이러한 영역을 프로그래밍 용어로는 블록(block) 이라고 부릅니다.

빼먹으니까 에러가 나죠.

이제 pass 부분에도 코드를 작성해봅시다. _process 함수의 내용에 나는 매 번 실행되는 내용이다! 라고 출력하는 코드를 작성해볼까요? 직접 해보세요!

3…

2…

1…

이렇게 했으면 정답입니다. 아, pass는 지워도 돼요. 여기서 print는 실행한 함수 이름이고 괄호 안의 값은 print를 실행하면서 건네준 값이죠.

현재까지의 코드는 이렇습니다. 슬슬 저장할 때가 되었군요. 스크립트는 Ctrl + Alt + S 로 저장합니다. 그냥 Ctrl + S 를 누르면 현재 열린 씬까지 모조리 저장하니 주의합시다.

플레이어를 움직이려면 어떻게 해야할까?

드디어 플레이어를 매 번 조금씩 움직일 토대를 마련했습니다. _process 함수의 내용에 조금씩 움직이는 코드를 적으면 될텐데, 어떻게 하면 될까요?

무언가를 움직일 때는 기본적으로 이런 순서로 합니다.

  1. 플레이어의 현재 위치를 가져옵니다. 함수 이름: get_pos() (건네줄 값 없음)
  2. 플레이어를 조금 움직입니다.
  3. 플레이어의 위치를 새 위치로 지정합니다. 함수 이름: set_pos( position ) (지정할 새 위치를 건네줌)

근데 가져온 값을 어떻게 보관하죠?

변수

변수(variable) 는 어떤 값을 어떤 이름으로 저장할 때 씁니다. 파일에 저장하는 게 아니고, 임시로 담아두기 위해서 씁니다.

변수는 var 변수이름[각주:5] 으로 만듭니다. _process 함수의 내용을 지우고 pos[각주:6]라는 이름의 변수를 만들어볼까요?

이 변수에는 값을 집어넣거나 (대입한다고 합니다) 가져올 수 있습니다 (참조한다고 합니다.)

지금은 get_pos() 함수를 실행해서 현재 위치를 받아와볼까요?

값을 집어넣을 때에는 = 기호를 씁니다. 오른쪽의 값을 왼쪽에 집어넣죠. get_pos()는 실행하면 현재 위치를 돌려줍니다.

혹시 아래에도 var를 썼나요? 이미 한 번 var로 만든 변수니까 다시 var를 쓰면 두 번 만드는 게 되니까 논리적으로 문제가 있습니다.

변수를 만들면서 동시에 값을 넣어도 됩니다. 다만 이후 변수를 사용하거나 다른 값을 넣을때는 다시 var 로 만들면 안 되겠죠?

y 위치만 바꾸기

이제 pos에는 get_pos()를 호출해서 받아온 현재 위치값이 들어있습니다. 현재 위치는 x, y로 나타내죠. 이번엔 위아래 방향인 y 좌표만 바꿔볼까요?

값의 세부 정보를 받아오고 설정할 때는 점 . 기호를 사용합니다. pos에 들어있는 좌표는 x, y 로 구성되므로, pos의 y 좌표를 받아오거나 바꾸려면 pos.y 처럼 써야 합니다.

pos.y 를 하나 증가시켜볼까요. pos.y를 읽어와 1을 더한 뒤 위에서 배운 = 기호로 다시 집어넣으면 됩니다.

만약 변수 pos에 들어있는 값이 (0, 10) 이었다면 이 코드가 실행된 이후에는 (0, 11) 이 될 것입니다.

이제 새 위치로 옮겨볼까요. set_pos 함수를 호출하되 변수 pos 의 값을 건네주면 됩니다. 건네줄 때에는 그냥 변수의 이름을 괄호안에 쓰면 됩니다.

이제 매 번 플레이어의 y 좌표가 1씩 증가할 겁니다. 위로 갈까요, 아니면 아래로 갈까요?

고도 엔진의 좌표제쳬

아래로 갑니다!!!

고도 엔진에서 x, y 좌표는 오른쪽이 +x, 아래쪽이 +y입니다. 일반적인 그래픽 프로그램에서도 이러니까 별 문제될 건 없겠죠?


다음에는 쉬어가는… 의미에서… 플레이어를 다른 폴더에 저장해보겠습니다. 계속 코딩 기초를 하긴 무리인 것 같아요.

쉽게쉽게 쉽게쉽게를 모토로 쓰다보니 프로그래밍도 아예 모른다고 가정을 해버렸습니다. 그 결과 설명이 너무 힘들어졌네요 ㅠㅠ 노오력이 해결해주겠죠 뭐,,,


  • 다음 글 → 은 아직 없습니다. 한 주 바빠서 손 못 댔는데 가능하면 17일까지는...