타지않는 놀이터

[고도4] Part.1 - 12 HP와 게임오버 본문

강좌/Godot 4 - Part.1

[고도4] Part.1 - 12 HP와 게임오버

김메가 2024. 2. 17. 13:47

지난 시간까지 액션게임의 필수 요소인 공격과 피격을 구현했지만, 수없이 공격해도 적이 쓰러지지 않으니 무의미하기 짝이 없고 아무리 맞아도 주인공이 쓰러지지 않으니 적을 피할 이유가 없다. 이번 시간에는 HP를 구현해서 공격과 피격이 그 의미를 갖게 해보자.

 

우선 HP0이 되었을 때 재생할 애니메이션부터 만들자.

1. player씬을 열고 AnimationPlayer노드를 선택한 다음, dead라는 이름의 새로운 애니메이션을 생성한다.

2. Sprite노드의 texture속성에 대한 트랙을 dead애니메이션에 추가한다.

3. 키프레임 2개를 0.5초 간격으로 배치한다.

4. graphic/character/main_character폴더의 dead_000.pngdead_001.png 이미지를 각 키프레임에 할당한다.

 

dead애니메이션을 완성했으면 스크린샷과 같이 player.gd스크립트에 코드를 추가 작성하여 실제 hp를 구현해보자.

1. hp라는 이름의 int형식 변수를 선언

2. hit함수를 수정

3. _process함수에 2줄 추가

4. _physics_process함수에도 2줄 추가

 

이제 게임을 실행하고 적 캐릭터한테 다가가 5번 공격을 받으면 죽어버리는 주인공을 볼 수 있다.

 

주인공 캐릭터의 hp구현 완료.

 

주인공 캐릭터와 마찬가지로 적 캐릭터도 hp 0이 되었을 때 재생될 사망 애니메이션을 만들어주자.

1. enemy씬을 열고 AnimationPlayer노드를 선택한 다음, dead라는 이름의 새로운 애니메이션을 생성한다.

2. Sprite노드의 texture속성에 대한 트랙을 dead애니메이션에 추가한다.

3. 키프레임 6개를 0.1초 간격으로 배치한다.

4. graphic/character/enemy폴더의 dead_000.png ~ dead_004.png5개의 이미지를 첫 키프레임부터 차례대로 할당해준다.

 

5. 이미지는 5개인데 키프레임은 6개이다. 마지막 키프레임은 적 캐릭터가 아예 화면에서 보이지 않도록 이미지를 할당하지 않을 것이다. 스크린샷과 같이 마지막 키프레임을 선택한 상태에서 인스펙터를 보고 value 오른쪽의 ∨모양 버튼을 클릭하자.

 

그 다음 나타난 메뉴에서 Clear를 클릭하면 된다.

 

그럼 이렇게 키프레임에 할당된 값이 지워진다.

 

애니메이션이 제대로 만들어졌는지 재생버튼을 눌러 확인 한 번하고

 

enemy.gd스크립트에도 코드를 추가 작성하여 적 캐릭터에 hp를 구현해보자.

1.hp라는 이름의 int형식 변수를 선언

2._process함수에 2줄 추가

3._physics_process함수에도 2줄 추가

4.마지막으로 hit함수를 수정

 

이제 게임을 실행하고 적을 3번 공격하면 흩날려 사라지는 적 캐릭터를 볼 수 있다.

 

이렇게 적 캐릭터까지 hp와 사망 시스템의 구현을 완료했다. 그런데, 현재로서는 죽고나서 게임을 이어가려면 프로그램 자체를 재시작 하는 수밖에 없다.

 

그러니 사망시 활성화 되는 재시작 버튼을 만들어주자. player씬에 CanvasLayer라는 노드를 추가해주고 그 하위에 Control노드를 또 추가해준다.

 

- CanvasLayer노드는 간단하게 설명하자면 2D화면 위에 덮어 씌우는 새로운 2D화면을 만들어 주는 노드이다. 기본적으로 카메라 노드에 영향 받지 않기 때문에 화면이 움직여도 그 하위의 노드들은 위치를 유지할 수 있다.

- Control노드는 앵커 시스템을 통해 위치를 잡는, GUI를 구현하는데 특화된 종류의 노드이다. 앵커 시스템이 무엇인지에 대한 설명은 추후 계속하겠다.

 

Control노드는 이름을 GameOver로 수정해주자.

 

GameOver노드를 선택한 상태에서 2D스크린 바로 위의 툴 바를 보면 스크린샷과 같이 연두색 동그라미 안에 십자가 들어간 버튼을 찾을 수 있는데 클릭하자. 그리고 뜨는 Anchor preset메뉴에서 가장 오른쪽 아래의 꽉 찬 사각형 모양 버튼을 클릭하자.

 

GameOver노드가 게임 표시 영역을 꽉 채우도록 사이즈와 위치가 자동으로 조절될 것이다.

 

이제 GameOver노드 하위에 Button노드를 추가해주고

 

사이즈를 적당히 조절해주자.

 

GameOver노드와 마찬가지로 Anchor Preset버튼을 클릭하는데, 이번에는 위에서 2번째, 왼쪽에서 2번째 자리의 사각형 모양 버튼을 클릭하자. 스크린샷과 같이 Button노드가 게임 표시영역 정중앙에 위치하게 될 것이다.

 

