반응형
로비 메뉴 구성
enum MAIN_MENU
{
MM_NONE,
MM_MAP,
MM_STORE,
MM_INVENTORY,
MM_EXIT
};
- 맵, 상점, 인벤, 종료로 enum(열거체) 추가
메뉴 선택 구성
int main()
{
while (true)
{
//로비 구성
system("cls");
cout << "******로비******" << endl;
cout << "1. 맵" << endl;
cout << "2. 상점" << endl;
cout << "3. 가방" << endl;
cout << "4. 종료" << endl;
cout << "메뉴를 선택하세요! : ";
int imenu;
cin >> imenu;
if (cin.fail())
{
cin.clear();
cin.ignore(1024, '\n');
continue;
}
if (imenu == MM_EXIT)
{
break;
}
}
return 0;
}
- main 함수에 while문을 이용해 종료되지 않도록 구성
- 플레이어가 메뉴를 선택할 수 있도록 구성

- 현재 4번을 누르면 종료되고 나머진 다시 선택하도록 되어 있음
맵 선택지 추가
enum MM_TYPE
{
MT_NONE,
MT_EASY,
MT_NORMAL,
MT_HARD,
MT_BACK
};
- enum(열거체)로 맵 선택시 선택지 추가
//메뉴에 따른 처리
switch (imenu)
{
//맵 선택
case MM_MAP:
while (true)
{
system("cls");
cout << "******맵******" << endl;
cout << "1. 쉬움" << endl;
cout << "2. 보통" << endl;
cout << "3. 어려움" << endl;
cout << "4. 뒤로가기" << endl;
cout << "난이도를 선택해 주세요 : ";
cin >> imenu;
if (cin.fail())
{
cin.clear();
cin.ignore(1024, '\n');
continue;
}
//이 if문은 맵 메뉴를 돌려주기 위한 while에 속해 있으므로 이 while문을 빠져나감
if (imenu == MT_BACK)
{
break;
}
}
break;
case MM_STORE:
break;
case MM_INVENTORY:
break;
default:
break;
}
- while문을 이용해 각각 enum에 따른 처리 구성
- MAP에 while문을 이용해 선택지 추가



