본문 바로가기

게임개발/Defold

[Defold 튜토리얼] 2. Walking astronaut

 

이번 튜토리얼은 Walking astronaut이다.

 

 

 

 

프로젝트를 생성하고 빌드(Ctrl+B)하여 게임을 실행해보면

캐릭터가 하나 나오는데 키입력을 해도 아직 아무 작동도 하지 않는다.

 

 

 

 

에디터에서 main폴더 안에 main.collection 을 더블클릭해서 연다.

 

 

 

 

main.collection은 게임이 처음 실행될때 로딩되는 컬렉션이며,

이를 부트스트랩 컬렉션이라 한다. (game.project 파일을 열어 보면 확인할 수 있다.)

특정 컬렉션을 부트스트랩으로 설정해놓으면 게임을 처음 실행했을때

첫 화면으로 해당 컬렉션의 오브젝트들을 보게된다.

 

 

 

 

현재 main.collection은 두개의 게임오브젝트(astronout, level)를 포함하고 있으며,

각 게임오브젝트들은 각각의 컴포넌트들을 포함하고 있다.

 

이런 각 객체들은 원본 파일을 가지고 있는 것과 없는것으로 구분된다.

Outline 뷰를 보면 원본 파일을 가진 객체들은 이탤릭체로 표시된다는 것을 알 수 있다.

 

 

 

 

그리고 원본 파일을 가진 객체들은 각 이름 옆에 파일의 경로가 표시된다.

astronaut 게임오브젝트는 main 폴더에 astronaut.go 파일과 연결되어있고,

level 타일맵 컴포넌트는 main 폴더에 level.tilmap 파일에 연결되어 있다.

 

여기서 level 게임오브젝트는 원본 파일을 가지고 있지 않은데,

그렇다고 원본 파일을 가진 객체들과 별 다른 차이가 있는 것은 아니다.

원본 파일을 가진 객체들은 단지 원본 파일이 수정되면 다같이 한번에 수정된다는 편리함이 있을 뿐이다.

(유니티의 프리팹과 같다고 보면 될것 같다.)

 

따라서 astronaut 게임오브젝트를 수정하기위해서는 main폴더 안에 astronout.go 파일을 수정해야한다.

그럼 astronout.go 파일을 더블클릭해서 연다.

 

 

 

 

astronaut.go 파일의 게임오브젝트에는 astronout 스크립트와 sprite 컴포넌트가 있다.

sprite 컴포넌트를 선택해보면 Properties 뷰에서 Image와 Default Animation을 확인할 수 있는데,

Image는 main/astronaut.atlas 파일로 설정되어 있고, Animation은 idle로 설정되어 있다.

 

현재 astronaut 게임오브젝트가 가진 애니메이션이 idle 하나뿐인지라, 다른 애니메이션들을 추가할 필요가 있다.

디폴드 엔진에서 애니메이션은 아틀라스(Atlas) 파일에서 관리한다.

따라서 애니메이션을 추가하기위해 main 폴더 안에 astronaut.atlas 파일을 연다.

 

 

 

 

astronout.atlas를 열어보면 idle 애니메이션 컴포넌트가 들어가 있는 것을 확인할 수 있다.

그리고 그 밑에는 idle 애니메이션에서 사용되는 이미지들이 포함되어 있다.

 

idle 애니메이션 컴포넌트를 선택하고 Space 바를 누르거나 View -> Play를 클릭하면

애니메이션이 플레이 되는것을 볼 수 있다.  (플레이중 Space바를 다시 누르면 멈춘다.)

 

 

 

 

이제 새로운 애니메이션을 추가하기 위해

Outline 뷰에서 Atlas 오브젝트를 우클릭하고, Add Animation Group을 클릭한다.

 

 

 

 

처음 생성된 애니메이션 그룹은 "New Animation"이라고 이름이 표기되는데,

Properties 뷰에서 Id를 "left"로 변경한다.

그리고 left 오브젝트를 우클릭하고, Add Images 를 클릭하여 애니메이션에 사용될 이미지를 추가한다.

 

 

 

 

Select Images 창이 뜨면 필터칸에 "left"라고 입력하고

left01~left_06 이미지들을 전부 선택한뒤 Ok 버튼을 클릭한다.

 

 

 

 

이제 Atlas 화면을 보면 idle 이미지들에 더하여 left 이미지들이 추가된 것을 확인할 수 있다.

left 애니메이션을 선택하고 space바를 눌러 애니메이션을 플레이 해본다.

 

 

 

 

애니메이션의 Fps가 60으로 잡혀있어 (1초당 60프레임씩 돌아가므로) 애니메이션이 너무 빠르다.

Properties 뷰에서 Fps를 15로 낮춘다.

 

지금까지 left를 추가했던것처럼 right, front, back 애니메이션도 추가한다.

 

 

 

 

다시 astronaut 게임오브젝트로 돌아가서 sprite 컴포넌트를 보면

