지난 포스트에서 플레이어를 구현하였으니,
이어서 이번에는 플레이어가 마을과 필드에 입장하고,
몬스터와 전투를 진행하는 부분까지 구현해 보려고 합니다.
완성된 형태의 출력 결과물은 다음과 같습니다.
우선 메인 함수에서 EnterGame() 함수를 만들어서 게임에 접속시키는 기능을 구현해 봅시다.
EnterGame() 함수에서 구현해야 하는 기능은 다음과 같습니다.
1) 마을에 도착
2) 필드로 갈 것인지, 로비로 돌아가서 다시 캐릭터 선택창으로 갈 것인지 선택.
3) 필드로 갔을 때 몬스터와 전투를 진행하기 (EnterField() 메서드를 만들어서 구현할 예정)
static void EnterGame(ref Player player)
{
while (true)
{
Console.WriteLine("시작의 마을에 도착했습니다.");
Console.WriteLine("[1] 필드로 간다");
Console.WriteLine("[2] 로비로 간다");
string input = Console.ReadLine();
if (input == "1")
{
EnterField(ref player);
}
else if (input == "2")
{
break;
}
}
}
ref Player player을 매개변수로 받아온 이유는, 바로 Player의 hp의 진짜 값을 변화시키고 싶기 때문입니다.
ref 키워드를 사용하지 않을 경우 hp 변수는 복사되어서 실제 hp 값에 변화를 줄 수 없기 때문입니다.
(관련 포스트 참고하기 - https://nybot-house.tistory.com/93)
While문을 활용하여 2를 눌렀을 때는 로비로 돌아가도록 구현해 줍니다.
EnterFiled() 함수에서 구현해야 하는 것은 몬스터와의 전투입니다.
1) 몬스터 한 마리를 랜덤으로 소환하기
2) 전투/도주 기능
3) 전투 선택시 배틀 진행하기
4) 도주 선택시 일정 확률로 도주 성공/실패 기능 구현하기.
따라서 몬스터도 플레이어와 마찬가지로 구조체를 만들어 공격과 hp 정보를 저장해주고,
선택에 따라 랜덤한 몬스터가 소환될 수 있도록 enum 구조체를 만들어서 몬스터의 타입을 구분해 봅시다.
enum MonsterType
{
None = 0,
Slime = 1,
Goblin = 2,
Skeleton = 3,
}
struct Monster
{
public int hp;
public int attack;
}
static void EnterField(ref Player player)
{
while(true)
{
Console.WriteLine("필드에 접속했습니다!");
//랜덤으로 몬스터 하나를 스폰
Monster monster;
CreateRandomMonster(out monster);
Console.WriteLine("[1] 전투다!");
Console.WriteLine("[2] 마을로 도망치자.");
string input = Console.ReadLine();
if (input == "1")
{
Fight(ref player, ref monster);
}
else if (input == "2")
{
//33%
Random rand = new Random();
int randValue = rand.Next(0, 101);
if(randValue <= 33)
{
Console.WriteLine("도주에 성공했습니다!");
break;
}
else
{
Fight(ref player, ref monster);
}
}
}
}
Random 한 수를 뽑아내기 위해서 Random 클래스를 사용했는데, 이에 대한 자세한 정보는 구글에 너무나도 쉬운 설명이 많기에 생략하겠습니다. (https://blockdmask.tistory.com/347)
이제 Fight 메서드를 구현해서 실제로 플레이어와 몬스터가 전투를 하도록 만들어 봅시다.
static void Fight(ref Player player, ref Monster monster)
{
while(true)
{
//플레이어가 몬스터 공격
monster.hp -= player.attack;
if (monster.hp <= 0)
{
Console.WriteLine("승리했습니다");
Console.WriteLine($"남은 체력 : {player.hp}");
break;
}
//몬스터 반격
player.hp -= monster.attack;
if(player.hp <= 0)
{
Console.WriteLine("패배했습니다.");
break;
}
}
}
간단하게 플레이어가 먼저 공격하고, 몬스터가 나중에 공격하도록 구성하였습니다.
hp가 0이 되면 함수를 break 하도록 하였습니다.
이제 main 함수에서 EnterGame(ref player); 이렇게 메서드를 호출해 주기만 하면 완성입니다!
다음은 코드 전문입니다.
using System.Numerics;
namespace CSharp
{
class Program
{
enum ClassType
{
None = 0,
Warrior = 1,
Rogue = 2,
Mage = 3
}
enum MonsterType
{
None = 0,
Slime = 1,
Goblin = 2,
Skeleton = 3,
}
struct Player
{
public int hp;
public int attack;
}
struct Monster
{
public int hp;
public int attack;
}
static void Main(string[] args)
{
while (true)
{
ClassType playerClassChoice = ChooseClass();
if (playerClassChoice == ClassType.None)
continue;
//캐릭터 생성
Player player;
CreatePlayer(playerClassChoice, out player);
EnterGame(ref player);
}
}
static ClassType ChooseClass()
{
Console.WriteLine("직업을 선택하세요!");
Console.WriteLine("[1] 전사");
Console.WriteLine("[2] 도적");
Console.WriteLine("[3] 마법사");
ClassType classChoice = ClassType.None;
string input = Console.ReadLine();
switch (input)
{
case "1":
classChoice = ClassType.Warrior;
break;
case "2":
classChoice = ClassType.Rogue;
break;
case "3":
classChoice = ClassType.Mage;
break;
}
return classChoice;
}
static void CreatePlayer(ClassType choice, out Player player)
{
//전사(100,10) 도적(75, 15), 마법사(50, 5)
switch (choice)
{
case ClassType.Warrior:
player.hp = 100;
player.attack = 10;
break;
case ClassType.Rogue:
player.hp = 75;
player.attack = 15;
break;
case ClassType.Mage:
player.hp = 50;
player.attack = 5;
break;
default:
player.hp = 0;
player.attack = 0;
break;
}
}
private static void CreateRandomMonster(out Monster monster)
{
Random rand = new Random();
int randMosnter = rand.Next(1, 4);
switch (randMosnter)
{
case (int)MonsterType.Slime:
Console.WriteLine("슬라임이 등장했습니다!");
monster.hp = 35;
monster.attack = 1;
break;
case (int)MonsterType.Goblin:
Console.WriteLine("고블린이 등장했습니다!");
monster.hp = 30;
monster.attack = 3;
break;
case (int)MonsterType.Skeleton:
Console.WriteLine("스켈레톤이 등장했습니다!");
monster.hp = 20;
monster.attack = 2;
break;
default:
monster.hp = 0;
monster.attack = 0;
break;
}
}
static void EnterGame(ref Player player)
{
while (true)
{
Console.WriteLine("시작의 마을에 도착했습니다.");
Console.WriteLine("[1] 필드로 간다");
Console.WriteLine("[2] 로비로 간다");
string input = Console.ReadLine();
if (input == "1")
{
EnterField(ref player);
}
else if (input == "2")
{
break;
}
}
}
static void EnterField(ref Player player)
{
while(true)
{
Console.WriteLine("필드에 접속했습니다!");
//랜덤으로 몬스터 하나를 스폰
Monster monster;
CreateRandomMonster(out monster);
Console.WriteLine("[1] 전투다!");
Console.WriteLine("[2] 마을로 도망치자.");
string input = Console.ReadLine();
if (input == "1")
{
Fight(ref player, ref monster);
}
else if (input == "2")
{
//33%
Random rand = new Random();
int randValue = rand.Next(0, 101);
if(randValue <= 33)
{
Console.WriteLine("도주에 성공했습니다!");
break;
}
else
{
Fight(ref player, ref monster);
}
}
}
}
static void Fight(ref Player player, ref Monster monster)
{
while(true)
{
//플레이어가 몬스터 공격
monster.hp -= player.attack;
if (monster.hp <= 0)
{
Console.WriteLine("승리했습니다");
Console.WriteLine($"남은 체력 : {player.hp}");
break;
}
//몬스터 반격
player.hp -= monster.attack;
if(player.hp <= 0)
{
Console.WriteLine("패배했습니다.");
break;
}
}
}
}
}
'C# 기초 프로그래밍 > TextRPG 만들기' 카테고리의 다른 글
<TextRPG> 02. 플레이어 생성 (0) | 2023.12.15 |
---|---|
<TextRPG> 01. 캐릭터 직업 고르기 (0) | 2023.12.15 |