- 전체
- 게임 일반 (make game basics)
- 모바일 기획 및 디자인
- GameMaker Studio
- Unity3D
- Cocos2D
- 3D Engine OGRE
- 3D Engine irrlicht
- copperCube
- corona SDK
- Windows Basic Game
- BaaS (Mobile Backend)
- phnegap & cordova
- ionic & anguler
- parse (backend)
- firebase (backend)
- Game Backend Server / Opt
- web assembly
- Smart Makers
- pyGame & Ren'Py
- 머드(MUD) 게임 만들기
- Xamarin(자마린)
- flutter (플루터 앱 개발)
- construct 2 / 3
- pocketbase
- RPG Maker 시리즈
- godot engine
- playmaker(unity)
- react native
머드(MUD) 게임 만들기 무작정 배우는 C언어 머드(MUD)게임 만들기 Part5 게임스랩
2020.10.17 23:58
무작정 배우는 C언어 머드(MUD)게임 만들기 Part5 게임스랩
예제 게임 소스 : MUD_TurtleAdventure(5).zip
자~ 이번 시간에는 드디어 몬스터와의 전투입니다. 사실 이번 포스팅부터는 여러분의 상상에 따라 코드의 내용도 천차만별이라 이렇게 글을 쓰는 것이 도움이 될까라는 생각도 해봤습니다. 기본적인 문법들은 거의 다 소개했기 때문에 이제는 여러분들의 몫이라고 생각됩니다. 그래도 아직 잘 모르겠다는 분들도 혹시 있을지 몰라 이렇게 소개하게 되는군요.
바로 본론으로 넘어가겠습니다. 전투를 위해서는 내 공격력, 방어력 등과 몬스터의 공격력, 방어력 등의 수치들을 이용해 여러분만의 전투 공식을 만들어 hp, mp등을 소모 시켜주는 형태가 가장 기본이라 하겠습니다. 우선 전체적인 코드를 보겠습니다.
void checkBattle()
{
if(g_map[g_player.PosX][g_player.PosY].monsterIndex != -1)
{
int _monsterHP = g_monster[g_map[g_player.PosX][g_player.PosY].monsterIndex].hp;
while(1)
{
//몬스터가주는데미지
int _monsterDamage = g_player.DEF - g_monster[g_map[g_player.PosX][g_player.PosY].monsterIndex].atk;
if(_monsterDamage >= 0)
_monsterDamage = -1;
bool _monsterCri = false;
bool _playerCri = false;
//크리티컬처리
int _prob = rand()%100;
if(g_monster[g_map[g_player.PosX][g_player.PosY].monsterIndex].criPro > _prob)
{
_monsterDamage = _monsterDamage * 2;
_monsterCri = true;
}
g_player.HP = g_player.HP + _monsterDamage;
//플레이어가주는데미지
int _playerDamage = g_monster[g_map[g_player.PosX][g_player.PosY].monsterIndex].def - g_player.ATK;
if(_playerDamage >= 0)
_playerDamage = -1;
//크리티컬처리
_prob = rand()%100;
if(g_player.CriProb > _prob)
{
_playerDamage = _playerDamage * 2;
_playerCri = true;
}
g_monster[g_map[g_player.PosX][g_player.PosY].monsterIndex].hp = g_monster[g_map[g_player.PosX][g_player.PosY].monsterIndex].hp + _playerDamage;
char tmp[256] = "";
if(_playerCri == true)
sprintf_s(tmp, 256, "%s은(는) %d의크리티컬데미지를주었습니다.\n", g_player.name,-_playerDamage);
else
sprintf_s(tmp, 256, "%s은(는) %d데미지를주었습니다.\n", g_player.name,-_playerDamage);
battleMessage(tmp);
Sleep(1000);
if(_monsterCri == true)
sprintf_s(tmp, 256, "%s은(는) %d의크리티컬데미지를주었습니다.\n", g_monster[g_map[g_player.PosX][g_player.PosY].monsterIndex].name, -_monsterDamage);
else
sprintf_s(tmp, 256, "%s은(는) %d데미지를주었습니다.\n", g_monster[g_map[g_player.PosX][g_player.PosY].monsterIndex].name, -_monsterDamage);
battleMessage(tmp);
Sleep(1000);
if(g_player.HP <= 0)
{
char tmp[256] = "";
sprintf_s(tmp, 256, "%s은(는) 죽었습니다.\n\n", g_player.name);
battleMessage(tmp);
break;
}
if(g_monster[g_map[g_player.PosX][g_player.PosY].monsterIndex].hp <= 0)
{
char tmp[256] = "";
sprintf_s(tmp, 256, "%s은(는) 죽었습니다.\n\n", g_monster[g_map[g_player.PosX][g_player.PosY].monsterIndex].name);
g_monster[g_map[g_player.PosX][g_player.PosY].monsterIndex].hp = _monsterHP;
battleMessage(tmp);
break;
}
}
}
else
{
battleMessage("대상이없습니다.\n\n");
}
}
void checkBattle() 함수는
case COMMAND_ATTACK:
{
checkBattle();
}
break;
위와 같이 공격이란 명령을 받은 순간 공격할 대상이 있는지를 찾고 있다면 전투공식을 이용해 전투를 진행하는 함수입니다. if(g_map[g_player.PosX][g_player.PosY].monsterIndex != -1) 를 이용해 현재 몬스터가 있는 확인을 한후에 while(1) { …중략 …} 에서 둘중 하나가 쓰러질 때까지 전투공식을 무한으로 실행시킵니다.
//몬스터가주는데미지
int _monsterDamage = g_player.DEF - g_monster[g_map[g_player.PosX][g_player.PosY].monsterIndex].atk;
간단하게 저는 플레이어의 방어력과 몬스터의 공격력의 수치의 차이를 데미지로 계산해봤습니다. 이런 공식은 여러분의 의도대로 만드시면 되겠습니다.
int _prob = rand()%100;
이 부분에서 처음 보는 함수인 rand() 입니다. 난수를 발생시켜주는 함수입니다. 뒤에 %100을 하면 0~99 사이의 수를 발생시키겠다는 뜻입니다. 만약 %1000 이라면?
그렇습니다. 바로 0~999 사이의 수를 한 개를 생성해줍니다. 많은 게임들이 랜덤적인 요소를 사용할 때 사용하는 부분입니다. 저는 이걸 이용해서 크리티컬 부분을 구현한 것이지요.
그 다음 또 새로 보이는 Sleep(1000); 코드가 있습니다. 이 함수의 용도는 지정된 시간동안 잠시 프로그램을 지연시키는 것입니다. 괄호안의 숫자의 단위는 시간 단위 ms 입니다. 1000=1초 인것이지요.
즉, 1초마다 한번씩 데미지를 주도록 만든것입니다. Sleep(1000); 을 사용하지 않는다면 공격 이후의 메시지 표시는 순식간에 나타나고 전투는 눈깜짝할 사이에 끝나게 됩니다. 하지만 전투의 재미를 주기 1초에 한번씩 데미지의 모습을 보여주며 플레이하게끔 한 것이지요. 첨부된 소스를 실행해보시면 감이 잡히실겁니다. Sleep(1000); 부분을 // 주석처리 하고 실행해보면 비교가 되겠지요?
나머지 코드들은 굳이 설명하지 않아도 이해하리라 믿습니다. 그럼 전체적인 결과가 어떤지 다음 화면을 보겠습니다.

