본문 바로가기
Godot

[GodotDocs][Your First 2D Game] 10. 마무리 작업(C#)

by 채식금지 2024. 4. 7.
728x90

본 게시글은 고도엔진 공식문서에 작성된 Your first 2D game를 정리하였습니다.

 

플레이어 숨김

  • 게임을 처음 실행할 때 플레이어가 화면에 출력되지 않도록 수정한다.
  • res://Main.cs 파일을 열어 _Ready 메소드를 아래와 같이 수정한다.
public override void _Ready()
{
    GetNode<Player>("Player").Hide();
}

 

게임 오버 후 적 제거

  • 게임이 끝난 후에도 남아있는 적들이 있고, 이 상태에서 게임을 바로 재시작하면 남아 있던 적들도 함께 피해야 되는 문제점이 발생한다.
  • 게임을 재시작했을 때 화면에 적이 없는 상태에서 시작되도록 게임을 수정할 것이다.

 

  • res://Mob.tscn 파일을 열어 Mob 노드를 선택한다.
  • 오른쪽 화면에 있는 Node 도크를 선택한다.
  • Node 도크에서 Groups 탭을 선택한 후 Manage Groups 버튼 바로 아래 있는 텍스트 입력창에 mobs를 입력한다.

 

  • 텍스트 입력창에 mobs를 입력한 후 오른쪽에 있는 Add 버튼을 누르면 mobs 그룹이 새로 추가된다.

 

  • 고도엔진에서 그룹은 유니티의 태그와 유사한 역할을 한다.
  • res://Mob.tscn 파일을 저장한다.

 

  • res://Main.cs 파일을 연다.
  • NewGame 메소드에 아래 내용을 추가한다.
GetTree().CallGroup("mobs", Node.MethodName.QueueFree)
  • 새로 추가한 코드는 게임에서 mobs 그룹이 설정된 노드를 찾아 queue_free 함수를 호출한다.
  • 게임을 시작할 때마다 mobs 그룹을 추가한 적들을 화면에서 사라지게 된다.

 

  • res://Main.cs 파일을 저장한다.
  • 에디터 오른쪽 상단에 있는 Build Project를 선택하여 변경사항을 적용한다.

 

배경 수정

  • res://Main.tscn 파일을 연다.
  • ColorRect 노드를 Main 노드의 자식으로 새로 추가한다.

 

  • ColorRect 노드를 가장 위로 올려 다른 노드들이 ColorRect 노드에 가려지지 않도록 만든다.

 

  • ColorRect 노드를 선택한다.
  • 뷰포트 상단에 새로 추가된 Anchor preset 툴바를 선택한다.
  • Full Rect를 선택하여 ColorRect 노드의 위치와 크기가 게임화면에 맞춰지도록 설정한다.

 

  • Inspector 도크에서 Color를 원하는 색으로 수정한다.

 

  • res://Main.tscn 파일을 저장한다.

 

소리 효과

  • res://Main.tscn 파일을 연다.
  • AudioStreamPlayer2D 노드를 Main 노드의 자식으로 추가한 후 Music으로 이름을 수정한다.
  • AudioStreamPlayer2D 노드를 Main 노드의 자식으로 추가한 후 DeathSound로 이름을 수정한다.

 

  • Music 노드를 선택한다.
  • Inspector 도크에 있는 Stream 속성에 res://art/House In a Forest Loop.ogg 파일을 드래그한다.
  • Stream 속성에 연결된 파일을 클릭하여 AudioStreamOggVoribs 속성이 나오도록 만든다.
  • Stream 속성에 연결된 파일을 우클릭하여 메뉴가 나오도록 만든다.(FileSystem 도크에서 우클릭하면 안 된다.)
  • 메뉴에서 Make Unique를 선택하여 AudioStreamOggVoribs 속성도 설정할 수 있도록 만들어 준다.

 

  • Loop 속성을 체크하여 자동반복재생할 수 있도록 만들어준다.

 

  • DeathSound 노드를 선택한다.
  • Inspector 도크에 있는 Stream 속성에 res://art/gameover.wav 파일을 드래그한다.

 

  • res://Main.cs 파일을 연다.
  • NewGame 함수에 아래 내용을 추가한다.
  • 게임을 시작할 때 배경음을 재생한다.
GetNode<AudioStreamPlayer2D>("Music").Play();

 

  • GameOver 함수에 아래 내용을 추가한다.
  • 게임이 끝날 때 배경음을 멈추고, 사망 효과음을 재생한다.
GetNode<AudioStreamPlayer2D>("Music").Stop();
GetNode<AudioStreamPlayer2D>("DeathSound").Play();

 

  • res://Main.cs 파일을 저장한 후, 에디터 오른쪽 상단에 있는 Build Project 버튼을 클릭한다.
  • res://Main.tscn 파일을 저장한다.

 

키보드 숏컷

  • Enter 키를 눌러 게임을 시작할 수 있도록 수정할 것이다.
  • 상단 메뉴에서 Project>Project Settings... 를 선택한다.
  • Project Settings 팝업창 상단의 Input Map 탭을 선택한다.
  • Add New Action 필드에 start_game 을 입력한 후 Add 버튼을 클릭한다.

 

  • start_game이 추가되면 Deadzon에 있는 ➕아이콘을 클릭한다.
  • Listening for input... 필드가 활성화된 상태에서 키보드 Enter 키를 누르면 자동으로 Enter 키가 선택된다.
  • Enter 키가 선택되면 OK 버튼을 눌러 Event Configuration 팝업창을 닫는다.

 

  • res://HUD.tscn 파일을 연다.
  • StartButton 노드를 선택한다.
  • Inspector 도크에서 Shortcut 속성을 찾아 Shortcut 리소스를 새로 추가한다.

 

  • Inspector 도크에서 추가된 Shortcut 리소스를 클릭하여하여 Shortcut 속성이 나오도록 만든다.
  • Events 속성의 Array[InputEvent] (size 0) 을 클릭하여 Events 속성이 나오도록 만든다.
  • Add Element 버튼을 클릭하여 새로운 이벤트를 추가한다.
  • 새로 추가된 이벤트에 InputEventAction 리소스를 추가한다.

 

  • Inspector 도크에서 추가된 InputEventAction 리소스를 클릭하여하여 InputEventAction 속성이 나오도록 만든다.
  • Action 속성에 start_game을 입력한다.

 

  • res://HUD.tscn 파일을 저장한다.
  • 이제 StartButton이 화면에 출력되고 있을 때 Enter 키를 눌러 게임을 시작할 수 있다.

 

완성된 스크립트

using Godot;
using System;

public partial class Main : Node
{
    [Export]
    public PackedScene MobScene
    {
        get;
        private set;
    }

    public int Score
    {
        get;
        private set;
    }

    public override void _Ready()
    {
        GetNode<Player>("Player").Hide();
    }

    void NewGame()
    {
        Score = 0;

        var player = GetNode<Player>("Player");
        var startPosition = GetNode<Marker2D>("StartPosition");
        var hud = GetNode<HUD>("HUD");

        player.Start(startPosition.Position);
        GetTree().CallGroup("mobs", Node.MethodName.QueueFree);
        GetNode<Timer>("StartTimer").Start();
        hud.UpdateScore(Score);
        hud.ShowMessage("Get Ready");
        GetNode<AudioStreamPlayer2D>("Music").Play();
    }

    void GameOver()
    {
        GetNode<Timer>("ScoreTimer").Stop();
        GetNode<Timer>("MobTimer").Stop();
        GetNode<HUD>("HUD").ShowGameOver();
        GetNode<AudioStreamPlayer2D>("Music").Stop();
        GetNode<AudioStreamPlayer2D>("DeathSound").Play();
    }

    void OnStartTimerTimeout()
    {
        GetNode<Timer>("ScoreTimer").Start();
        GetNode<Timer>("MobTimer").Start();
    }

    void OnScoreTimerTimeout()
    {
        ++Score;
        GetNode<HUD>("HUD").UpdateScore(Score);
    }

    void OnMobTimerTimeout()
    {
        var mob = MobScene.Instantiate<Mob>();

        var spawnLocation = GetNode<PathFollow2D>("MobPath/MobSpawnLocation");
        spawnLocation.ProgressRatio = GD.Randf();

        var direction = spawnLocation.Rotation + Mathf.Pi / 2;
        direction += (float)GD.RandRange(-Mathf.Pi / 4, Mathf.Pi / 4);

        mob.Position = spawnLocation.Position;
        mob.Rotation = direction;

        var velocity = new Vector2((float)GD.RandRange(150.0, 250.0), 0f);
        mob.LinearVelocity = velocity.Rotated(direction);

        AddChild(mob);
    }
}

 

게임 영상

 

godotdocs-1st2dgame-10-16.mp4
6.47MB