Airene HUE

aireneHue.egloos.com

포토로그 마이가든



c언어 : gotoxy 활용, 좌표측량 및 간단한 게임만들기. C언어





c언어를 공부하시는 분들이라면gotoxy에 대해서는 많이 들어보셨을겁니다.
콘솔창을 기반으로 하여 간단한 게임을 만들어볼때도 많이 쓰이고 좌표값을 측정해
프로그램를 시각적으로 디자인하는데도 자주 사용되는 개념이라
익숙하신분들도 많으실 개념이지요.

간단하게 콘솔창을 하나의 좌표로 보고 x,y값을 변경시켜 원하는 위치에
원하는 출력을 하기위한 방식이라고 생각하면 됩니다.
잘 정리된 함수를 미리 선언해두고 활용하면
콘솔창을 기반으로 한 간단한 게임도
만들어볼 수 있기에, 알아두면 재미있게c언어를 연습할 수 있는
유용한 함수라고 할 수 있지요
.

다만 역시 처음 사용하는 입장에서는 생각보다 다루기에 익숙하지 않은점이 있습니다.
단순히 좌표를 지정하고 출력하는것만으로는 다양하게 응용하기에는
부족한 감도 있구요.

그래서 이번 글에서는 gotoxy의 기본적인 사용법과 이를 응용해보는 내용을
정리해보기로 했습니다.





gotoxy 함수를 사용하는 방법부터 이런
간단한 게임을 만들어보는것까지 다루도록 하겠습니다.


참고 :  gotoxy함수는 이미 많은분들이 활용하고 계시는 것으로
         익숙하신분들은 이 글을 보실 필요가 없습니다.
       
         이 글은 gotoxy를 활용해보지 않으신 분들을 대상으로
         처음에 접할때 좀더 쉽게 다가갈 수 있도록 도움을 드리는 취지에서
         작성되었습니다.
        





프로젝트를 실행시켜주세요
헤더를 선언하시고
메인함수를 준비해봅시다.



gotoxy는 api쪽 함수입니다. 따라서 사용하기 위해서는
#include <windows.h>
를 선언해야 합니다.



참고 : 어디까지나 이 이야기는 Visual Studio를 사용하는 경우의 이야기입니다.
         Turbo C/C++을 사용하는분들은 헤더로

    
     #include
<stdio.h>

        #include  <conio.h>

       를 선언하시고 사용하시면 됩니다.
        (컴파일러의 차이로 생각하시면 되겠지요^^)





이제 gotoxy함수를 호출해옵시다.
저기 적힌 내용들은 api를 배우지 않는 입장에서는 자세히 알 필요가 없습니다.

어쨌건 사용하는데는 지장도 없고 선언만 해두면 C언어의 문법만으로 활용이 가능하니

그냥 복사해서 똑같이 넣으셔도 무방합니다.


Visual Studio 2010을 기준으로 붉은 밑줄이 스크린샷처럼
나타날 텐데요. 이건 무시해도 됩니다. 에러가 나지는 않습니다.

 


gotoxy(int x, int y)//gotoxy함수를 호출해올 기본함수.

{   

      COORD pos = {x, y};
      SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
 
}



gotoxy.txt

*코드입니다. 긁기를 방지해두었기때문에...
  메모장파일로 첨부해 두겠습니다.
  다운받으셔서 사용하세요





이제 바로 활용해보도록 할까요?
선언 후에는 이제 좌표가 다 지정된것처럼 자유롭게 활용하시면 됩니다.

스크린샷에서는gotoxy(10,10);이라고 좌표값을 적어 두었죠.
그럼 콘솔창을 하나의 좌표로 보고 X=10,Y=10 인 지점으로
가겠다는 의미가 됩니다.

그리고 뒤에 "테스트입니다!" 라고 printf 출력함수를 넣어주었습니다.
자 그럼 어떻게 되나 볼까요?





자 빌드하고 테스트해봤습니다 처음 위치에서 문자열을 출력하지 않죠?

입력해준 좌표 10,10으로 이동한 후에 거기서부터 printf함수로 출력해는것을
확인할 수 있습니다.




   *  기본 콘솔창에서의 좌표값에 대해.....


  아무런 설정도 되지 않았을때에 기본으로 콘솔창의 크기는 가로 80 세로 24 설정되어있습니다.
  이 이야기는 gotoxy함수를 이용할때에도 기본적인 좌표계가

  x좌표가  0~79의 범위
  y좌표가  0~23의 범위

  로 초기화되어있다는 것을 의미합니다.
  (시작점이 0,0이기때문에 각각 1을 뺀 값이 좌표계의 한계값이 됩니다.)

  물론 이대로 고정되어 수정이 불가능하다면 활용의 폭이  매우 좁겠습니다만...

  콘솔창의 크기 자체를 수정할 수 있는 함수가 존재하므로 이를 통해서 해결해 줄 수 있습니다.
  콘솔창 크기 조절에 관해서는 앞선 포스팅에서 정리해두었으니 참고해주세요

  
  
  즉  mode con을 이용하여 콘솔창의 크기를 수정할 경우  좌표계가 크기에 따라서
  늘어나기도 하고 줄어들기도 한다는 점입니다.

  
            ex) system("mode con cols=92 lines=40"); 
                       
//cols = 칸/행 (가로)  lines = 줄/열 (세로)
  
                    로 설정했을 경우 가로에 해당하는 cols값이 92
                                               세로에 해당하는 lines값이 40
  
                            이 됨으로써 x좌표의 범위가 0~91가 되고
                                                y좌표의 범위가 0~39
이 됩니다.


   이런식으로 좌표계의 범위를 조절해 줄 수 있다는 것입니다.  좌표를 조절해준 뒤에는
   이제 원하는대로 작업할 수 있겠죠. 크기도 마음대로 조절하고 또 조절된 좌표계의 한계점까지
   명확히 알게 되니 작업하기는 수훨해지겠지요?

   괜히 좌표계니 범위니 하는 말들을 썼지만 그냥 단순하게 생각합시다.

   "아 창크기 크게 만들어서 뭐 많이 출력하고 꾸미고 할 수 있겠네?"  이런식으로 말이죠.
  





