무작정 배우는 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);

                                       

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

                                        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

 

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수
1 [no code 게임개발] PlayMaker 요약 file 졸리운_곰 2025.03.05 250
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED