목차
서론
C++ 구조체, 배열 활용 연습할 겸 텍스트 기반 RPG 게임을 만들어 봤습니다
사실 기능은 진짜없는데도 소스가 750줄이 넘네요
현재 기능은 간단한 탐색, 아이템 사용, 인벤토리 정도밖에 없습니다
몬스터와 턴제 전도 구현하고 싶긴 한데 가능할지는 잘 모르겠네요
사용자의 선택지에 따라서 게임이 진행되고, 특정 선택지는 체력이 깎이거나 배드 엔딩으로 갈 수 있습니다.
전체소스는 깃허브 링크에 공개되어 있습니다
소스가 긴 관계로 포스트에서는 핵심적인 내용만 정리하겠습니다
게임소개
게임 목적은 죽지않도록 주의하며 엔딩조건을 만족시키면 됩니다
처음 시작하면 캐릭터의 이름을 짓고 직업을 선택합니다.
직업별로 스탯은 다릅니다. 참고로 지금 공격력이나 마법 관련 스탯은 존재하긴 하는데 기능을 안합니다
메뉴는 인벤토리, 캐릭터, 탐색하기, 게임 종료의 4가지 입니다.
위 아래 방향키로 조작해서 엔터눌러서 선택하시면 됩니다
인벤토리에는 현재 보유한 아이템의 종류와 수량이 뜹니다.
설명과 같이 숫자 키를 눌러 아이템 번호를 입력하면 해당 아이템이 사용됩니다.
(예: 해당 이미지에서 0 을 누르면 [파란물약] 이 사용됨)
아이템 설명은 간단하게 써 드리겠습니다
얻을 확률이 낮은 아이템도 2종 있는데 이건 빼고 쓰겠습니다
종류 | 설명 |
빨간 물약 | Hp를 10 회복합니다 |
파란 물약 | Mp를 10 회복합니다 (현재 Mp는 기능없음) |
이상한 사탕 | 레벨을 1 증가시킵니다 (현재 레벨은 기능없음) |
물 | 아무 효과가 없습니다 |
독약 | Hp가 100 감소합니다 |
아이템 사용시 다음과 같이 설명과 효과를 표시합니다
캐릭터 선택 시 현재 캐릭터 정보를 표시 합니다
참고로 Hp가 0이 되면 게임 오버됩니다
탐색하기는 아이템 획득, 함정, 특수이벤트의 이벤트가 일어납니다
함정 이벤트의 경우 체력이 하락하기 때문에 Hp관리에 주의하셔야겠습니다.
엔딩조건에 도달하면 게임이 종료됩니다.
엔딩 종류는 총 7개로, 이중 배드엔딩은 4개입니다
보물을 찾는 것 외에도 히든엔딩이 2개 있고, 배드엔딩중에서도 히든엔딩이 하나 있습니다
궁금하면 한번 해보시거나 깃허브 소스를 확인해보세요
소스코드(핵심 부분만)
먼저 인벤토리, 캐릭터, 아이템 정보는 구조체로 선언되어 있습니다.
인벤토리 - 아이템 정보는 아이템 번호가 키값이라고 생각하시면 됩니다.
struct MyCharacter
{
int intLevel;
string strName;
int intHP;
int intMp;
int intAttack;
int intMagic;
};
struct Inventorty
{
int intItemNo;
int intItemCount;
};
struct Iteminfo
{
int intItemNo;
string strItemName;
int RestoreHp;
int RestoreMp;
int Levelup;
};
아이템의 정보를 등록해주는 함수, 및 초기 인벤토리를 설정해 주는 함수입니다.
void ItemMaster()
{
// itemcode, itemname, hp , mp, level
iteminfo[0] = { 0,"빨간물약",10,0,0 };
iteminfo[1] = { 1,"파란물약",0,10,0 };
iteminfo[2] = { 2,"이상한사탕",0,0,1 };
iteminfo[3] = { 3,"물",0,0,0 };
iteminfo[4] = { 4,"독약",-100,0,0 };
iteminfo[5] = { 5,"복권",0,0,0 };
iteminfo[6] = { 6,"데스노트",0,0,0 };
}
void InvenFirst()
{
MyInven[0] = { 0,0 };
MyInven[1] = { 0,0 };
MyInven[2] = { 0,0 };
MyInven[3] = { 0,0 };
MyInven[4] = { 0,0 };
MyInven[5] = { 0,0 };
MyInven[6] = { 0,0 };
}
방향키로 조작하는 메뉴를 보여주는 코드입니다
메뉴 목록에 {종료하기, 돌아가기}를 넣은 후
pointerPosition 값에 따라(사용자가 상 하로 이동하며 정할수있는 현재 위치)
엔터 시 선택한 메뉴별로 처리합니다.
cout << "-- 종료하시겠습니까? --" << endl;
vector<string> menuItems = { "종료하기", "돌아가기" };
int pointerPosition = 0;
while (true)
{
system("cls");
for (int i = 0; i < menuItems.size(); i++)
{
if (i == pointerPosition)
{
cout << ">> " << menuItems[i] << endl;
}
else {
cout << " " << menuItems[i] << endl;
}
}
// 키 입력 대기
int key = _getch();
// 위쪽 방향키
if (key == 72)
{
pointerPosition = (pointerPosition - 1 + menuItems.size()) % menuItems.size();
}
// 아래쪽 방향키
else if (key == 80)
{
pointerPosition = (pointerPosition + 1) % menuItems.size();
}
// Enter 키
else if (key == 13)
{
// 종료하기
if (pointerPosition == 0)
{
cout << "프로그램을 종료합니다." << endl;
return 0;
}
// 돌아가기
if (pointerPosition == 1)
{
break;
}
}
}
아이템을 얻었을 때 인벤토리에 추가하는 코드입니다.
지금 보니 인벤토리 개수 늘리고 코드를 안바꿔서 안맞는 부분이 있네요...
루프를 돌며 인벤토리에 IntItemno 를 기준으로 탐색하고 인벤토리에 추가하거나 수량을 +1 시킵니다
void AddInvent(int ItemNo, int ItemCount)
{
// 특수 엔딩에 사용되는 변수
if (ItemNo == 5)
{
isLotto = true;
}
// 먼저 인벤토리에 같은 아이템이 있는지 확인
for (int i = 0; i < 5; i++)
{
if (MyInven[i].intItemNo == ItemNo) // 이미 존재하는 아이템 번호라면
{
MyInven[i].intItemCount += ItemCount; // 수량을 추가
cout << iteminfo[ItemNo].strItemName + " " + to_string(ItemCount) + "개 추가." << endl;
return; // 함수 종료
}
}
// 인벤토리에 동일한 아이템이 없으면 빈 슬롯에 추가
for (int i = 0; i < 5; i++)
{
if (MyInven[i].intItemCount == 0) // 빈 슬롯 찾기
{
MyInven[i].intItemNo = ItemNo;
MyInven[i].intItemCount = ItemCount;
// 아이템 정보 출력
for (int j = 0; j < 10; j++)
{
if (iteminfo[j].intItemNo == ItemNo)
{
cout << iteminfo[j].strItemName + " " + to_string(ItemCount) + "개 획득." << endl;
return;
}
}
}
}
}
인벤토리 확인 함수입니다.
현재 가지고 있는 아이템 종류/ 개수를 표시합니다.
아이템이 하나도 없다면 비어 있음 으로 표시 합니다.
void ShowMyInvent()
{
int intCount = 0;
cout << "**** 인벤토리 ****" << endl;
cout << " ( ※ 아이템 번호를 입력하면 사용 가능합니다. (0~ 4))" << endl;
cout << " ( 돌아가기: 0~4를 제외한 아무 키를 누르면 돌아갑니다.)" << endl;
for (int i = 0; i < 5; i++)
{
if (MyInven[i].intItemCount>0)
{
for (int j = 0; j < 10; j++)
{
if (MyInven[i].intItemNo == iteminfo[j].intItemNo)
{
cout << to_string(i)+":"+ iteminfo[j].strItemName + "/" + to_string(MyInven[i].intItemCount) + "개" << endl;
intCount++;
break;
}
}
}
}
if (intCount == 0)
{
cout << "비어 있음." << endl;
}
}
아이템 사용 함수 코드 중 일부입니다.
먼저 인벤토리 에 있는 아이템 수량을 차감합니다.
그리고 사용된 아이템 번호(useItemNo) 를 기준으로 해당되는 아이템의 아이템 정보를 가져옵니다
해당 아이템에 따라 Mp, Hp,레벨 값을 증감시킵니다
만약 Hp가 0 이 된다면 (if (MyCh.intHP <= 0) 부분)
배드엔딩으로 보냅니다. GameEnding()은 엔딩을 처리하는 함수입니다
MyInven[InventNo].intItemCount--;
for (int i = 0; i < 10; i++)
{
if (useItemNo == iteminfo[i].intItemNo)
{
MyCh.intHP = MyCh.intHP + iteminfo[i].RestoreHp;
MyCh.intMp = MyCh.intMp + iteminfo[i].RestoreMp;
MyCh.intLevel = MyCh.intLevel + iteminfo[i].Levelup;
if (iteminfo[i].RestoreHp != 0)
{
string strStatus;
if (iteminfo[i].RestoreHp > 0)
{
strStatus = "증가";
}
else
{
strStatus = "감소";
// 독으로 인한 데미지
lastDamage = 0;
}
cout << "-- Hp: " << iteminfo[i].RestoreHp << " " << strStatus << " / Hp: " << MyCh.intHP << endl;
}
if (iteminfo[i].RestoreMp != 0)
{
string strStatus;
if (iteminfo[i].RestoreMp > 0)
{
strStatus = "증가";
}
else
{
strStatus = "감소";
}
cout << "-- Mp: " + to_string(iteminfo[i].RestoreMp) + " " + strStatus + "/ Mp: " + to_string(MyCh.intMp) << endl;
}
if (iteminfo[i].Levelup != 0)
{
string strStatus;
if (iteminfo[i].Levelup > 0)
{
strStatus = "증가";
}
else
{
strStatus = "감소";
}
cout << "-- 레벨: " + to_string(iteminfo[i].Levelup) + " " + strStatus + "/ 레벨: " + to_string(MyCh.intLevel) << endl;
}
if (MyCh.intHP <= 0)
{
GameEnding(lastDamage, false);
}
return;
}
}
전체코드(링크)
나머지 코드는 하단 깃허브 링크를 참조 부탁드립니다
텍스트rpg 게임 실행 파일은 첨부파일에 있습니다.
https://github.com/Chaeyunbyun/GameProject_Test/blob/master/GameProject_Test.cpp
GameProject_Test/GameProject_Test.cpp at master · Chaeyunbyun/GameProject_Test
Contribute to Chaeyunbyun/GameProject_Test development by creating an account on GitHub.
github.com
'연습 프로젝트' 카테고리의 다른 글
텍스트 RPG 게임 만들기-3 (C++) (0) | 2025.03.26 |
---|---|
텍스트 RPG 게임 만들기-2 (C++) (2) | 2025.03.14 |