게임 캐릭터 컴포넌트
Coddy C# 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 70개 중 69번째.
챌린지
쉬움컴포넌트 기반 아키텍처 패턴을 사용하여 게임 캐릭터 시스템을 구축해 봅시다! 경직된 상속 계층 구조를 만드는 대신, 특정 동작을 처리하는 독립적인 컴포넌트를 부착하여 캐릭터를 구성하게 됩니다. 이는 게임 개발에서 널리 사용되는 유연한 방식입니다.
코드는 다음 다섯 개의 파일로 구성됩니다:
IComponent.cs:Game.Components네임스페이스에IComponent인터페이스를 정의합니다. 모든 컴포넌트는 해당 컴포넌트가 무엇을 하고 있는지 출력하는Update()메서드를 가져야 합니다.HealthComponent.cs:IComponent를 구현하는HealthComponent클래스를 생성합니다. 이 클래스는 현재 체력과 최대 체력을 추적해야 하며,TakeDamage(int amount)및Heal(int amount)메서드를 포함해야 합니다. 체력은 0보다 낮아지거나 최대치를 초과해서는 안 됩니다. 체력이 변경될 때마다 새로운 체력 값을 전달하며 실행되는event Action<int> HealthChanged를 포함하세요.Update()메서드는 현재 체력 상태를 출력해야 합니다.InventoryComponent.cs:IComponent를 구현하는InventoryComponent클래스를 생성합니다. 이 클래스는 아이템 이름 목록을 관리하며,AddItem(string item)및RemoveItem(string item)(성공 여부를 나타내는bool반환) 메서드를 가집니다.Update()메서드는 인벤토리 내용을 출력해야 합니다.Character.cs:Game네임스페이스에 컴포넌트 컬렉션을 보유하는Character클래스를 생성합니다. 캐릭터는Name속성과 다음 메서드들이 필요합니다:AddComponent(IComponent component)- 캐릭터에 컴포넌트를 부착합니다.GetComponent<T>()(여기서 T : IComponent) - 해당 타입 T의 첫 번째 컴포넌트를 반환하거나, 찾지 못한 경우 null을 반환합니다.UpdateAll()- 부착된 각 컴포넌트의Update()를 호출합니다.
Program.cs: 캐릭터를 생성하고, 컴포넌트를 부착하고, 명령을 처리하여 모든 요소를 하나로 합칩니다.
다음 입력을 받게 됩니다:
- 캐릭터 이름
- HealthComponent를 위한 초기 최대 체력
- 처리할 명령의 개수
- 각 명령: 액션과 그에 따른 관련 데이터
명령 형식:
damage
{amount}
heal
{amount}
add_item
{itemName}
remove_item
{itemName}
update출력 형식:
- 체력이 변경될 때 (이벤트를 통해):
Health changed: {newHealth} - 아이템을 추가할 때:
Added: {itemName} - 아이템을 제거할 때:
Removed: {itemName}또는Item not found: {itemName} - HealthComponent의
Update():Health: {current}/{max} - InventoryComponent의
Update():Inventory: {item1}, {item2}, ...또는Inventory: empty
예를 들어, 입력이 다음과 같다면:
Hero
100
7
add_item
Sword
add_item
Shield
damage
30
heal
10
remove_item
Potion
remove_item
Sword
update출력은 다음과 같아야 합니다:
Added: Sword
Added: Shield
Health changed: 70
Health changed: 80
Item not found: Potion
Removed: Sword
Health: 80/100
Inventory: Shield캐릭터가 특별한 것을 상속받지 않고, 단순히 동작을 제공하는 컴포넌트들을 보유하고 있다는 점에 주목하세요. GetComponent<T>() 메서드는 타입 안전한 검색을 위해 제네릭을 사용하며, 이벤트는 체력이 변경될 때 알림을 줍니다. 이러한 구성(composition) 방식은 컴포넌트를 자유롭게 조합하고 매치할 수 있게 해줍니다!
직접 해보기
using System;
using Game;
using Game.Components;
class Program
{
public static void Main(string[] args)
{
// 캐릭터 이름 읽기
string characterName = Console.ReadLine();
// 초기 최대 체력 읽기
int maxHealth = Convert.ToInt32(Console.ReadLine());
// 명령어 개수 읽기
int numCommands = Convert.ToInt32(Console.ReadLine());
// TODO: 주어진 이름으로 Character 생성
// TODO: maxHealth를 가진 HealthComponent와 InventoryComponent 생성
// TODO: HealthChanged 이벤트에 구독하여 Health changed: {newHealth} 출력
// TODO: 캐릭터에 두 컴포넌트 모두 추가
// TODO: 각 명령어 처리
for (int i = 0; i < numCommands; i++)
{
string command = Console.ReadLine();
// TODO: 각 명령어 타입 처리:
// - "damage": 양을 읽고, health component의 TakeDamage 호출
// - "heal": 양을 읽고, health component의 Heal 호출
// - "add_item": 아이템 이름을 읽고, inventory component의 AddItem 호출
// - "remove_item": 아이템 이름을 읽고, inventory component의 RemoveItem 호출
// - "update": character의 UpdateAll 호출
}
}
}