본문 바로가기
코스웨어/15년 스마트컨트롤러

2015.11.19_개인업무일지_[Win32API #6]_이량경_매핑,밀기,점수

by 알 수 없는 사용자 2015. 11. 19.
728x90
반응형

 <Win32API>✔ 

================================================================

7-2-다. 컨트롤의 메시지

컨트롤은 자신에게 어떤 변화가 있을 때마다 부모 윈도우로 메시지를 보내며 이 메시지를 통지 메시지라고 부른다.

예를 들어 ->체크 박스의 경우 사용자가 마우스로 체크 박스를 클릭할 때마다 부모 윈도우로 BN_CLICKED 메시지를 보낸다. 
컨트롤이 부모 윈도우로 보내는 통지 메시지와는 달리 부모 윈도우가 체크 박스의 현재 상태를 알아보거나 상태를 바꾸고자 할 때도 차일드 윈도우로 메시지를 보낸다. 
부모 윈도우가 체크 박스로 보낼 수 있는 메시지에는 다음 두가지가 있다.

메시지설명
BM_GETCHECK체크 박스가 현재 체크되어 있는 상태인지를 조사하며 추가정보는 없다.
BM_SETCHECK체크 박스의 체크 상태를 변경하며 wParam에 변경할 체크 상태를 보내주면 된다.

BM_GETCHECK에 의해 리턴되는 값, 또는 BM_SETCHECK에 의해 설정되는 체크 박스의 상태는 다음 세가지가 있다.

상수의미
BST_CHECKED현재 체크되어 있다.
BST_UNCHECKED현재 체크되어 있지 않다.
BST_INDETERMINATE체크도 아니고 안체크도 아닌 상태

ID 0의 체크 박스가 클릭되었을 때> 를 처리하는 코드를 보자. 
체크 박스가 클릭되면 BN_CLICKED 통지 메시지가 WM_COMMAND 메시지를 통해 전달되므로 WM_COMMAND 메시지에 이 코드가 작성되어 있다.

case WM_COMMAND:
switch(LOWORD(wParam)) {
case 0:
        if (SendMessage(c1,BM_GETCHECK,0,0)==BST_UNCHECKED) {
                SendMessage(c1,BM_SETCHECK,BST_CHECKED,0);
                ELLIPSE = TRUE;
        }
        else {
                SendMessage(c1,BM_SETCHECK,BST_UNCHECKED,0);
                ELLIPSE = FALSE;
        }
        InvalidateRect(hWnd, NULL, TRUE);
        break;
* 부모 윈도우> BM_GETCHECK 메시지를 c1체크 박스로 보내 현재 체크 박스의 상태를 조사
> 그 값이 BST_UNCHECKED (현재 체크되어 있지 않으면) BM_SETCHECKED 메시지를 다시 보내 체크 박스에 체크 표시를 명령함.
> 이때 wParam으로 체크 표시를 하라는 의미의 BST_CHECKED가 전달되었다. 
> 만약 BST_UNCHECKED가 아니면, 즉 현재 체크되어 있으면 체크 표시를 해제하도록 메시지를 보낸다. 
> 또한 조사된 체크 박스의 상태에 따라 ELLIPSE 변수값을 TRUE나 FALSE로 변경하도록 하며 
> InvalidateRect 함수를 호출하여 WM_PAINT 메시지를 발생시키는데 
> WM_PAINT 메시지에서는 ELLIPSE 변수의 값에 따라 사각형이나 타원을 그리게 된다. 
> 따라서 사용자가 이 체크 박스를 클릭할 때마다 체크박스의 상태가 토글되며 화면상의 사각형/타원형이 계속 교체된다.

* 부모 윈도우와 자식 윈도우는 이런 식으로 메시지를 통해 서로의 상태를 알리거나 변경하도록 지시한다


* ID 2의 체크 박스> 는 BS_3STATE 스타일로 생성
> 되었으므로 세가지 상태를 가질 수 있으며 
> 수동 체크 박스이기 때문에 ID 0의 체크 박스와 마찬가지로 BN_CLICKED 통지 메시지가 발생했을 때 체크 상태를 변경해줘야 한다.

> 반면 ID 1과 ID 3의 체크 박스는 자동 체크 박스이기 때문에 이런 코드를 작성하지 않아도 윈도우즈가 알아서 체크 박스의 상태를 변경해 준다. 
> 이렇게 변경된 값은 체크 박스의 상태가 필요할 때만 BM_GETCHECK 메시지를 보내 상태를 알아 보기만 하면 되며 체크 박스값이 변경될 때마다 어떤 처리를 해 줄 필요는 없다. 
> 이 예제의 경우 ID 1의 체크 박스 상태는 종료시에만 사용되므로 종료 직전에만 값을 검사하여 체크되어 있으면 메시지 박스를 출력하고 그렇지 않으면 그냥 프로그램을 종료하면 된다.
case WM_DESTROY:
                if (SendMessage(c2,BM_GETCHECK,0,0)==BST_CHECKED)
                        MessageBox(hWnd,"Good bye","Check",MB_OK);
                PostQuitMessage(0);
                return 0;

> ID 0의 수동 체크 박스는 체크 상태가 변경될 때마다 ELLIPSE 변수값을 변경해 주어야 하고 
> 또한 화면을 다시 그려야 하므로 자동 체크 박스 스타일은 부적당하다.

7-2-라. 라디오 버튼

* "button" 클래스에 BS_RADIOBUTTON, BS_AUTORADIOBUTTON 둘 중 하나의 스타일을 지정하면 라디오 버튼이 된다.
> 수동, 자동(윈도우즈가 체크 상태를 자동으로 변경)의 두 가지 종류

- 같은 그룹에 속한 라디오 버튼은 하나만 선택할 수 있으며 사용자에 의해 라디오 버튼이 선택되면 같은 그룹에 속한 다른 모든 라디오 버튼은 선택이 해제된다.




----------------------------------------------------------------
<게임만들기>

       SelectObject(MemDC, HbmHero);
       BitBlt(hdc, ixPos, iyPos, XTILEYTILE, MemDC, 0, 0, SRCCOPY);

에서 골뱅이의 좌표값을 가지고 잇음.

맴카피를 쓰지 않는다 :  현재 히어로의 멈춰있는 @ 이 위치를 계속 로드해서 동시에 히어로의 위치를 가져와야한다

맵복사할때 memcpy를 쓰면 for문을 쓰면 복사하면서 @의 위치를 알수 잇다./예) 맵핵

- 컴퓨터는 위치를 실시간으로 계산하고 잇다. 스타 : 다 감시 해야 한다. 그래서 총인구수 제한을 둔다.

- 타이머 있으면 : 실시간오락
- 타이머 빠지면 : 퍼즐 오락

- 따라오는 몹 은 실시간으로 캐릭터의위치를 안다. 타이머를 늘리면 천천히 쫒아 오고, 줄이면 빨리 쫒아온다

* 타이머 
- 테트리스의 블럭 속도
- 블럭이 도달할때마다.if문으로 각 라인이 찼는지 검사한다.
- 블럭 = *이고, 공백은 0으로 두고, 다찼으면 한줄 지움.

- 도형그리는 알고리즘만 중요하다.
- 타이머 숫자 감소.
- 랜덤함수의 시드값을 현재시간으로 하면 항상 랜덤하게 된다.

**********************
(@)길           o     1   
(@)닷           o     2
(@)박스 벽    x    
(@)박스 박스 x
        
(@)박스 길    o     3
(@)박스 닷    o     4

(@)벽           x
**********************

위 논리로 좌표.
> 전체를 다시 그리면서 일어나는 깜빡임 현상을 처리하기위해 무효화영역 을 
> RECT 의 멤버 변수에 무효화 영역 의 좌표를 넣고 키입력시 처리 . 
> #: 이동 불가 영역,      .(dot) : 스테이지 성공,       박스 이동처리
     * ucMap(실제 맵)의 #을 화면에 그림으로 그려놓았을뿐 '화면'
     -> 방향키가 변하려면 지도의 @가 변해야 한다.
> 'HOME' 키 입력 처리 : 스테이지 재시작의 메시지박스호출
     -> 재시작 : @위치를 찾아 다시 그린다.
> . 지점에 박스가 놓이면 : 다음 스테이지
> 마지막 스테이지까지 클리어 하면 게임종료





내일 오전 :  최적화 할것.
--------------------------------------------------------------
<소스>

#include <windows.h>
#include "smart.h"
#include "resource1.h"

HINSTANCE g_hInst;
LPSTR lpszClass = TEXT ("SMART" );

LRESULT CALLBACK WndProc(HWND , UINT , WPARAM , LPARAM );
stMsgMap MsgMap[] =
{
       { WM_PAINT , OnPaint },
       { WM_KEYDOWN, OnKeydown },
       { WM_CREATE, OnCreate },
       { WM_DESTROY, OnDestroy },

       { WM_NULL, 0 }
};

/****Mapping****/
UCHAR ucStageMap[STAGE ][YFRAME ][XFRAME + 1] = 
{
       {
               "###############",
               "#     #########" ,
               "# ###  ########",
               "# ##         ##" ,
               "#    B    ## ##" ,
               "#     @   ## ##" ,
               "#         ## ##" ,
               "#        .   ##" ,
               "#####        ##" ,
               "###############",
       }
       ,
       {
               "###############",
               "#           ###" ,
               "# ###   .    ###" ,
               "# ##         ##" ,
               "#    @    ## ##" ,
               "#    B    ## ##" ,
               "#         ## ##" ,
               "#     #####  ##" ,
               "#####        ##" ,
               "###############",
       }
};

UCHAR ucMap[YFRAME ][XFRAME + 1];

int APIENTRY WinMain(HINSTANCE hInstance , HINSTANCE hPrevInstance
       , LPSTR lpszCmdParam, int nCmdShow )
{
        HWND hWnd;
        MSG Message;
        WNDCLASS WndClass;
       g_hInst = hInstance;

       WndClass.cbClsExtra = 0;
       WndClass.cbWndExtra = 0;
       WndClass.hbrBackground = ( HBRUSH)GetStockObject( WHITE_BRUSH);
       WndClass.hCursor = LoadCursor(NULL , IDC_ARROW );
       WndClass.hIcon = LoadIcon( NULL, IDI_APPLICATION);
       WndClass.hInstance = hInstance;
       WndClass.lpfnWndProc = ( WNDPROC)WndProc;
       WndClass.lpszClassName = lpszClass;
       WndClass.lpszMenuName = NULL;
       WndClass.style = CS_HREDRAW | CS_VREDRAW ;
        RegisterClass(&WndClass);

       hWnd = CreateWindow(
              lpszClass,
              lpszClass,
               WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU ,
               CW_USEDEFAULT,
               CW_USEDEFAULT,
               XWINSIZE,
               YWINSIZE,
               NULL, ( HMENU) NULL, hInstance, NULL);
       ShowWindow(hWnd, nCmdShow);

        while ( GetMessage(&Message, 0, 0, 0))
       {
              TranslateMessage(&Message);
               DispatchMessage(&Message);
       }
        return Message.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd , UINT iMessage , WPARAM wParam , LPARAM lParam )
{
        HDC hdc;
        PAINTSTRUCT ps;
        stMsgMap *stpMap = MsgMap;

        while( WM_NULL != ((*stpMap).uiMsg) )
       {
               if ( iMessage == ((*stpMap).uiMsg))
              {
                      return (((*stpMap).fp)( hWnd, wParam, lParam));
              }
              ++stpMap;
       }

        return(DefWindowProcA( hWnd, iMessage, wParam, lParam));
}

LRESULT OnDestroy(HWND hWnd , WPARAM wParam , LPARAM lParam )
{
       DeleteObject(HbmFront);
       DeleteObject(HbmRear);
       DeleteObject(HbmRight);
       DeleteObject(HbmLeft);
       DeleteObject(HbmGround);
       DeleteObject(HbmRoad);
       DeleteObject(HbmDot);
       DeleteObject(HbmBox);
       DeleteDC(MemDC);
       
       PostQuitMessage(0);
        return 0;
}
LRESULT OnCreate(HWND hWnd , WPARAM wParam , LPARAM lParam )
{
        HDC hdc;
       Load_map();
       
       hdc = GetDC( hWnd);
       MemDC = CreateCompatibleDC(hdc);

       HbmFront = LoadBitmap(g_hInst, MAKEINTRESOURCE (IDB_BITMAP1 ));
       HbmLeft = LoadBitmap(g_hInst, MAKEINTRESOURCE (IDB_BITMAP2 ));
       HbmRight = LoadBitmap(g_hInst, MAKEINTRESOURCE (IDB_BITMAP3 ));
       HbmRear = LoadBitmap(g_hInst, MAKEINTRESOURCE (IDB_BITMAP4 ));
       HbmGround = LoadBitmap(g_hInst, MAKEINTRESOURCE (IDB_BITMAP5 ));
       HbmRoad = LoadBitmap(g_hInst, MAKEINTRESOURCE (IDB_BITMAP7 ));
       HbmDot = LoadBitmap(g_hInst, MAKEINTRESOURCE (IDB_BITMAP8 ));
       HbmBox = LoadBitmap(g_hInst, MAKEINTRESOURCE (IDB_BITMAP9 ));

       ReleaseDC( hWnd, hdc);
       HbmHero = HbmFront;
        return 0;
}
void Load_map(void )
{
        int ixCnt;
        int iyCnt;
       uiDotNum = 0;
       uiScore = 0;
       
        for (ixCnt = 0; ixCnt < XFRAME; ixCnt++)
       {
               for (iyCnt = 0; iyCnt < YFRAME; iyCnt++)
              {
                      if ( '.' == ucStageMap[uiStage][iyCnt][ixCnt])
                     {
                           ++uiDotNum;
                     }
                      if ( '@' == ucStageMap[uiStage][iyCnt][ixCnt])
                     {
                           ixPos = ixCnt;
                           iyPos = iyCnt;
                           ucMap[iyCnt][ixCnt] = ' ';
                            continue;
                     }
                     ucMap[iyCnt][ixCnt] = ucStageMap[uiStage][iyCnt][ixCnt];
              }
       }
       
        return;
}
LRESULT OnPaint(HWND hWnd , WPARAM wParam , LPARAM lParam )
{
        HDC hdc;
        PAINTSTRUCT ps;
        int ixCnt;
        int iyCnt;
       hdc = BeginPaint( hWnd, &ps);
       
        for (ixCnt = 0; ixCnt < XFRAME; ixCnt++)
       {
               for (iyCnt = 0; iyCnt < YFRAME; iyCnt++)
              {
                      if ( '#' == ucMap[iyCnt][ixCnt])
                     {
                           SelectObject(MemDC, HbmGround); //벽이면 백그라운드 사용.
                     }
                      else if ( ' ' == ucMap[iyCnt][ixCnt])
                     {
                           SelectObject(MemDC, HbmRoad);
                     }
                     
                      else if ( '.' == ucMap[iyCnt][ixCnt])
                     {
                           SelectObject(MemDC, HbmDot);
                     }
                      else if ( 'B' == ucMap[iyCnt][ixCnt])
                     {
                           SelectObject(MemDC, HbmBox);
                     }
                     BitBlt(hdc, ixCnt* XTILE, iyCnt* YTILE, XTILE, YTILE, MemDC, 0, 0, SRCCOPY);
              }
       }
       SelectObject(MemDC, HbmHero);
       BitBlt(hdc, ixPos* XTILE, iyPos* YTILE, XTILE, YTILE, MemDC, 0, 0, SRCCOPY);

       EndPaint( hWnd, &ps);
        wsprintf(cTitle, TEXT( "STAGE : %d  KeyCount : %d" ), (uiStage + 1), uiScore);
        SetWindowText(hWnd , cTitle);
        return 0;
}

LRESULT OnKeydown(HWND hWnd , WPARAM wParam , LPARAM lParam )
{
        int ixCnt;
        int iyCnt;
        UINT uiDotCnt;

        RECT stArea;
       stArea.left = ixPos* XTILE;
       stArea.right = (ixPos + 1)* XTILE;
       stArea.top = iyPos* YTILE;
       stArea.bottom = (iyPos + 1)* YTILE;
       
        int iRet;

        switch ( wParam)
       {
        case VK_RIGHT:
              ++uiScore;
              HbmHero = HbmRight;
               if ( ' ' == ucMap[iyPos][ixPos + 1])       
              {
                     ++ixPos;
                     stArea.right = (ixPos + 1)* XTILE;
              }
               else if ( '.' == ucMap[iyPos][ixPos + 1]) 
              {
                     ++ixPos;
                     stArea.right = (ixPos + 1)* XTILE;
              }
               else if ( 'B' == ucMap[iyPos][ixPos + 1]) 
              {
                      if ( ' ' == ucMap[iyPos][ixPos + 2])
                     {
                           ucMap[iyPos][ixPos + 2] = ucMap[iyPos][ixPos + 1];
                            if ( '.' != ucStageMap[uiStage][iyPos][ixPos + 1])
                           {
                                  ucMap[iyPos][ixPos + 1] = ' ';
                           }
                            else
                           {
                                  ucMap[iyPos][ixPos + 1] = '.';
                           }
                           ++ixPos;
                           stArea.right = (ixPos + 2)* XTILE;
                     }
                      else if ( '.' == ucMap[iyPos][ixPos + 2])
                     {
                           ucMap[iyPos][ixPos + 2] = ucMap[iyPos][ixPos + 1];
                            if ( '.' != ucStageMap[uiStage][iyPos][ixPos+1])
                           {
                                  ucMap[iyPos][ixPos + 1] = ' ';
                           }
                            else
                           {
                                  ucMap[iyPos][ixPos + 1] = '.';
                           }
                           ++ixPos;
                           stArea.right = (ixPos + 2)* XTILE;
                     }
              }
               break;
        case VK_LEFT:
              ++uiScore;
              HbmHero = HbmLeft;
               if ( ' ' == ucMap[iyPos][ixPos - 1])       
              {
                     --ixPos;
                     stArea.left = ixPos* XTILE;
              }
               else if ( '.' == ucMap[iyPos][ixPos - 1])
              {
                     --ixPos;
                     stArea.left = ixPos* XTILE;
              }
               else if ( 'B' == ucMap[iyPos][ixPos - 1])
              {
                      if ( ' ' == ucMap[iyPos][ixPos - 2])
                     {
                           ucMap[iyPos][ixPos - 2] = ucMap[iyPos][ixPos - 1];
                            if ( '.' != ucStageMap[uiStage][iyPos][ixPos - 1])
                           {
                                  ucMap[iyPos][ixPos - 1] = ' ';
                           }
                            else
                           {
                                  ucMap[iyPos][ixPos - 1] = '.';
                           }
                           --ixPos;
                           stArea.left = (ixPos- 1)* XTILE;
                     }
                      else if ( '.' == ucMap[iyPos][ixPos - 2])
                     {
                           ucMap[iyPos][ixPos - 2] = ucMap[iyPos][ixPos - 1];
                            if ( '.' != ucStageMap[uiStage][iyPos][ixPos - 1])
                           {
                                  ucMap[iyPos][ixPos - 1] = ' ';
                           }
                            else
                           {
                                  ucMap[iyPos][ixPos - 1] = '.';
                           }
                           --ixPos;
                           stArea.left = (ixPos - 1)* XTILE;
                     }
              }
               break;
        case VK_UP:
              ++uiScore;
              HbmHero = HbmRear;

               if ( ' ' == ucMap[iyPos-1][ixPos]) 
              {
                     --iyPos;
                     stArea.top = iyPos* YTILE;
              }
               else if ( '.' == ucMap[iyPos-1][ixPos])
              {
                     --iyPos;
                     stArea.top = iyPos* YTILE;
              }
               else if ( 'B' == ucMap[iyPos-1][ixPos])
              {
                      if ( ' ' == ucMap[iyPos-2][ixPos])
                     {
                           ucMap[iyPos - 2][ixPos] = ucMap[iyPos - 1][ixPos];
                            if ( '.' != ucStageMap[uiStage][iyPos-1][ixPos])
                           {
                                  ucMap[iyPos - 1][ixPos] = ' ';
                           }
                            else
                           {
                                  ucMap[iyPos - 1][ixPos] = '.';
                           }
                           --iyPos;
                           stArea.top = (iyPos-1)* YTILE;
                     }
                      else if ( '.' == ucMap[iyPos-2][ixPos])
                     {
                           ucMap[iyPos - 2][ixPos] = ucMap[iyPos - 1][ixPos];
                            if ( '.' != ucStageMap[uiStage][iyPos - 1][ixPos])
                           {
                                  ucMap[iyPos - 1][ixPos] = ' ';
                           }
                            else
                           {
                                  ucMap[iyPos - 1][ixPos] = '.';
                           }
                           --iyPos;
                           stArea.top = (iyPos-1)* YTILE;
                     }
              }
               break;
        case VK_DOWN:
              ++uiScore;
              HbmHero = HbmFront;

               if ( ' ' == ucMap[iyPos+1][ixPos])  
              {
                     ++iyPos;
                     stArea.bottom = (iyPos + 1)* YTILE;
              }
               else if ( '.' == ucMap[iyPos+1][ixPos])
              {
                     ++iyPos;
                     stArea.bottom = (iyPos + 1)* YTILE;
              }
               else if ( 'B' == ucMap[iyPos+1][ixPos])
              {
                      if ( ' ' == ucMap[iyPos+2][ixPos])
                     {
                           ucMap[iyPos + 2][ixPos] = ucMap[iyPos + 1][ixPos];
                            if ( '.' != ucStageMap[uiStage][iyPos + 1][ixPos])
                           {
                                  ucMap[iyPos + 1][ixPos] = ' ';
                           }
                            else
                           {
                                  ucMap[iyPos + 1][ixPos] = '.';
                           }
                           ++iyPos;
                           stArea.bottom = (iyPos + 2)* YTILE;
                     }
                      else if ( '.' == ucMap[iyPos+2][ixPos])
                     {
                           ucMap[iyPos + 2][ixPos] = ucMap[iyPos + 1][ixPos];
                            if ( '.' != ucStageMap[uiStage][iyPos + 1][ixPos])
                           {
                                  ucMap[iyPos + 1][ixPos] = ' ';
                           }
                            else
                           {
                                  ucMap[iyPos + 1][ixPos] = '.';
                           }
                           ++iyPos;
                           stArea.bottom = (iyPos + 2)* YTILE;
                     }
              } 
               break;
        case VK_HOME:
              iRet = MessageBox(hWnd , TEXT ("스테이지 다시시작" ), TEXT ("명박 명박"), MB_YESNO);
               if (iRet == IDYES)
              {
                     Load_map();
                     uiStage = 0;
                     uiScore = 0;
                     HbmHero = HbmFront;
              }
              InvalidateRect( hWnd, NULL, TRUE);
               return 0;
       }
       InvalidateRect( hWnd, &stArea, FALSE);

       uiDotCnt = 0;
        for (ixCnt = 0; ixCnt < XFRAME;ixCnt++)
       {
               for (iyCnt = 0; iyCnt < YFRAME; iyCnt++)
              {
                      if ( 'B'== ucMap[iyCnt][ixCnt]) 
                     {
                            if ( '.'== ucStageMap[uiStage][iyCnt][ixCnt]) 
                                  ++uiDotCnt;
                     }
              }
       }
        if (uiDotCnt == uiDotNum)
       {
               MessageBox(hWnd , TEXT ("스테이지 클리어" ), TEXT ("명박 ㅇㅋ" ), MB_OK );
              ++uiStage;
               if (( STAGE) <= uiStage)
              {
                      MessageBox(hWnd , TEXT ("게임종료" ), TEXT ("명박 ㅇㅋ" ), MB_OK );
                      SendMessage(hWnd , WM_DESTROY , wParam , lParam );
                      return 0;
              }
              Load_map();
              HbmHero = HbmFront;
              InvalidateRect( hWnd, NULL, TRUE);
       }

        return 0;
}

--------------------------------------------------------------










728x90