좌표를 원하는지점으로 이동시킨 뒤에 출력을 해보았으니 다음에는
이런 생각을 해볼 수 있겠죠?

"아 그런데 이런식으로 좌표를 일일이 지정해줘야되나? 그럼 여러가지 좌표들이
 함께 움직일때는 복잡해서 어떻게 하냐?"

저는 처음 gotoxy를 접했을때 이런생각을 했었답니다^^
하지만 다행히도 gotoxy함수의 좌표값을 입력하는 자리에는 "변수"를 넣어줄 수 있었습니다!






이런식으로 변수를 선언한뒤에 그 변수값 자체를 좌표값으로 이용할 수 있습니다.
해당 값을 직접 좌표값으로 입력해주었을때와 같은 결과를 출력합니다.

그러니까 이건 특정 좌표를 저장해 두고 각각의 좌표들이 필요할때는
언제든지 불러와 사용할 수 있다는 의미가 됩니다.





생각해볼까요?

자 저런식으로 변수를 4개 2개씩 하나의 좌표를 나타내도록 지정해 주었습니다.
"나"라던지 "적/나쁜놈"같은 글자는 저렇게 각각 다른 좌표를 나타내야 될때
응용하면 좋겠다는 의미로 넣어 보았습니다.

뭐 어찌되었건 결과를 봅시다.




색이 바뀐것은 textcolor함수를 이용했기 때문입니다.
관련 내용은 이전 포스팅에서 다루고 있으니 참고해주세요

이렇게 보면 각각 다른 좌표를 저장해두고 필요할때마다 불러와
쉽게 사용할 수 있다는 의미로 해석될 수 있겠죠.



이제 여기서 좀더 응용하면 특정 키보드키를 누를때마다

캐릭터가 움직이는듯한 모습을 연출할 수 있습니다!

아래의 코드를 참고해 봅시다.


 


#include <stdio.h>
#include
<windows.h>

#define UP 72
#define DOWN 80 //키보드 방향키의 아스키코드값을 정의해둔것입니다.
#define LEFT 75     //이런식으로 정의해두면 편하게 사용할 수 있습니다.
#define RIGHT 77

gotoxy(int x,int y) //gotoxy함수를 호출해올 기본함수.
{   
      COORD pos = {x, y};
      SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
 }

 int main(){
 
 int X=44,Y=22; //좌표값.
 int test;

 system("mode con cols=92 lines=40");
 
 
            while(1){
  
            test = getch(); //문자를 먼저 입력받습니다.
   
            switch (test){ //입력받은 문자에 따라서 스위치문을 구성합니다.
                                      
                        caseUP : gotoxy(X,Y);
                        printf("  "); //기존에 출력된 문자는 지우고
                        Y -= 1;        //좌표를 이동시킨 뒤에
                        gotoxy(X,Y);
                        printf("●"); //새로운 위치에 문자를 출력해줍니다
                        break;   //이렇게 해서 마치 문자가 움직이는듯한
                                     //효과를 만들 수 있습니다.
         
                        case DOWN : gotoxy(X,Y);
                        printf("  ");
                        Y += 1;
                        gotoxy(X,Y);
                        printf("●");
                        break;
     
                        case LEFT : gotoxy(X,Y);
                        printf("  ");
                        X -= 1;
                        gotoxy(X,Y);
                        printf("●");
                        break;
    
                        case RIGHT : gotoxy(X,Y); 
                        printf("  ");
                        X += 1;
                        gotoxy(X,Y);
                        printf("●");
                        break
                                   
                            }//switch닫음
   
            gotoxy(80,38);
            printf("%2d %2d",X,Y); //변수 X,Y는 좌표값이며                                          continue;                           // 유동적으로 변하는 값입니다.
                               //이를 출력시키는것으로 "좌표측량"이 가능합니다!

               } //while 닫음
  
        } //main 함수 닫음




 

그대로 옮겨서 한번 실행시켜볼까요?
제가 코드긁기를 방지해둔관계로.... 역시 메모장파일을 첨부합니다^^


      gotoxy_ex.txt
        (다운받아주세요)


다운받아서 그대로 복사해서 옮긴 뒤 한번 실행해 보세요^^
(기준은 Visual Studio를 기준으로 합니다. 다른 컴파일러라면 실행이 안될겁니다)

어떤가요? 방향키를 누르니까 거기에 맞춰서 공이 이동하는것처럼 보이지 않나요?

다만 아직 설정이 덜 되어 계속 이동하면 화면밖으로 튀어나는 일이 생길겁니다.
튀어나가도 좌표계는 그대로 존재합니다. 그냥 자꾸 값이 커져나갈 뿐이죠
그리고 콘솔창은 엉망이 됩니다.

이를 방지하는방법도 아랫쪽에 설명할 것입니다.  일단은 움직이는구나! 하고
한번 느껴만 주시면 좋겠습니다^^


대부분 설명은 코드에 주석으로 달아 두었습니다.
좌표를 이동시키면서 기존에 출력된 부분을 지우고 옮긴 좌표에
다시 출력해주는 방식을 이용해서 마치 공이 조작키에 따라서 움직이는것처럼
보이도록 만드는게 주안점이라고 할 수 있지요.

굳이 언급하지 않았던 부분은 앞부분에 #defile 으로 정의되어진 키보드값입니다.
각각 키보드의 방향키값에 해당되는 아스키코드값을 UP,DOWN등 우리가 알기 쉬운
문자로 정의해두는 것으로 아래에서 스위치문 등으로 활용할때 편하게 사용하기
위해 적은 것으로 생각하시면 됩니다.

강제 형변환 등을 이용해서 아스키코드값을 매번 적어가며 작성하는 방법도 있겠지만
그럴 바에는 저렇게 알기쉽게 조정해 두는것이 좋을 것입니다.



#define UP 72
#define
DOWN 80
#define LEFT 75 
#define
RIGHT 77

이들이 자주 사용되는 방향키값입니다.

