DX라이브러리2014. 12. 24. 14:18

3.3 간단한 선택화면


이번 섹션에선 구조체를 이용하여 진행한다. 자세한 사항은 이곳을 참고하자.


메뉴항목에서는 X좌표, Y좌표, 메뉴이름이 한 묶음이 될 수 있으며 다음과 같은 방식으로 선언 가능하다.


typedef struct{

  int x, y좌표;

  char* 이름;

} 메뉴항목태그;


이를통하여 메뉴항목을 작성하면 매우 편리하다. 또한 만약 메뉴 항목이 5개라면 메뉴항목태그[5]같은 방식으로 배열을 선언하여 계산 루프를 진행하면 효율적이다. 다음 예제는 방향키 "하"를 누를 때 마다 메뉴에서 한칸씩 아래로 내려가는 모습을 구현하였다.


#include <DxLib.h>


int Key[256];


int gpUpdateKey(){

        char tmpKey[256];

        GetHitKeyStateAll( tmpKey );

        for( int i=0; i<256; i++ ){ 

                if( tmpKey[i] != 0 ){

                        Key[i]++;

                } else {

                        Key[i] = 0;

                }

        }

        return 0;

}


// 메뉴항목에 필요한 구조체 선언

typedef struct{

        int x, y;       // 좌표 변수

        char name[128]; // 항목 이름 변수

} MenuElement_t;


int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){

        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK );


        // 메뉴항목은 5개를 만든다.

        MenuElement_t MenuElement[5]={

                {  80, 100, "새 게임" }, // 구조체 내부에 선언된 순서대로 각각의 값이 저장된다. (x,y,name 순서)

                { 100, 150, "보너스" },

                { 100, 200, "도움말" },

                { 100, 250, "설정" },

                { 100, 300, "게임종료" },

        };

        int SelectNum = 0; // 현재 선택 번호


        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && gpUpdateKey()==0 ){


                // 계산 구문


                if( Key[ KEY_INPUT_DOWN ] == 1 ){ // 방항키"하"를 입력했을 때에만 처리


                        SelectNum = ( SelectNum + 1 ) % 5; // 현재 항목에서 한칸 밑으로 내림 (루프)


                        for( int i=0; i<5; i++ ){              // 메뉴 항목의 갯수인 5로 루프 처리

                                if( i == SelectNum ){          // 지금 처리중인 항목이 선택번호와 같으면

                                        MenuElement[i].x = 80; // 좌표를 x좌표를 80으로

                                } else {                       // 지금 처리중인 항목이 선택번호와 다르면

                                        MenuElement[i].x = 100;// 좌표를 x좌표를 100으로

                                }

                        }

                }


                // 묘화 구문


                for( int i=0; i<5; i++ ){ // 메뉴 항목 묘화

                        DrawFormatString( MenuElement[i].x, MenuElement[i].y, GetColor(255,255,255), MenuElement[i].name );

                }


        }


        DxLib_End();

        return 0;

}


실행결과



이번에도 역시 계산구문과 묘화구문이 나누어져있으며 항상 이를 의식하고 코딩해나가자. 아래 예제는 이 구분을 의식하지 않고 작성한 예이다.


#include <DxLib.h>


int Key[256]; 


int gpUpdateKey(){

char tmpKey[256];

GetHitKeyStateAll( tmpKey ); 

for( int i=0; i<256; i++ ){ 

if( tmpKey[i] != 0 ){ 

Key[i]++;     

} else {              

Key[i] = 0;  

}

}

return 0;

}


typedef struct{

        int x, y;               

        char name[128];

} MenuElement_t;


int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){

        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK );


        MenuElement_t MenuElement[5]={

                {  80, 100, "새 게임" },

                { 100, 150, "보너스" },

                { 100, 200, "도움말" },

                { 100, 250, "설정" },

                { 100, 300, "게임종료" },

        };

        int SelectNum = 0;


        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && gpUpdateKey()==0 ){


                // 계산 구문


                if( Key[ KEY_INPUT_DOWN ] == 1 ){ 


                        SelectNum = ( SelectNum + 1 ) % 5; 


                }


                // 묘화 구문


                for( int i=0; i<5; i++ ){

                        if( i == SelectNum ){

                                DrawFormatString( MenuElement[i].x-20, MenuElement[i].y, GetColor(255,255,255), MenuElement[i].name );

} else {

DrawFormatString( MenuElement[i].x,    MenuElement[i].y, GetColor(255,255,255), MenuElement[i].name );

}

}


}


DxLib_End(); 

return 0;

}


실행결과는 위의 예제와 완전히 동일하다. 예제와 같이 짧은 코드에서는 크게 문제가 되지 않을 수 있지만 프로그램이 커지게 되면 이런 방식은 문제가 발생할 확률이 매우 높다. 되도록이면 계산, 묘화구문은 구별하여 작성하도록 한다.

Posted by 캡슐리어