<이미지를 클릭하시면 더 자세히 보실 수 있습니다.>
위와 같이 이동을 하여 몬스터를 만나고 “공격” 이란 명령을 통해 서로 공격하는 장면입니다. 왼쪽은 크리티컬이 발생안한 경우입니다. 오른쪽은 다시 한번 싸웠더니 크리티컬이 발생했습니다. 이처럼 확률을 이용하면 게임을 좀 더 재미있게 만들 수 있습니다. 또한 데미지가 똑같은게 싫다면 범위값을 두어서 다양하게 데미지가 나올 수 있도록 할 수도 있습니다. 예를 들면 캐릭터 공격력을 변수 하나로만 하는 것이 아니라 MAX_ATK 와 MIN_ATK 처럼 최대, 최소값을 가지게 만들고 이 사이에서 공격력을 발생시키면 좀 더 그럴싸한 게임이 되겠죠?
다시 한번 말씀드리자면 위의 코드들이 잘 작성된 것도 아니고 보편적인것이라고 말하기도 힘듭니다. 하나의 예시를 보여준 것에 불과한 것이니 굳이 저런 형식에 얽매이지 않으셔도 됩니다. 이 글의 목적은 게임을 만들어 보는 것을 통해 c언어를 좀 더 쉽게 접근해 보자는 취지였지요. 기본적인 문법들에 대해선 상세하진 않으나 소개가 되었고 게임의 진행도 여기까지 이어져 왔습니다.
지금까지 소개한 것으로도 여러분들이 나머지 부분들을 충분히 완성할 수 있으리라 생각됩니다. 아이템 드랍, 장착, 이벤트, 가방 등… 게임에 필요한 여러분의 상상력을 c언어로 펄쳐보이세요. 여러분의 무한한 가능성과 도전으로 재밌는 게임을 만드시길 바라며 머드게임 만들기를 이만 마치도록 하겠습니다.
[출처] https://gameslab.tistory.com/m/93?category=486131
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
댓글 0
| 번호 | 제목 | 글쓴이 | 날짜 | 조회 수 |
|---|---|---|---|---|
| 1 |
[godot 엔진] 오픈 소스 고도 프로젝트 모음 - 고도 배우기, Godot
| 졸리운_곰 | 2024.12.16 | 338 |