Default Animation에 left, right, front, back이 추가된 것을 확인할 수 있다.

 

 

 

 

이제 GameObject 하위에 연결된 astronout.script 를 더블클릭하여 열고 스크립트를 작성한다.

 

 

 

 

스크립트를 열어보면 6개의 함수가 선언되어 있다.

 

  • init() : 오브젝트가 화면에 뜨기 전에 컴포넌트를 초기화하면서 호출된다.
  • final() : 컴포넌트가 제거될때(게임오브젝트가 삭제되거나 게임이 종료하기 바로 전) 호출된다.
  • update() : 매 프레임마다 호출된다. "dt"는 deltaTime이다.
  • on_message() : 스크립트 컴포넌트로 메시지가 보내질때마다 호출된다.
  • on_input() : 스크립트 컴포넌트로 입력 행동이 보내질때마다 호출된다. 입력 행동은 input 폴더의 game.input_binding 파일에서 정의된다. 이 프로젝트에서는 이미 위아래좌우 방향키가 세팅되어 있다.
  • on_reload() : 현재 스크립트가 hot-reloaded 될때 호출된다. 이는 게임 테스트나 디버깅에 유용하다. 자세한건 추후에 다룬다.

 

  • self : 현재 스크립트의 인스턴스이다.
  • dt : deltaTime의 약자로, 프레임당 시간을 의미한다.
  • message_id : 메시지가 전달되었을때 어떤 메시지인지 구분하는 값이다.
  • action_id: 입력행동이 발생했을때 어떤 키가 입력되었는지 구분하는 값이다.

이번 튜토리얼에서는 init(), update(), on_input()만 사용할 것이므로 나머지 함수는 지운다.

그리고 다음과 같이 스크립트를 작성한다.

 

 

 

 

  • (1) speed : 플레이어의 이동속도를 저장하기 위한 변수이다.
  • (2) msg.post("대상이름", "메시지") : "대상이름"에게 "메시지"를 보낸다. 현재 게임오브젝트한테 메시지를 보내려면 대상이름에 "."를 입력하면 된다. 그리고 "acquire_input_focus" 메시지를 받은 게임오브젝트는 키입력 이벤트의 대상이 된다. 즉, 키 입력이 발생할때마다 스크립트의 on_input()이 호출된다.
  • (3) 인스턴스(self) 내에 방향벡터를 저장할 변수(dir)를 선언하고 초기화한다.
  • (4) 인스턴스(self) 내에 실행중인 애니메이션을 저장할 변수(current_anim)을 선언하고 초기화한다.
  • (5) 키 입력 행동이 발생하면 on_input()이 호출되는데, "action_id" 파라미터로 어떤 키인지 확인할 수 있다. 어떤 방향키인지 확인하여 방향값(dir)을 설정한다. 좌(x = -1), 우(x = 1), 상(y = -1), 하 (y = 1). 만약 유저가 좌우 키를 동시에 누른다면 on_input()이 두번 호출되어 좌, 우가 교차될 것이다.

 

다음으로 update() 에서 플레이어의 이동과 애니메이션에 대한 코드를 작성한다.

 

 

 

 

  • (1) 방향키를 여러개 눌렸을경우, 방향벡터(dir)의 크기는 1이 넘어간다. 방향벡터의 크기가 1이 넘어가면 스피드값을 곱했을때 추가 스피드값이 생기므로 문제가 된다. 따라서 벡터를 정규화(normalize)하여 크기가 1인 단위벡터로 만든다.
  • (2) 스크립트에서 게임오브젝트는 "go" 변수로 접근한다. 게임오브젝트를 이동시키기 위해서 get_position()으로 위치 벡터를 가져오고 이동벡터를 더한 값을 set_position()으로 설정해 준다.
  • (3) 현재 방향 벡터(dir)의 값에 따라 플레이할 애니메이션의 해쉬(hash)값을 변수(anim)에 저장한다.
  • (4) 설정된 값이 현재 애니메이션(current_anim)과 다를 경우, Sprite 컴포넌트에 "play_Animation" 메시지를 보낸다. (애니메이션은 스프라이트에서 처리하기 때문에 스프라이트 컴포넌트가 메시지를 받아야 한다.) 파라미터에 id 변수를 선언하여 애니메이션 해쉬값(anim)을 넣어준다.
  • msg.post("대상이름", "메시지", 파라미터")는 대상에게 파라미터가 담긴 메시지를 보내는 함수다. 게임오브젝트의 컴포넌트들에 메시지를 보내려면 대상이름 앞에 "#"을 붙인다.
  • (5) 방향키 입력에 대한 처리가 끝났으므로 방향벡터(dir)를 초기화한다.

 

스크립트를 저장(Ctrl + S)하고 게임을 빌드(Ctrl + B)하면 캐릭터 이동과 애니메이션이 잘 실행되는 것을 확인할 수 있다.

 

 

 

 

끝.