Button노드의 인스펙터에서 text재시작이라고 입력하고

 

[Theme Overrides]-[Font Sizes]-[Font] 속성의 체크박스를 활성화하고 그 값을 100으로 설정하여 버튼에 재시작이라는 커다란 글자를 나타내자.

 

이제 버튼이 작동할 수 있도록 스크립트를 작성할 시간이다. script폴더를 우클릭, [Create New]-[Script]메뉴를 선택하여 새로운 스크립트 파일을 생성해주자.

 

InheritsButton으로 지정해주고, 스크립트 파일의 이름을 restart_button으로 한 다음 [Create]버튼을 누르면 된다.

 

생성된 스크립트를 파일시스템에서 Button노드로 드래그하여 붙여준다.

 

해당 스크립트를 열고 내용을 작성해주자.

 

그리고 재시작 UI는 주인공 캐릭터가 사망하기 전에 보이면 안 되니 씬 독에서 GameOver노드 오른쪽의 눈 모양 버튼을 클릭하여 숨겨주자. (또는 인스펙터에서 visible속성을 꺼도 된다. 둘은 완전히 같은 동작에 해당한다)

 

이제 player.gd 스크립트를 열고 active_game_over함수와 그 내용을 추가해주자.

 

마지막으로 dead애니메이션의 끝부분에서 방금 코딩한 active_game_over함수가 작동하도록 Call Method Track을 추가하고 키프레임에 해당 함수를 할당해주면 재시작 버튼 구현 완료다.

 

이제 적 캐릭터에게 맞아 죽으면 현재 스테이지를 재시작할 수 있다.

 

HP도 구현했고 재시작도 구현했다. 다 좋은데, 현재 HP가 얼마나 남았는지 알 수 없다는 것은 별로 좋지 않아 보인다. 현재 남은 HP를 표시하는 HP게이지까지만 구현하고 끝내자. 아래 링크에서 hp_gauge.png파일을 다운받자.

https://i-mega.itch.io/sideview-dummy-graphics

 

graphic폴더 하위에 ui폴더를 만들고 그 안에 hp_gauge.png파일을 넣어준다.

 

player씬의 CanvavsLayer노드 하위에 Control노드를 하나 더 생성해주고 이름을 UI로 수정해준다.

 

GameOver노드 하위의 재시작 버튼이 다른 UI에 가려질 우려가 있으니 UI노드를 GameOver노드 바로 위쪽으로 드래그하여 표시되는 순서를 미리 바꿔주자.

 

UI노드를 선택하고 Anchor preset을 꽉 찬 사각형 모양으로 설정하여 게임 표시 영역을 꽉 채우게 만들어주자.

 

이제 HP게이지를 표현하기 위하여 TextureProgressBar노드를 UI노드 하위에 생성해주자.

 

인스펙터를 보고 [Textures]-[progress]속성에 다운받은 hp_gauge.png 이미지를 할당한 후

 

value속성을 max_value속성과 같게 100으로 설정해준다.

 

스크린샷처럼 HP게이지가 2D스크린에서 보일 것이다.

 

다른 노드와 헷갈리지 않도록 TextureProgressBar의 이름을 HPGauge로 수정해주고

 

Anchor preset을 제일 왼쪽, 위에서 3번째로 지정해주자.

 

HP게이지가 HP게이지임을 더 확실히 플레이어에게 전달하기 위하여 Label노드를 UI노드 하위에 추가해주자. Label노드는 Control노드의 일종인데 화면에 텍스트를 표시해주는 역할을 한다.

 

Label노드의 이름을 HPLabel로 수정하고

 

인스펙터의 text속성에 HP라고 입력하자.

 

글씨 크기를 키우기 위하여 [Theme Overrides]-[Font Sizes]-[font_size] 속성을 활성화하고 48을 입력하고

 

글씨를 더 잘보이게 하기 위해 [Theme Overrides]-[Constants]-[outline_size] 속성을 활성화하고 8을 입력하여 테두리를 표시한 다음

 

테두리의 색이 글자의 색과 겹치지 않도록 [Theme Overrides]-[Colors]-[font_outline_color] 속성을 활성화하고 원하는 색상으로 설정해준다.

 

글자에 대한 설정을 끝마쳤으면 HPLabelAnchor presetHPGauge와 같게 설정해준다.

 

그리고 HPGauge노드가 HPLabel과 겹치지 않도록 오른쪽으로 조금 옮겨준다. 2D스크린에서 적당히 드래그해도 되고 스크린샷처럼 인스펙터에서 position속성에 구체적인 값을 입력해도 된다.

 

이제 player.gd스크립트를 열어서 HP게이지가 실제 작동하게 해보자. 스크린샷과 같이 변수 선언 코드를 추가하고

 

_ready함수에도 코드를 추가해주고

 

_process함수에도 코드를 추가로 작성해주면 HP게이지 구현 완료다.

 

 

게임을 켜고 적 캐릭터에게 맞아보자. 과정을 잘 따라왔다면 왼쪽 아래의 HP게이지가 주인공 캐릭터의 현재 HP를 표시해주는 모습을 볼 수 있을 것이다.