위로(72) 아래로(80) 오른쪽(77) 왼쪽(75)
을 나타내는
아스키코드값으로 정의해둔 것이죠.

저렇게 선언만 해 두면 아래에서 switch문이라던가 if문 등을 통해
다양하게 응용할 수 있습니다.

#define ENTER 13
#define
ESC 27

추가로 더 알려드리자면 엔터는 아스키코드 13번
                                 ESC키는 아스키코드 27번

에 해당됩니다. 자주 사용될것 같아 추가로 알려드립니다^^

또 무한 while문 맨 아래에 이동후에 좌표값을 출력시키고 있음을 확인할수 있을것입니다.





gotoxy(80,38); //(80,38)의 위치로 가서
printf("%2d %2d",X,Y);  //현재 저장된 좌표변수의 값을 좀 출력해달라
continue;       //그리고 무한반복문 맨처음으로 돌아가서 다시 스위치문을 돌려라

이런식으로 이동 후 출력까지 완료한 후에 현재 x,y값에 저장된 좌표값 자체를 출력시키는 것이죠. 

뭔가 만들때 살짝 불러와서 좌표를 측정해두고

"아 이 위치에 뭘 출현시키면 되겠군!"
하고 조사하는 방식으로 이용됩니다. 출력시킬것을 다 출력한 다음에는
해당 코드를 지워서 없애주면 정리되겠죠.

사실 내용 자체는 아주 간단합니다. 저장된 변수의 값을 특정 위치에 출력시키는것에 지나지
않으니까요. 하지만 이렇게 화면 구석에 좌표값을 출력시키게 만들어주는것은 상당한 도움이
됩니다. 어느점은 무슨무슨 좌표구나 하는것을 알수 있게 되니 응용은 무궁무진하죠.

자 여기까지 했으니 이제 gotoxy를 처음 접하셨던 분들이라도
콘솔창에 움직이는 캐릭터를 출현시킬 수 있고 또 원하는 좌표에 원하는
문자열도 출력할 수 있게 되었을 것입니다.

마지막으로 응용해서 간단한 미로찾기라도 한번 만들어보면 어떨까요?
이를 소개하면서 아까 있었던 문제점인

"공이 화면 밖으로 탈출하는 오류"까지 해결해 봅시다^^




자 저런식으로 2차원 배열을 선언해볼까요?
선언된 2차원 배열을 일종의 좌표계로 생각하고
알맞은 문자열을 출력해서 맵으로 만듭니다.

참고 : 여기서 기준은map[Y좌표][X좌표]로 생각하시면 됩니다.
          2차원 배열 선언을 할때에는 뒤의 배열이 가로를
          앞의 배열이 세로를 나타내거든요.

          이렇게 좌표개념을 직관적으로 적용 가능한 2차원 배열이기에
          맵출력시 2차원 배열을 이용하는걸 추천해드립니다.
 
        




일단은 간단하게 1줄 부터 입력해 봤습니다. 먼저 1줄 해두고
계속 밑으로 내려가면서 2차원 배열을 추가로 초기화해주면 됩니다.






점점 길게 늘여쓰고있습니다.

보시면 아시겠지만 초기화할때 0,1을 이용해 다르게 초기화하는것을
확인할 수 있으실 텐데요, 이렇게 다르게 초기화해주기 위해서
일부러 2차원배열을 선언하고 일일이 숫자를 입력하고 있는 것이랍니다.

이쯤에서 배열 외에도 아래에 출력하는 부분도 살펴볼까요?

배열 선언후에 일단 콘솔창의 크기를 조절해주고
그다음에 2중 for문을 돌려서 별을 출력하고있습니다.

설명이 필요한 부분은 대부분 스크린샷의 주석에 남겨두었으니
스크린샷을 참고해주세요.

그밖에도 아예 코드 자체를 아래에 업로드해 둘테니
복사해서 Visual Studio 상에서 확인하는것도 좋겠지요!

참고 : 다만 아랫쪽에 for문을 돌린 후에 한칸 띄워주는\n를 출력하고 있는데요
         NULL을 입력해서 출력의 오류를 방지하는데 목적이 있습니다.

         이를 입력해주지 않으면 배열이 의도대로 출력되지 않고
         배열이 출력된 다음 바로 뒤에 다음 배열이 연결되어 출력되어
         엉망이 되는 모습을 볼 수 있을겁니다.

         그래서NULL을 출력시켜 정리해 주고 있습니다.

         글을 읽는것으로는 잘 와닿지 않는 부분이기도 하지요...
         직접 엉키는 오류를 접하시면 더 깊게 와닿으실듯 합니다^^;






이렇게 1로 초기화한 부분에 지정된 문자열인 별 문자열이 출력되는것을
확인할 수 있습니다.

이를 응용해서 복잡한 맵도 만들게 되는거지요.




계속 같은 방식으로 늘여주고 있습니다.
이쯤되면 슬슬 짜증이 나는 분들도 계실지 모르겠습니다.

 


도데체 왜 쓸데없이 일일이 초기화하는가.

콘솔창에서 맵을 출력한다는게 복잡한 맵이 될수록 어렵습니다.

이유는 어디까지나 콘솔창은 문자열만 출력하는 하나의 화면일 뿐이고 코딩하는 사람이
일일이 위치를 지정해줘서 원하는 위치에 문자열을 출력해주는 방식이기 때문입니다.

일일이 좌표를 측정해서 해당 좌표로 이동해서 출력할 문자열을 출력해주는 방식으로
과연 복잡한 맵을 만들 수 있을까요?

적절히 섞어서 사용하는건 필요하지만 모든 문자열을 깔끔하게 출력하기란 참 어렵습니다.

그래서 직관적으로 이해하기 쉽도록 2차원 배열을 통해 문자열로 이루어진
"그림"
을 하나 그려주고 이것을 맵으로 사용하는것입니다.

처음 접할때는 귀찮아보이고 짜증나는 방법처럼 보일지 모르지만
익숙해지면 콘솔창에 문자열로 "그림"을 그린다는 느낌을 받으실수 있을 것입니다.







추가로 출력할 문자열의 모양도 바꿔 봅시다.




