-
Turn RPG 만들기 / 스파르타 부트캠프 숙제게임 개발기록 2024. 5. 6. 17:36
Turn RPG를 만들어 보자.
먼저 Monster와 Player의 Class들을 만들어 주자. 이번엔 interface를 활용 해서 만들어 볼 것이다. 왜냐하면 쓰라고 했으니까.
interface를 만들어 주고 property와 Damage를 입게 하는 함수를 만들어 준다.
그리고 Player에서 상속을 받고 구현을 하고 Monster라는 Class도 만들어서 구현을 해준다.
internal interface ICharacter
{
string Name { get;}
int Health { get; set; }
int Attack { get;}
bool IsDead { get;}
void TakeDamage(int damage);
}
internal class Warrior : ICharacter
{
public string Name { get; }
public int Health { get; set; }
public bool IsDead => Health <= 0;
public int Attack { get; set; }
public Warrior(string name)
{
Name = name;
Health = 100;
Attack = 30;
}
public void TakeDamage(int damage)
{
Health -= damage;
if (IsDead) Console.WriteLine($"{Name}이(가) 죽었습니다.");
else Console.WriteLine($"{Name}이(가) {damage}의 데미지를 받았습니다. 남은 체력: {Health}");
}
}
public class Monster : ICharacter
{
public string Name { get; set; }
public int Health { get; set; }
public int Attack { get; set; }
public bool IsDead => Health <= 0;
public void TakeDamage(int damage)
{
Health -= damage;
if (IsDead) Console.WriteLine($"{Name}이(가) 죽었습니다.");
else Console.WriteLine($"{Name}이(가) {damage}의 데미지를 받았습니다. 남은 체력: {Health}");
}
}잘 몰르겠어가지고 답안지 보면서 했더니 좀 섞였다. 그리고 Moster Class에서 파생 된 Goblin과 Dragon Class를 만들어 주면 된다.
public class Goblin : Monster
{
public Goblin(string name = "Goblin", int health = 100, int attack = 10)
{
Name = name;
Health = health;
Attack = attack;
}
}
public class Dragon : Monster
{
public Dragon(string name = "Dragon", int health = 200, int attack = 20)
{
Name = name;
Health = health;
Attack = attack;
}
}난 이렇게 했는데 값을 넣어줄 때 매개변수에 넣을 필요 없이 생성자 안에서 바로 해줄 수 있다.
public class Dragon : Monster
{
public Dragon(string name = "Dragon")
{
Name = name;
Health = 200;
Attack = 20;
}
}이런 식으로, 굳이 내가 했던 것 처럼 할 필요가 없다. 상황에 따라 다르겠지만,
그리고 이제 Item class를 만들어 준다 이 것도 interface를 활용 해보라고 한다.
interface 안에는 name 변수와 Use 함수를 만들어 주고 Class에서 구현을 하게 했다.
internal class HealthPotion : IItem
{
public string Name => "체력 포션";
public void Use(Warrior warrior)
{
warrior.Health += 50;
Console.WriteLine("체력이 회복 되었습니다!");
}
}
internal class StrengthPotion : IItem
{
public string Name { get; set; }
public void Use(Warrior warrior)
{
warrior.Attack += 10;
Console.WriteLine("공격력이 강화 되었습니다!");
}
public StrengthPotion(string name = "강화 포션")
{
Name = name;
}
}난 이렇게 했다. 위와 아래가 좀 다른 게 확인이 될텐데 그건 내가 답지 보면서 하다가 좀 섞였다.
그리고 이제 Stage라는 class를 만들어줘서 게임이 실행 되게 해주면 된다.
이 때 interface를 최대한 활용 해줘서 간단하게 함수들을 작성 할 수 있었다.
internal class Stage
{
ICharacter Player;
ICharacter Monster;
List<IItem> Items;
public Stage(ICharacter player, ICharacter monster, List<IItem> items)
{
Player = player;
Monster = monster;
Items = items;
}
public void start()
{
Console.Clear();
Console.WriteLine("전투 시작!");
Console.WriteLine($"{Player.Name}의 체 력 : {Player.Health}");
Console.WriteLine($"{Player.Name}의 공격력 : {Player.Attack}\n");
Console.WriteLine($"{Monster.Name}의 체 력 : {Monster.Health}");
Console.WriteLine($"{Monster.Name}의 공격력 : {Monster.Attack}");
Console.WriteLine("==========================================================");
while(!Player.IsDead && !Monster.IsDead)
{
Console.WriteLine("Player의 공격!");
Monster.TakeDamage(Player.Attack);
Console.WriteLine($"{Player.Attack}의 Damage!");
Thread.Sleep(1000);
if (Monster.IsDead) break; //여기에서 if조건문을 사용 한 것은 moster가 죽었는데 공격 하면 안 되기 때문!
Console.WriteLine($"{Monster.Name}의 공격!");
Player.TakeDamage(Monster.Attack);
Console.WriteLine($"{Monster.Attack}의 Damage!");
Thread.Sleep(1000);
}
if(Monster.IsDead)
{
Console.WriteLine("Player의 승리!");
Console.WriteLine("전림품을 획득 할 수 있습니다!");
Console.WriteLine("사용 할 아이템을 선택 해주세요.");
for (int i = 0; i < Items.Count; i++)
{
Console.WriteLine($"{i+1}. {Items[i].Name}");
}
while (true)
{
if (int.TryParse(Console.ReadLine(), out int num) && num <= Items.Count)
{
Items[num - 1].Use((Warrior)Player);
Console.WriteLine($"현재 Player의 정보");
Console.WriteLine($"체력 : {Player.Health} 공격력 : {Player.Attack}\n");
break;
}
else
{
Console.WriteLine("잘 못 된 입력 입니다.");Console.WriteLine("다시 입력 해주세요.");
}
}
}
else if(Player.IsDead)
{
Console.WriteLine("Monster에게 패배 하였습니다.");
}
}
}이렇게 class를 만들어 줬는데 interface로 만들어 두니 함수를 작성 할 때 매우 편리 했다. 원래대로라면 참조 하려면 객체를 생성하거나 매개변수로 받아오게 하거나 등등 번거로웠는데 interface로 작업을 하니 되게 편리 했다.
함수 하나만 만들어두고 사용 할 때 값만 class를 넣어주면 되니까 편했다.
이제 main 함수에서 실행이 되게끔 객체들을 생성 해주고 함수를 실행 하게 하면 된다.
static void Main(string[] args)
{
Warrior player = new Warrior("원강");
Goblin goblin = new Goblin();
Dragon dragon = new Dragon();
List<IItem> items = new List<IItem> { new HealthPotion(), new StrengthPotion() };
Stage stage1 = new Stage(player, goblin, items);
stage1.start();
if (player.IsDead) return;
Stage stage2 = new Stage(player, dragon, items);
stage2.start();
if (player.IsDead) return;
Console.WriteLine("축하합니다! Game Clear!");
}이렇게 하면 끝이다.
느낀 점 : 이번 숙제를 하면서 interface에 대한 활용법에 대해서 깨달은 느낌이다.
원래 interface가 무엇인진 알았고, 어떤 식으로 활용 할 수도 있는지는 알고 있었지만 직접 해보니 더 깨달은 느낌이다.
interface를 상속 받은 class에 구현한 함수들을 실행 하려면 interface형 객체를 만들고 값에 class를 넣어줘서 함수들을 사용 할 수 있었는데 이것 말고도 다른 class에서 함수들을 만들 때 interface형으로 참조형을 만들어서 함수들을 편리하게 만들어 줄 수 있었다. 이 방법을 사용 안 한다면 다른 class에서 만들 때 객체를 매번 생성 하거나 매개변수로 받아오거나 등등 번거롭게 작업을 해야 했는데 이 방식을 사용하니 매우 편리 했다. 그러면 interface에 최대한 많은 기능들을 넣는 게 좋은 걸까. 어찌 되었든 console game 만들 때는 유용한 것 같으나 Unuty에서도 유용한지는 의문이다.
class 작성 방법 자체가 많이 다른 느낌이라 Unuty에서 interface는 어떤 방식으로 사용 되는지 궁금하다.
그리고 살짝 권태기가 온 것일까. 열정이 많이 사그라진 느낌으로 이번 숙제를 한 것 같다. 다시 되찾자 내 열정.
'게임 개발기록' 카테고리의 다른 글
TopDown Shooting Game/캐릭터 이동 기능 (1) 2024.05.20 TopDown Shooting Game 만들기 (2) 2024.05.20 상점에 페이지 기능 추가하기 // 스파르타 C#문법 심화팀과제 (0) 2024.05.02 치명타 기능 구현하기 // 스파르타 C#문법 심화 팀과제 (0) 2024.05.02 스파르타 개인 과제 / 던전 입장 전 구현 (1) 2024.04.28