- 1번 선택시 맵으로 가고 -> 맵에서 4번 선택시 -> 로비로 잘 감
플레이어 구조체 추가
enum JOB
{
JOB_NONE,
JOB_KNIGHT,
JOB_ARCHER,
JOB_WIZARD,
JOB_END
};
#define NAME_SIZE 32
struct _tagPlayer
{
char strName[NAME_SIZE];
char strJobNAME[NAME_SIZE];
JOB eJob;
int iAttackMin;
int iAttackMax;
int iArmorMin;
int iArmorMax;
int iHp;
int iHpMax;
int iMP;
int iMPMax;
int iExp;
int iLevel;
};
- 플레이어의 직업으로 enum추가
- 각 필요한 요소들 추가
- min, max값은 범위값으로 주기 위함
몬스터 구조체 추가
struct _tagMonster
{
char strName[NAME_SIZE];
int iAttackMin;
int iAttackMax;
int iArmorMin;
int iArmorMax;
int iHp;
int iHpMax;
int iMP;
int iMPMax;
int iExp;
int iLevel;
int iGoleMin;
int iGoleMax;
};
- 몬스터에게 iGold는 몬스터 처지 시 획득용
- 나머지는 비슷
캐릭터 생성
int main()
{
srand((unsigned int)time(0));
//게임 시작할때 플레이어 정보 설정
_tagPlayer tPlayer = {};
//이름 설정
cout << "이름 : ";
//끝까지 문자열을 다 채워버리면 null을 인식 못하기 때문
cin.getline(tPlayer.strName, NAME_SIZE - 1);
//직업 설정
int iJob = JOB_NONE;
while (iJob == JOB_NONE)
{
system("cls");
cout << "1. 기사" << endl;
cout << "2. 궁수" << endl;
cout << "3. 마법사" << endl;
cout << "직업을 선택하세요 : " << endl;
if (cin.fail())
{
cin.clear();
cin.ignore(1024, '\n');
continue;
}
else if (iJob <= JOB_NONE || iJob >= JOB_END)
{
iJob = JOB_NONE;
}
//직업 이름
tPlayer.eJob = (JOB)iJob;
switch (tPlayer.eJob)
{
case JOB_KNIGHT:
strcpy_s(tPlayer.strJobNAME, "기사");
tPlayer.iAttackMin = 5;
tPlayer.iAttackMax = 10;
tPlayer.iArmorMin = 15;
tPlayer.iArmorMin = 20;
tPlayer.iHpMax = 500;
tPlayer.iHp = 500;
tPlayer.iMP = 100;
tPlayer.iMPMax = 100;
break;
case JOB_ARCHER:
strcpy_s(tPlayer.strJobNAME, "궁수");
tPlayer.iAttackMin = 10;
tPlayer.iAttackMax = 15;
tPlayer.iArmorMin = 10;
tPlayer.iArmorMin = 15;
tPlayer.iHpMax = 400;
tPlayer.iHp = 400;
tPlayer.iMP = 200;
tPlayer.iMPMax = 200;
break;
case JOB_WIZARD:
strcpy_s(tPlayer.strJobNAME, "마법사");
tPlayer.iAttackMin = 15;
tPlayer.iAttackMax = 20;
tPlayer.iArmorMin = 5;
tPlayer.iArmorMin = 10;
tPlayer.iHpMax = 300;
tPlayer.iHp = 300;
tPlayer.iMP = 300;
tPlayer.iMPMax = 300;
break;
}
tPlayer.iLevel = 1;
tPlayer.iExp = 0;
}
...생략
- 캐릭터 이름, 직업 선택 후 각 직업별 능력치 추가
몬스터 생성
...생략
tPlayer.iLevel = 1;
tPlayer.iExp = 0;
}
//몬스터 생성
_tagMonster tMonsterArr[MT_BACK - 1] = {};
//고블린 생성
strcpy_s(tMonsterArr[0].strName, "고블린");
tMonsterArr[0].iAttackMin = 20;
tMonsterArr[0].iAttackMax = 30;
tMonsterArr[0].iArmorMin = 2;
tMonsterArr[0].iArmorMax = 5;
tMonsterArr[0].iHp = 100;
tMonsterArr[0].iHpMax = 100;
tMonsterArr[0].iMP = 10;
tMonsterArr[0].iMPMax = 10;
tMonsterArr[0].iLevel = 1;
tMonsterArr[0].iExp = 1000;
tMonsterArr[0].iGoleMin = 500;
tMonsterArr[0].iGoleMax = 1500;
//트롤 생성
strcpy_s(tMonsterArr[1].strName, "트롤");
tMonsterArr[1].iAttackMin = 80;
tMonsterArr[1].iAttackMax = 130;
tMonsterArr[1].iArmorMin = 60;
tMonsterArr[1].iArmorMax = 90;
tMonsterArr[1].iHp = 2000;
tMonsterArr[1].iHpMax = 2000;
tMonsterArr[1].iMP = 100;
tMonsterArr[1].iMPMax = 100;
tMonsterArr[1].iLevel = 5;
tMonsterArr[1].iExp = 7000;
tMonsterArr[1].iGoleMin = 6000;
tMonsterArr[1].iGoleMax = 8000;
//드래곤 생성
strcpy_s(tMonsterArr[2].strName, "드래곤");
tMonsterArr[2].iAttackMin = 250;
tMonsterArr[2].iAttackMax = 500;
tMonsterArr[2].iArmorMin = 200;
tMonsterArr[2].iArmorMax = 400;
tMonsterArr[2].iHp = 30000;
tMonsterArr[2].iHpMax = 30000;
tMonsterArr[2].iMP = 20000;
tMonsterArr[2].iMPMax = 20000;
tMonsterArr[2].iLevel = 10;
tMonsterArr[2].iExp = 30000;
tMonsterArr[2].iGoleMin = 20000;
tMonsterArr[2].iGoleMax = 50000;
while (true)
{
//로비 구성
...생략
- 각 몬스터 별로 셋팅
난이도 별 전투
...생략
}
//이 if문은 맵 메뉴를 돌려주기 위한 while에 속해 있으므로 이 while문을 빠져나감
if (imenu == MT_BACK)
{
break;
}
//선택한 메뉴 1을 빼주면 몬스터 배열의 인덱스가 된다
//그렇게 해서 해당 맵의 몬스터 생성
_tagMonster tMonster = tMonsterArr[imenu - 1];
//전투 시작
while (true)
{
switch (imenu)
{
case MT_EASY:
cout << "********* 쉬움 *********" << endl;
break;
case MT_NORMAL:
cout << "********* 보통 *********" << endl;
break;
case MT_HARD:
cout << "********* 어려움 *********" << endl;
break;
}
}
}
break;
case MM_STORE:
...생략
- 맵 선택 후 각 난이도별 처리용 swich문 추가
최종코드
#include <iostream>
#include <time.h>
using namespace std;
enum MAIN_MENU
{
MM_NONE,
MM_MAP,
MM_STORE,
MM_INVENTORY,
MM_EXIT
};
enum MM_TYPE
{
MT_NONE,
MT_EASY,
MT_NORMAL,
MT_HARD,
MT_BACK
};
enum JOB
{
JOB_NONE,
JOB_KNIGHT,
JOB_ARCHER,
JOB_WIZARD,
JOB_END
};
#define NAME_SIZE 32
struct _tagPlayer
{
char strName[NAME_SIZE];
char strJobNAME[NAME_SIZE];
JOB eJob;
int iAttackMin;
int iAttackMax;
int iArmorMin;
int iArmorMax;
int iHp;
int iHpMax;
int iMP;
int iMPMax;
int iExp;
int iLevel;
};
struct _tagMonster
{
char strName[NAME_SIZE];
int iAttackMin;
int iAttackMax;
int iArmorMin;
int iArmorMax;
int iHp;
int iHpMax;
int iMP;
int iMPMax;
int iExp;
int iLevel;
int iGoleMin;
int iGoleMax;
};
int main()
{
srand((unsigned int)time(0));
//게임 시작할때 플레이어 정보 설정
_tagPlayer tPlayer = {};
//이름 설정
cout << "이름 : ";
//끝까지 문자열을 다 채워버리면 null을 인식 못하기 때문
cin.getline(tPlayer.strName, NAME_SIZE - 1);
//직업 설정
int iJob = JOB_NONE;
while (iJob == JOB_NONE)
{
system("cls");
cout << "1. 기사" << endl;
cout << "2. 궁수" << endl;
cout << "3. 마법사" << endl;
cout << "직업을 선택하세요 : " << endl;
if (cin.fail())
{
cin.clear();
cin.ignore(1024, '\n');
continue;
}
else if (iJob <= JOB_NONE || iJob >= JOB_END)
{
iJob = JOB_NONE;
}
//직업 이름
tPlayer.eJob = (JOB)iJob;
switch (tPlayer.eJob)
{
case JOB_KNIGHT:
strcpy_s(tPlayer.strJobNAME, "기사");
tPlayer.iAttackMin = 5;
tPlayer.iAttackMax = 10;
tPlayer.iArmorMin = 15;
tPlayer.iArmorMin = 20;
tPlayer.iHpMax = 500;
tPlayer.iHp = 500;
tPlayer.iMP = 100;
tPlayer.iMPMax = 100;
break;
case JOB_ARCHER:
strcpy_s(tPlayer.strJobNAME, "궁수");
tPlayer.iAttackMin = 10;
tPlayer.iAttackMax = 15;
tPlayer.iArmorMin = 10;
tPlayer.iArmorMin = 15;
tPlayer.iHpMax = 400;
tPlayer.iHp = 400;
tPlayer.iMP = 200;
tPlayer.iMPMax = 200;
break;
case JOB_WIZARD:
strcpy_s(tPlayer.strJobNAME, "마법사");
tPlayer.iAttackMin = 15;
tPlayer.iAttackMax = 20;
tPlayer.iArmorMin = 5;
tPlayer.iArmorMin = 10;
tPlayer.iHpMax = 300;
tPlayer.iHp = 300;
tPlayer.iMP = 300;
tPlayer.iMPMax = 300;
break;
}
tPlayer.iLevel = 1;
tPlayer.iExp = 0;
}
//몬스터 생성
_tagMonster tMonsterArr[MT_BACK - 1] = {};
//고블린 생성
strcpy_s(tMonsterArr[0].strName, "고블린");
tMonsterArr[0].iAttackMin = 20;
tMonsterArr[0].iAttackMax = 30;
tMonsterArr[0].iArmorMin = 2;
tMonsterArr[0].iArmorMax = 5;
tMonsterArr[0].iHp = 100;
tMonsterArr[0].iHpMax = 100;
tMonsterArr[0].iMP = 10;
tMonsterArr[0].iMPMax = 10;
tMonsterArr[0].iLevel = 1;
tMonsterArr[0].iExp = 1000;
tMonsterArr[0].iGoleMin = 500;
tMonsterArr[0].iGoleMax = 1500;
//트롤 생성
strcpy_s(tMonsterArr[1].strName, "트롤");
tMonsterArr[1].iAttackMin = 80;
tMonsterArr[1].iAttackMax = 130;
tMonsterArr[1].iArmorMin = 60;
tMonsterArr[1].iArmorMax = 90;
tMonsterArr[1].iHp = 2000;
tMonsterArr[1].iHpMax = 2000;
tMonsterArr[1].iMP = 100;
tMonsterArr[1].iMPMax = 100;
tMonsterArr[1].iLevel = 5;
tMonsterArr[1].iExp = 7000;
tMonsterArr[1].iGoleMin = 6000;
tMonsterArr[1].iGoleMax = 8000;
//드래곤 생성
strcpy_s(tMonsterArr[2].strName, "드래곤");
tMonsterArr[2].iAttackMin = 250;
tMonsterArr[2].iAttackMax = 500;
tMonsterArr[2].iArmorMin = 200;
tMonsterArr[2].iArmorMax = 400;
tMonsterArr[2].iHp = 30000;
tMonsterArr[2].iHpMax = 30000;
tMonsterArr[2].iMP = 20000;
tMonsterArr[2].iMPMax = 20000;
tMonsterArr[2].iLevel = 10;
tMonsterArr[2].iExp = 30000;
tMonsterArr[2].iGoleMin = 20000;
tMonsterArr[2].iGoleMax = 50000;
while (true)
{
//로비 구성
system("cls");
cout << "******로비******" << endl;
cout << "1. 맵" << endl;
cout << "2. 상점" << endl;
cout << "3. 가방" << endl;
cout << "4. 종료" << endl;
cout << "메뉴를 선택하세요! : ";
int imenu;
cin >> imenu;
if (cin.fail())
{
cin.clear();
cin.ignore(1024, '\n');
continue;
}
if (imenu == MM_EXIT)
{
break;
}
//메뉴에 따른 처리
switch (imenu)
{
//맵 선택
case MM_MAP:
while (true)
{
system("cls");
cout << "******맵******" << endl;
cout << "1. 쉬움" << endl;
cout << "2. 보통" << endl;
cout << "3. 어려움" << endl;
cout << "4. 뒤로가기" << endl;
cout << "난이도를 선택해 주세요 : ";
cin >> imenu;
if (cin.fail())
{
cin.clear();
cin.ignore(1024, '\n');
continue;
}
//이 if문은 맵 메뉴를 돌려주기 위한 while에 속해 있으므로 이 while문을 빠져나감
if (imenu == MT_BACK)
{
break;
}
//선택한 메뉴 1을 빼주면 몬스터 배열의 인덱스가 된다
//그렇게 해서 해당 맵의 몬스터 생성
_tagMonster tMonster = tMonsterArr[imenu - 1];
//전투 시작
while (true)
{
switch (imenu)
{
case MT_EASY:
cout << "********* 쉬움 *********" << endl;
break;
case MT_NORMAL:
cout << "********* 보통 *********" << endl;
break;
case MT_HARD:
cout << "********* 어려움 *********" << endl;
break;
}
}
}
break;
case MM_STORE:
break;
case MM_INVENTORY:
break;
default:
break;
}
}
return 0;
}
반응형
'C++ > C++입문' 카테고리의 다른 글
[C++] 3. TextPRG 상점 제작 (0) | 2025.04.01 |
---|---|
[C++] 2. TextRPG 전투 (0) | 2025.03.30 |
[C++] 구조체와 문자열 (0) | 2025.03.28 |
[C++] 빙고 게임 하드모드 (0) | 2025.03.27 |
[C++] 빙고 게임_3 (0) | 2025.03.26 |