슬슬 모양새 좀 나나요?

위의 미로찾기샘플이라는 글씨는 gotoxy로 따로 위치를 옮겨준뒤에 출력했습니다.
이렇게 짧거나 단순히 문자열 한줄정도 출력하는 경우에는 일일이 배열을 지정하는게
비효율적입니다. 단순할 경우에는 직접 좌표를 이동시켜서 그 위치에 출력해주는게 좋지요.

좌표를 이동시켜서 출력하는방식과
배열을 이용해 출력하는 방법 둘다 적절히 섞어 사용하는걸 추천해드립니다.






자 그럼 이제 제대로 미로 좀 만들어 볼까요?





이제 좀 뭐 만든거 같은 느낌이 나지요?

배열을 이용하지 않았다면 어땠을까요?

저 많은 벽들을 좌표를 일일이 측정해서 해당 좌표로 이동한뒤에 출력한다고
생각해보세요....

어휴 생각만해도 끔찍합니다.

그래서 2차원 배열을 사용해서 그려주는게 훨씬 더 깔끔하고 간편한 방법이
되는 것입니다.






하트를 추가하기 위해 코드를 추가했습니다. 저런식으로
0~9까지 총 10가지 모양을 배열을 돌려 출력할 수 있습니다.

간단히 말해서
10가지 타일로 그림을 그린다!
라고 생각하면 이해가 잘 될거에요.


일단 여기까지의 코드를 메모장 파일로 올려두겠습니다

gotoxy_map.txt

 (다운받아주세요)


그대로 복사해서 Visual Studio로 돌려보세요
그리고 금방 문제점을 찾으실수 있을 것입니다.





움직이긴 하는데 공이 돌아다니면서 벽이고 글씨고 다 부셔버립니다!

이것참 큰 문제네요!

뿐만아니라 이전에 만든 간단한 공출력 코드에서 공이 화면 밖으로 빠져나가며
오류가 생기는 모습도 여전히 나타납니다.

이걸 좀 고쳐봐야겠네요!

(일단 수정해둔 코드를 먼저 올려두겠습니다.
먼저 코드를 보시고 진행하는게 좋을것 같습니다.)





gotoxy_miro.txt


(수정된 코드입니다. 다운받아주세요)


위에서 오류가 나던 코드를 수정했습니다.

실제로 미로처럼 이동할수도 있고 끝부분의 하트를 먹으면
승리 메세지가 뜨며 콘솔창이 종료되도록 구현했습니다.

먼저 코드를 받아서 Visual Studio로 직접 돌려보시고
계속 봐주세요. 아래에 작성할 내용은 코드를 어떻게 수정해서

벽을 뚫지 않는지, 하트를 먹으면 게임이 완료되는지 등을 설명하고 있습니다.
그냥 코드를 가지고 분석해보고 응용하실 분들은 글을 더 읽지 않으셔도 좋을듯 합니다.




코드를 실행해 보셨나요? 이제는 벽을 뚫는다던가 하는일 없이 잘 되지요?^^
여기서부터는 어떻게 수정한것인가에 대해서 다루어보겠습니다.

오류가 생기는 이유는 배열의 값과는 상관없이
공은 공에 지정된 좌표변수에 따라서 움직이고 출력후
지움을 반복하기 때문입니다.

따라서 배열의 초기화된 값과 공의 좌표값을 연결지어 배열의 값에 따라서
공의 좌표를 되돌려주는 매커니즘이 필요한 것이죠.

일단 좌표의 값을 따로 만든 함수에 맵 배열값과 함께 넘겨줍니다.




그리고 받는 함수는 맵을 표현한 배열을 2차원 배열 포인터로 받고 좌표값은 그냥
지역변수로 받도록 해 뒀습니다.

이때 받는 변수가 공의 좌표라는점이 중요합니다.

그 다음에 if문을 통해서 넘겨받은 공의 좌표값에 해당되는 배열위치를 포인터로 접근하고
초기화된 배열값에 따라서 반환값을 다르게 지정해 주었습니다.

이런 방식으로 맵에서 아무것도 출력시키지 않는 0의 경우 지나가도 괜찮도록
1을 반환하고,

다른 숫자의 경우 그냥 지나가서는 안되는 곳이므로
(벽을 1로 초기화했지요)
0을 반환하도록 지정했습니다.

반환하고 돌아오면 그 값에 따라서 이동된 좌표에다가 공을 새로 출력할것인가
그렇지 않으면 이동해서는 안되는 지점이므로 다시 좌표를 되돌려주고 되돌린 위치에
다시 공을 출력해줄것인가를 결정하게 됩니다.

이런 매커니즘을 통해서 공이 벽을 뚫고 지나가는것을 방지하는것이죠.




그리고 배열을 수정했습니다. 가로값에 해당되는 x좌표의 부분에
더미 초기화값을 채워주었습니다.

이렇게 하는 이유는 현재 사용하고있는 벽을 나타내는
사각형 문자열과
공을 출력시키는 원모양 문자열의 경우
2바이트 문자라
배열을 통해 출력시킬경우
2칸을 잡아먹기 때문입니다.

단순 출력으로는 오류가 없지만 이동되는 다른 좌표와 연결할 경우
문제가 발생될 수 있어 저렇게 따로 한줄은 9로 초기화해주었습니다.

실제로 2바이트 문자를 활용할때는 저런 과정을 거치지 않으면
출력된 맵에 해당되는 문자열과 이동하는 문자열의 값이 충돌하게 됩니다.

(충돌결과는 다양하지요 맵을 뚫어버린다던가 이상한곳에 문자열이
출력된다던가...)

따라서 처음부터 2바이트 문자를 이용할때는 더미 배열값을 두고 시작하겠다
하는편이 좋습니다.

또 이 내용은 가로냐 세로냐에 따라서도 다릅니다.
오류가 생기는건 가로의 문제입니다.

왜냐하면 2바이트건 1바이트건 세로를 이동시키는것은 같지만
가로는 길이가 다르기 때문이지요.

