728x90
본 게시글은 고도엔진 공식문서에 작성된 Your first 2D game를 정리하였습니다.
스크립트 추가
res://Player.tscn
을 선택한다.- Scene 도크에서 Player 노드를 선택한다.
- Attach Script 아이콘을 클릭한다.
- Attach Node Script 팝업창이 열리면 Language를 C# 으로 선택한다.
- C#을 선택하면 Path는 자동으로
res://Player.cs
로 변경된다. - Create 버튼을 클릭하여 스크립트를 생성한다.
플레이어 이동구현
Player.cs
파일을 연다.- 클래스 안에 클래스를 프로퍼티를 선언한다.
[Export]
public int Speed
{
get;
set;
} = 400;
Vector2 ScreenSize
{
get;
set;
}
- Export 어트리뷰트를 사용하면 해당 필드나 프로퍼티의 값을 Inspector에서 설정할 수 있게 된다.
- 스크립트를 저장한 후, 프로젝트를 빌드한 후,
Player.tscn
씬을 열고, Player 노드를 선택하면 Inspector 도크에 Speed 속성이 추가되어 있는 것을 확인 할 수 있다.
- 처음 스크립트를 추가하면
_Ready()
메소드와_Process(double delta)
메소드는 이미 추가되어 있다. _Ready()
함수 안에 아래의 코드를 추가한다.
public override void _Ready()
{
ScreenSize = GetViewportRect().Size;
}
_Ready()
메소드는 Player 노드 씬 트리에 등록되었을 때(초기화 되었을 때) 한 번 호출된다.GetViewportRect()
메소드를 이용하여 게임 화면의 크기를 불러와ScreenSize
프로퍼티 안에 저장한다.
_Process(double delta)
메소드 안에 아래의 코드를 추가한다.
public override void _Process(double delta)
{
var direction = Vector2.Zero;
if (Input.IsActionPressed("move_right"))
direction.X += 1;
if (Input.IsActionPressed("move_left"))
direction.X -= 1;
if (Input.IsActionPressed("move_down"))
direction.Y += 1;
if (Input.IsActionPressed("move_up"))
direction.Y -= 1;
}
move_right
,move_left
,move_down
,move_up
은 [GodotDocs][Your First 2D Game] 1. 프로젝트 설정에서 미리 키보드 A, D, S, W와 미리 입력 시켜 두었다.Input.IsActionPressed
함수는 특정키를 누르고 있을 때true
를 반환한다.Input.IsActionPressed
함수 안에move_right
,move_left
,move_down
,move_up
을 넣어 사용하면 키보드 A, D, S, W를 누르고 있을 때true
를 반환한다.- 키보드를 누를 때 이동할 방향을
direction
변수에 저장한다.
- 고도 엔진의 2D 좌표는 가로는 X축, 세로는 Y축이다.
- 따로 카메라를 추가하지 않았다면 화면 기준으로 왼쪽 상단 좌표가 (0, 0)이다.
- 오른 쪽으로 갈 수록 X축 값이 증가하고, 아래 쪽으로 내려갈 수록 Y축 값이 증가한다.
_Process(double delta)
메소드 안에 아래의 코드를 더 추가한다.
var animSprite = GetNode<AnimatedSprite2D>("AnimatedSprite2D");
var velocity = Vector2.Zero;
if (direction.Length() > 0)
{
velocity = direction * Speed;
animSprite.Play();
}
else
animSprite.Stop();
direction.Length()
메소드는 벡터의 거리를 계산하는 함수이다. 키보드를 누를 경우 0 이 아닌 값을 반환한다.velocity = direction * Speed
는 키보드를 누를 경우direction
방향으로speed
만큼의 속력으로 이동한다는 의미가 된다. 하지만 실제 노드의 좌표를 변경하지 않았기 때문에 이것 만으로 노드가 이동하지 않는다.GetNode("AnimatedSprite2D")
를 이용하여 Player 노드의 자식으로 등록된 AnimatedSprite2D 노드를 불러올 수 있다.GetNode("AnimatedSprite2D").Play()
는 등록된 SpriteFrame에 맞춰 스프라이트 애니메이션을 재생 시키는 함수이다.
_Process(double delta)
메소드 안에 아래의 코드를 더 추가한다.
Position += velocity * (float)delta;
Position = Position.Clamp(Vector2.Zero, ScreenSize);
Position
에velocity
를 더해 노드가velocity
만큼 이동하게 된다.- 컴퓨터의 사양과 관계없이 동일한 시간에 동일한 거리를 이동하도록 처리하기 위해
velocity
에delta
를 곱해준다. Clamp
함수는 입력된 값의 범위를 벗어나지 않게 보정해준다.Position.Clamp(Vector2.Zero, ScreenSize)
를 적용하면 노드가 화면 밖으로 이동하지 않도록 보정해준다.
_Process(double delta)
함수 안에 아래의 코드를 더 추가한다.
if (direction.X != 0)
{
animSprite.Animation = "walk";
animSprite.FlipV = false;
animSprite.FlipH = direction.X < 0;
}
else if (direction.Y != 0)
{
animSprite.Animation = "up";
animSprite.FlipV = direction.Y > 0;
}
walk
,up
은 [GodotDocs][Your First 2D Game] 2. 플레이어 씬 제작에서 미리 만들어둔 애니메이션이다.GetNode("AnimatedSprite2D").Animation
값을 수정하여 미리 만들어둔 애니메이션을 선택할 수 있다.- X축으로 이동할 때는
walk
, Y축으로 이동할 때는up
애니메이션을 선택한다. GetNode("AnimatedSprite2D").FlipH
가true
일 경우 X축을 기준으로 이미지를 반전 시킨다.GetNode("AnimatedSprite2D").FlipV
가true
일 경우 Y축을 기준으로 이미지를 반전 시킨다.- 플레이어가 오른쪽으로 이동하면 X축을 기준으로 이미지를 반전 시키고, 아래로 내려갈 경우 Y축을 기준으로 이미지를 반전 시킨다.
- 지금까지 작업한 내용은 빌드 후 에디터 오른쪽 상단의 Run Current Scene 버튼을 클릭하여 테스트할 수 있다.
충돌처리 준비
- 적과 충돌하였을 때 처리를 미리 구현한다.
- 클래스 안에 클래스를
SignalAttribute
가 포함된 델리게이트를 선언한다.
[Signal]
public delegate void HitEventHandler();
- Scene 도크에서 Player 노드를 선택한다.
- 에디터 오른쪽에 있는 Node 도크를 선택한다.
body_entered(body: Node2D)
시그널을 더블 클릭한다.
- Connect a Signal to a Method 팝압창이 열리면 Receiver Method: 에 적힌 함수의 이름을 OnBodyEntered 로 변경한다.
- Connect 버튼을 클릭하여
body_entered(body: Node2D)
시그널과 나중에 추가할 OnBodyEntered 메소드를 연결한다.
- C# 으로 개발할 경우, 시그널을 연결해도 메소드가 자동으로 추가되지 않기 때문에 시그널과 연결된 메소드를 직접 코딩으로 입력한다.
public void OnBodyEntered(Node2D body)
{
Hide();
EmitSignal(SignalName.Hit);
GetNode("CollisionShape2D").SetDeferred(CollisionShape2D.PropertyName.Disabled, true);
}
- 적과 충돌하게 되면
void OnBodyEntered(Node2D body)
메소드가 자동으로 호출된다. Hide()
메소드를 호출하면 노드가 화면에 출력되지 않는다.EmitSignal()
메소드를 호출하면 미리 정의해둔Hit
시그널의 신호가 발생한다.- CollisionShape2D를 바로 비활성화하면 고도엔진이 충돌처리를 하는 도중에 오류가 발생할 수 있다.
SetDeferred
메소드드를 이용하면 안전하게 CollisionShape2D를 비활성화할 때까지 대기하도록 고도엔진에 지시하게 된다.
Start(Vector2 position)
메소드를 새로 추가한다.Start(Vector2 position)
메소드는 게임을 시작할 때 플레이어를 초기화하기 위해 호출한다.
public void Start(Vector2 position)
{
Position = position;
Show();
GetNode<CollisionShape2D>("CollisionShape2D").Disabled = false;
}
완성된 스크립트
using Godot;
using System;
public partial class Player : Area2D
{
[Signal]
public delegate void HitEventHandler();
[Export]
public int Speed
{
get;
set;
} = 400;
Vector2 ScreenSize
{
get;
set;
}
// Called when the node enters the scene tree for the first time.
public override void _Ready()
{
ScreenSize = GetViewportRect().Size;
}
// Called every frame. 'delta' is the elapsed time since the previous frame.
public override void _Process(double delta)
{
var direction = Vector2.Zero;
if (Input.IsActionPressed("move_right"))
direction.X += 1;
if (Input.IsActionPressed("move_left"))
direction.X -= 1;
if (Input.IsActionPressed("move_down"))
direction.Y += 1;
if (Input.IsActionPressed("move_up"))
direction.Y -= 1;
var animSprite = GetNode<AnimatedSprite2D>("AnimatedSprite2D");
var velocity = Vector2.Zero;
if (direction.Length() > 0)
{
velocity = direction * Speed;
GetNode<AnimatedSprite2D>("AnimatedSprite2D").Play();
}
else
GetNode<AnimatedSprite2D>("AnimatedSprite2D").Stop();
Position += velocity * (float)delta;
Position = Position.Clamp(Vector2.Zero, ScreenSize);
if (direction.X != 0)
{
animSprite.Animation = "walk";
animSprite.FlipV = false;
animSprite.FlipH = direction.X < 0;
}
else if (direction.Y != 0)
{
animSprite.Animation = "up";
animSprite.FlipV = direction.Y > 0;
}
}
public void OnBodyEntered(Node2D body)
{
Hide();
EmitSignal(SignalName.Hit);
GetNode("CollisionShape2D").SetDeferred(CollisionShape2D.PropertyName.Disabled, true);
}
public void Start(Vector2 position)
{
Position = position;
Show();
GetNode<CollisionShape2D>("CollisionShape2D").Disabled = false;
}
}
'Godot' 카테고리의 다른 글
[GodotDocs][Your First 2D Game] 5. 적(Mob) 코딩(GDScript, C#) (0) | 2024.02.18 |
---|---|
[GodotDocs][Your First 2D Game] 4. 적(Mob) 제작 (0) | 2024.02.16 |
[GodotDocs][Your First 2D Game] 3. 플레이어 코딩(GDScript) (2) | 2024.02.06 |
[GodotDocs][Your First 2D Game] 2. 플레이어 씬 제작 (0) | 2024.01.28 |
[GodotDocs][Your First 2D Game] 1. 프로젝트 설정 (0) | 2024.01.14 |