세로가 같은 이유에 대해서 얘기해보지요.
어차피 세로는 줄이고 2바이트 문자건 1바이트 문자건
엔터치면 그냥 줄이 내려가지 않던가요? 그런것처럼 세로의 경우는
어떤 문자를 이용해도 결과가 같습니다. 그래서 더미 배열값같은 것도 만들지 않지요.





일단 당장은 좀 어수선하기도 하고 어지럽네요




그래도 마저 만들어 미로처럼 만들어 봤습니다.
색도 녹색이 보기 어려운듯 싶어

회색으로 바꾸었습니다.

전체적으로 좁아진 느낌이 드는데 배열의 반절을
더미 초기화 시켰기 때문입니다.

(더미 초기화된부분은 출력을 하지 않으므로 반절정도의 크기가 된 거죠)

처음부터 이렇게 만들기 위해서 배열의 가로길이를 세로길이의
2배로 만들어준 것입니다.

콘솔창의 경우세로의 길이가 가로의 길이보다 2배 길거든요.
이걸 생각하지 않으면 안되니까요.






배열의 출력지점 역시 일반 문자열과 마찬가지로 gotoxy를 활용해서
원하는 위치에 출력시킬 수 있습니다. 다만 보통의 방식은 이동해서
문자열을 하나 출력해야지 하는 정도라면

이 경우는 배열이라는 문자열로 이루어진 하나의 큰 그림을
옮기는 것으로 생각해 주시면 되겠습니다.

위치는 조심히 지정해야합니다.
또 공의 좌표와도 연계를 고려해야하기때문에 항상 원칙을 지켜서
지정하는것이 좋습니다.

스크린샷에 자세히 설명해 두었듯이
배열을 출력시키는 좌표를 수정해 주었다면
이후에 공을 출력시키는 좌표도 그에 맞춰 이동시켜줘야
합니다. 이를 무시하면 공은 원래 위치에서 따로 놀게 되어
오류가 발생합니다.






그리고 하트의 경우 벽처럼 막는게 아니라 먹는게 되어야겠지요?

while문 마지막에 하트에 해당되는 좌표인경우 break
while문을 탈출하고

아닌경우는 continue로 다시while문을 반복하게끔 수정했습니다.





while문 밖에는 승리 메세지가 기다리고 있습니다.
이외에도 적 같은것을 구현한다면

while문 밖을 if문으로 돌려서 적한테 당했을 경우와
승리했을 경우를 나누어주는방식으로 진행하면 되겠지요.





완성된 게임 플레이는 저런 식으로 진행됩니다
방향키로 공을 움직이고 하트에 도달했을때 하트를 먹으며
게임에 승리하는방식으로 진행되지요.

앞서 전체코드를 먼저 올려두긴 했습니다만,
해당 코드를 좀더 수정해서 음악까지 재생되도록 만든 프로그램을 첨부합니다.

miro_sample.zip


(아까 코드에 음악이 재생되도록 손본 파일입니다.

 Visual Studio로 옮길 필요 없고 그냥 압축풀어서

  실행시키면 됩니다)


헤더파일 등의 문제와 음악파일 포함등의 문제로
코드 대신에 실행파일로 올려두겠습니다.

음악재생을 코딩하는방법에 대해서는 이전 포스팅에서 다루고있으니
해당 포스트를 참고해주세요.


c언어 : 콘솔창 크기조절, 폰트 색깔 조절. C언어


이번에 올리는 글은 간단한 팁입니다.
콘솔창의 크기를 조절하는것과 출력되는 폰트의 색상을 조절하는법을
소개하겠습니다.



프로젝트를 실행시킨 다음에 헤더를 입력해주세요
다만 이때 #include <windows.h> 를 헤더로 선언해주어야 합니다.

윈도우 시스템의 콘솔창을 조절하는 함수는 api쪽의 함수이기 때문이지요.
마찬가지로 색상을 조절하는 함수 역시 api함수입니다.

따라서 window 헤더를 선언하고 시작해야 합니다.





선언뒤에는 저렇게 입력하고 빌드해봅시다.

 


system("mode con cols=80 lines=25"); 
              
//cols = 칸/행 (가로)  lines = 줄/열 (세로)


windows 헤더선언만 되어있다면 언제든지 사용가능합니다.
여러가지로 크기를 변경해보면서 알맞은 크기를 만들어보세요






이것이 크기 설정 전의 기본 콘솔창 화면이고...



크기를 조절한 뒤의 콘솔창입니다.
간단하게 조절할 수 있습니다.

한가지 주의할 점이라면 가로의 길이는
세로의 길이보다 짧다는 점입니다.

가로 2칸이 세로 1줄의 길이와 같습니다.

생각해볼까요? 실제 커서를 다룰때 스페이스바로 한칸
띄우는 것과 엔터키로 한칸 띄워 내릴때
 그 길이의 차이를 비교한다면 당연히 엔터키로 내릴때
더 길다는 느낌이 들지 않던가요?

그런 맥락에서 생기는 차이입니다. 어찌되었건
가로의 길이를 2배 해야 세로의 길이 1줄과 같다는것을
염두하고 크기를 조절하시면 되겠습니다!

다음은 출력 색상을 조절하는 함수에 대해서 살펴봅시다.




 


void textcolor(int color_number)

{
 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),color_number);
}

콘솔창의 출력 색상을 조절하는 핸들입니다.
실제 cmd창에서 변경가능한 컬러를 사용할수 있게끔 짜여져 있습니다.






사용법은 간단합니다. 선언한 뒤에 함수를 사용하듯이 불러오면 됩니다.
전달하는 숫자는 고유컬러의 값을 나타냅니다. 1~15번까지 색상이 지정되어있습니다.





색상핸들을 호출해와서 색을 변경해준뒤에
출력해보면 색이 바뀌는것을 확인할 수 있습니다.




각각의 색상은 다음과 같습니다.
참고가 되도록 1~15번까지 모두 출력해 두었습니다.



15번 이후의 번호를 입력하면 블루스크린계열이 바탕색으로 나타납니다.
이렇게 나타내는것도 색상표현의 방식이니 사용할...수도 있겠지요?
별로 권장해드리고싶지는 않습니다.


 

#include <stdio.h>
#include <windows.h>

void textcolor(int color_number) //콘솔창 출력색상을 나타내는 함수
{
 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),color_number);
}


int main(){
    
    int helper;

     system("mode con cols=37 lines=24");      
       //cols = 칸/행 (가로)  lines = 줄/열 (세로)
       //숫자만 바꾸어주면 원하는 크기로 조절할 수 있습니다.
   
    for(helper=0;helper<=15;helper++){
   
   textcolor(helper);
   printf("%d번 색상 출력\n",helper);}
      //15번까지 for문을 돌려 모든 색상을 출력하고 있습니다 
        }



여기까지의 내용을 코드로 정리했습니다.
참고가 되셨으면 좋겠습니다.

긁기를 방지해두었으므로 대신에 아래에
메모장파일로 코드를 첨부해두겠습니다.

sizecolor.txt
(참고해주세요)



C언어 : fmod를 이용한 mp3파일 재생 코딩하기 C언어


visual studio
를 사용하면서
음악 파일을 재생하고 싶다는 분들이 많으셔서
글로 정리해보았습니다.참고하실 분들에게 도움이 되었으면 좋겠습니다.

저 역시 음악을 넣고싶어서 열심히 방법을 찾던 기억이 있어
이런걸 자세히 정리해놓은 글이 있다면 얼마나 좋을까 했지요.

그래서 최대한 간단하게 전달하고자 노력하겠습니다.

기준은 visual studio 2010을 기준으로 제가 전에 만든 윷놀이 코드로 작성할게요.

참고 : 이 포스트는 일단fmod를 사용해본 적이 없는 분들을 기준으로 일단 어떻게 나오든 좋으니
        음악 한번 넣어보자! 하는 분들을 대상으로 작성되었습니다
.
                
        
fmod의 자세한 기능은 설명하지 않았고 어디까지나 한번 사용해보는데 의의가 있습니다.
        fmod의 다른 여러 유용한 기능들은 추후에 다른 포스팅을 통해 작성하겠습니다.



자 그러면 가장먼저 할일은fmod를 설치하는 것입니다.





 http://www.fmod.org/



인터넷 주소창에 이 주소를 입력해주세요.
귀찮으시다면 그냥 제가 써둔 링크를 이용해주세요






자 그러면 이제 fmod홈페이지가 나오네요.


관련된 여러 정보들을 포함하고있으니
자세한 사용법을 원하시거나
관련문서를 읽고싶으신 분들은
참고하시면 좋겠습니다.





일단 우리는 설치파일이 필요하니 다운로드 탭으로 들어가봅시다.



API 다운로드 메뉴에서 알맞은 운영체제의 버전을 다운받아 주시면 됩니다.
물론 저를 포함한 많은 분들은 마이크로소프트의 비쥬얼 c++을 사용하지 않을까 싶은데요...
어찌되었건 다운받아 봅시다! 저는 윈도우 버전을 받았습니다
저처럼 마소 비쥬얼 스튜디오를 사용하시는분들은 윈도우버전을 받아주세요


참고 :  
StableDevelopment의 두가지 버전이 있는데
         어느쪽을 받으셔도 상관은 없습니다.
         다만 Stable은 좀더 안정화된 버전이고
        Development는 최신기능이 추가된 버전이라고 할 수 있지요.






그럼 다운받은 파일을 설치해 주시고

설치가 완료되면
c드라이브의 program files 경로에서

 FMOD soundsystem을 확인해 주세요.


여기까지 했으면 이제 필요한 라이브러리가 추가된 셈입니다.


확인되었다면 이제 비쥬얼 스튜디오를 실행시켜 주세요
지금부터 음악을 넣어봅시다.
저는 이전 포스트로 올렸던 윷놀이 프로젝트를 불러오겠습니다.



프로젝트를 생성하거나 불러온 뒤에 메뉴에서 프로젝트탭의 속성을 클릭해주세요



이제 헤더경로와 라이브러리 경로를 지정해줍니다.

이 부분에서는 사용하시는 visual studio 버전에 따라서 조금씩 다를 수 있습니다.

저는 2010을 기준으로 작성하겠습니다.2010의 경우 속성창이 활성화된 후 왼쪽의 메뉴에서
구성속성
들어가 주세요그리고 VC++ 디렉터리들어가줍니다. 그러면 오른쪽에
스크린샷과 같은 디렉터리 경로 지정메뉴가 나타날 것입니다.





이제 포함 디렉터리를 클릭하고 그 옆에서 경로지정을 해줍시다.옆의 경로를 클릭하고 편집을 클릭합니다.




1번 2번  순서대로 클릭해주세요



 

  포함 디렉터리의 경로



 

라이브러리 디렉터리의 경로



자 그럼 아까 설치했던 FMOD soundSystem쪽으로 경로를 지정해줍니다.
포함 디렉터리와 라이브러리 디렉터리를 수정해주세요
자세한 경로는 스크린샷에 첨부해 두었으니 참고해서 진행하세요.



다음은 다시 프로젝트 속성에 들어가서 링커 탭의 입력 메뉴를 선택해주세요
그리고 그 안에서 스크린샷과 같이 추가 종속성을 수정해주세요


요약  :  visual studio실행 -> 프로젝트 -> 속성 -> 구성속성 -> VC++디렉터리 ->
         포함디렉터리 경로수정  ->라이브러리 디렉터리 경로수정 ->
        (다시)프로젝트 -> 속성 -> 링커 -> 입력 -> 추가 종속성 값에fmodex_vc.lib 입력






추가로 fmodex.dll 파일을 반드시 집어넣어야 합니다.

스크린샷에 보이는 경로로 집어넣어주세요
프로젝트 폴더에 현재 작업하는 프로젝트의 Debug폴더에 넣어주시면 됩니다.

이렇게 넣어주는 이유는 프로그램이 실행되었을때
fmod로 작성되었다면 fmod 함수를 사용하는데
이를 관장하는 파일이 fmodex.dll이기 때문입니다.






이 파일은 fmod라이브러리가 설치된 폴더에 잘 모셔져 있습니다.
어서 복사해줍시다

귀찮으신분들은 그냥 이 포스트에 올려두겠으니 바로 다운받아서 넣어주세요

fmodex.dll


(다운받아주세요)




경로지정이 완료되었나요?

자 이제야 코딩 좀 해보겠군요^^


중간에define으로 정의된 키보드 방향키값은 무시해주세요.^^


중요한건 이제#include <fmod.h> 를 통해 fmod헤더를 선언하는겁니다.


이걸 선언하기 위해서 앞에서 디렉토리 경로를 설정해준거죠.
(경로설정이 제대로 이루어지지 않으면 2010의 경우 매우 친절하게 빨간색 밑줄을 그어줍니다^^)

물론 앞에서 써둔 디렉토리는 fmod기본 설치 직후 설치된 경로에 맞춰서경로지정을 해 준 것입니다.
물론 해당 파일들을 다른 폴더에 옮겨서원하시는대로 경로를 수정해주셔도 됩니다.아무튼 아랫쪽을 봅시다.

FMOD_SYSTEM *g_System; //fmod 선언

FMOD_SOUND *g_Sound[7];
//사용할 음악의 갯수를 정하는 포인터 배열 선언

FMOD_CHANNEL *g_channel;

이런 코드들이 있네요.

FMOD_SYSTEM
FMOD_SOUND
FMOD_CHANNEL

들은 일단 선언하고 시작합시다. 각각의 용도는 주석으로 달아둔 내용과 동일합니다
.

(뒤의 g_~~등의 포인터는 제가 참고한 다른 블로그에서 해당 이름의 포인터를 이용해서
참고하던 제가 그대로 작성했던 것입니다...

당연하지만 보시는 분들은 딱히 이걸 따라하실 필요는 없고...
원하는이름으로 작성하시길^^)




작성 후에는 음악파일 선언을 할 함수를 만들어볼까요?
물론 main함수에 그냥 다 선언해도 괜찮겠습니다만...
설마 그렇게 만드시는 분들은 없으시겠죠.
아마 C언어 조금이라도 해보신 분들은 저 스크린샷만봐도바로 응용이 가능하실겁니다.

FMOD_System_CreateSound( ); //fmod라이브러리를 이용한 음악파일선언

속에 앞에서 선언한 fmod선언 포인터를 가져와 뒤에 그에 해당되는 정보를 덧붙여준것이죠.

귀찮으신분들은 역시 그대로 타이핑하여 응용해 보시는것도 좋습니다.
사용하실 음악파일의 이름을
" 어떤어떤.mp3 " 속에 입력하고 배열번호만 주의하시면 됩니다.

mp3음악파일을 이용하실거라면 확장자를 mp3,
wave확장자를 이용하실 거라면 wave확장자를

달아주면 되겠죠. 게다가 fmod의 경우는 실제로 최첨단 게임등에 사용될만큼강력한 기능들을 제공하므로...
왠만한 음악파일들은 다 재생할수 있다고 생각하시면 됩니다.

(자세한 지원 확장자는 검색을 해 보시는것이...)

자자 소리를 집어넣는데

배경음은 반복되어 재생이 되어야겠고
효과음은 한번만 재생해야 할것 아닌가요?
이때 스크린샷에 나와있는것처럼

FMOD_LOOP_NORMAL //무한재생
FMOD_DEFAULT //1번 재생

을 이용해 그런 부분을 수정해 줄 수 있습니다.
배경음과 효과음이 다른것을 확인하실 수 있겠죠?

(그밖의 자세한 기능들은 다음 포스팅에서 다루어보죠)



이제 음악들이 선언되었으므로
선언된 음악을 재생할 함수들을 마련합시다.

선언은 CreateSound를 이용하지만
재생은 PlaySound 함수를 이용합니다.

FMOD_System_PlaySound( ); 함수를 유용하게 이용합시다.

그외에도 이것저것 여러가지 내용들이 많은데일단은 넘어가겠습니다.

(다음에 기능만 정리해서 포스팅하겠습니다
)
선언함수도 만들었고 재생함수도 만들었으니
 이제 main함수로 와서 작업해 봐야죠?

main함수에 먼저 음악파일을 선언한 함수를 불러줍시다.
저의 경우는 배경음 재생을 따로 함수로 안만들고 그냥 main에 집어넣어버렸는데
별로 좋은 방식은 아닙니다 그냥 배경음도 따로 함수만드시는것이 깔끔합니다.



자 선언도 완료되었겠다.
 
이제 필요할때마다
 만들어둔 음악재생 함수 호출해서
 가져다 쓰면 되겠군요?

(main함수 외에 다른함수에서 호출할 경우
 해당 함수에도 음악선언함수를 호출해야겠죠?)

드디어 재밌는 순간이 오는군요.




어찌되었건 이렇게 해서 음악을 넣은 코딩을 완료한 다음에
빌드해줍니다.

그리고 바로 CTRL + F5 를 눌러서 확인.....

하면 좋겠지만 그러지 마세요

일단 실행은 되어도 음악재생은 안될 것입니다.
왜일까요?

당연히 아직
음악파일들을 프로젝트 폴더에 안집어넣었으니까그렇지요!






자 이제 선언해둔 재생함수에 해당되는 음악파일들을 모조리

Debug 폴더에 집어넣읍시다!

스크린샷은 위에서 사용한것을 재사용했습니다


(아까 fmodex_vc.lib 입력하고fmodex.dll을 넣어준 경로와 동일합니다)






<<이건 어떻게 보면 팁이라고 할 수 있습니다.>>

msvcr
파일도 넣어줘야 합니다. 음악 재생을 위해서 필수적으로 필요합니다.

fmod를 설치하면 자동으로 설치되긴 합니다만
여러분은 C를 이용해서 뭔가 만든 다음에 그냥 혼자 감상만 하지는 않겠죠?
누군가에게 보여준다거나 업로드해본다거나 하시겠죠?

그러나 다른 사람의 컴퓨터에 msvcr파일이 없다면 여러분들이 열심히 코딩해서
음악까지 재생되는 프로그램을 만들어두어도그 사람의 컴퓨터에서는 재생이 안됩니다.
따라서 이 파일을 debug폴더에 넣어주셔야 합니다

그리고debug폴더만 따로 복사해서 옮기면 다른 컴퓨터에서도 잘 작동이 되죠^^
(물론 음악파일들이 있기때문에 폴더채로 복사해야 합니다.)

msvcr파일은 인터넷 검색으로 쉽게 구할수 있지만


역시 귀찮으신분들을 위해서 파일을 바로 올려놓겠습니다.


msvcp100d.dll
msvcr100.dll
msvcr100d.dll


(다운받아주세요)


필요한 파일은 컴퓨터마다 다릅니다만
저같은 경우는 귀찮아서3가지 파일을 모두 집어넣었습니다.
다수를 대상으로 하는 배포를 고려한다면
모두 넣는게 좋을듯 합니다.

 
(용량에 극도로 민감하신분들은 자세히 알아보시고 필요한 파일만 넣으세요)






그리고 음악파일도 넣고 필요한 dll파일들도 넣어주었다면이제 실행해 봅시다.



(이 경우에도 exe실행파일로 실행해야지 그냥 빌드하고
 ctrl+f5로 확인하려 하면 음악재생은 안됩니다)






(C언어 배우시는분들은 너무나 익숙할 검은 콘솔창입니다^^)

적용이 잘 되었다면 음악이 재생되는 감동을 느끼실 수 있을 것입니다.

참고하시라고 지금 스샷으로 보여드린 코드로 작성된
윷놀이 파일을 아래에 올려두겠습니다.물론 전체코드는 없습니다^^;

그냥 음악이 재생된다는것 정도 확인하실수 있을겁니다

single.alz
single.a00

(참고해보세요)
분할압축입니다.





자 이번 포스팅은 여기까지입니다.
다음번에는 fmod함수의 여러 기능들을
좀더 자세히 살펴보도록 합시다!





C언어로 만든 윷놀이 C언어





C언어를 배우면서 만들어본 윷놀이입니다.아직 다 만들지는 못했고 그냥 혼자서 윷굴리고 완주하는 정도네요.

컴퓨터 인공지능을 만드는게 생각만큼 안되서 어려움을 겪고 있죠 ㅎㅎ
(플레이어 말이 어떤 지점에 있을때 컴퓨터가 어떻게 어떻게 생각해서 확률에 따라서 어떤 짓을 한다
이런식으로 만드는중인데 은근히 어렵습니다)

일단 2차원 배열로 메뉴랑 윷판을 만들었습니다.

물론 앞서서 콘솔창 크기조절하는 함수를 이용해서 크기 알맞게 만들구요.

그리고 gotoxy로 좌표를 이동시키면서 말을 움직이게 했습니다

playsound도 사용했고 fmod를 이용해서 mp3파일과 wave파일도 재생시켜 보았습니다.

 

윷 움직이는건 여러 윷 패턴을 만들고 for문으로 여러번 돌리게 만들었습니다.

윷 자체는 랜덤으로 돌리는 듯한 섞는 내용을 출력시키고 지우고 하는 작업을 반복해서 꾸몄고
섞고난뒤 윷이 결정되는 부분에서는 난수를 이용했습니다.

난수를 1~6까지 나오게 하여 1이면 도 2이면 개.... 6이면 뒷도...이런식으로 구성했죠.
그리고 if문을 통해 실제 나와야할 윷의 모양을 출력했습니다.

else if(num == 6){ //윷굴리는 난수가 6이 나왔을경우.....

    gotoxy(62,10); textcolor(10); printf("┏━┓");
    gotoxy(62,11); textcolor(10); printf("┃▒┃");
    gotoxy(62,12); textcolor(10); printf("┃뒷┃");
    gotoxy(62,13); textcolor(10); printf("┃도┃");
    gotoxy(62,14); textcolor(10); printf("┃▒┃");
    gotoxy(62,15); textcolor(10); printf("┗━┛");


    gotoxy(62,16); textcolor(14); printf("┏━┓");
    gotoxy(62,17); textcolor(14); printf("┃ X┃");
    gotoxy(62,18); textcolor(14); printf("┃ X┃");
    gotoxy(62,19); textcolor(14); printf("┃ X┃");
    gotoxy(62,20); textcolor(14); printf("┃ X┃");
    gotoxy(62,21); textcolor(14); printf("┗━┛");


    gotoxy(68,10); textcolor(14); printf("┏━┓");
    gotoxy(68,11); textcolor(14); printf("┃ X┃");
    gotoxy(68,12); textcolor(14); printf("┃ X┃");
    gotoxy(68,13); textcolor(14); printf("┃ X┃");
    gotoxy(68,14); textcolor(14); printf("┃ X┃");
    gotoxy(68,15); textcolor(14); printf("┗━┛");

    gotoxy(68,16); textcolor(14); printf("┏━┓");
    gotoxy(68,17); textcolor(14); printf("┃ X┃");
    gotoxy(68,18); textcolor(14); printf("┃ X┃");
    gotoxy(68,19); textcolor(14); printf("┃ X┃");
    gotoxy(68,20); textcolor(14); printf("┃ X┃");
    gotoxy(68,21); textcolor(14); printf("┗━┛");

     


("뒷도"가 나왔을때 출력하는 부분.)

좌표를 일일이 측량한다음
 원하는 위치에 저런 문자열을 출력시킨 것이지요.

저걸 몇개 섞어서 일정패턴으로 만들고 빠르게 출력시키면 마치 윷을 섞는듯한
모습을 연출할 수 있습니다아직은 덜 만든 상태입니다.

마저 완성해야겠지요.(다른거 배울게 많아서 언제 완성할지는
 모르겠지만 일단 시작한거 끝은 봐야겠네요)

 

아무튼 직접 처음으로 뭔가 만들어보니 뿌듯합니다.

이런 맛에 프로그램 짜는게 아닐까 싶네요.


single.alz
single.a00


(분할파일입니다)





1



protect