방향키 입력과 사각형 두개의 충돌(Rectangle)
WndProc 함수의 메시지에 코드를 작성한다.
참고) RectMakeCenter 은 사각형을 중심점과 가로 세로 길이로 처리 할 수 있도록 유저가 만든 함수이다. 각 rc에 RECT에 대응하는 값들을 수치로 넣을 것
예시) rc = {100, 100, 100, 200};
* RECT 구조체 원형
typedef struct tagRECT
{
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT, *PRECT, NEAR *NPRECT, FAR *LPRECT;

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
HDC hdc; //핸들DC
PAINTSTRUCT ps; //페인트구조체
static RECT rc1;
static RECT rc2;
switch (iMessage)
{
case WM_CREATE: //생성자 == 초기화
rc1 = RectMakeCenter(300, WINSIZEY / 2, 100, 100);
rc2 = RectMakeCenter(500, WINSIZEY / 2, 100, 100);
break;
case WM_PAINT://출력에 관한 모든것을 담당한다(문자, 그림, 도형등등 화면에 보이는 모든것)
hdc = BeginPaint(hWnd, &ps);
//이곳에 출력에 관한 코딩을 하면 된다
Rectangle(hdc, rc1.left, rc1.top, rc1.right, rc1.bottom);
Rectangle(hdc, rc2.left, rc2.top, rc2.right, rc2.bottom);
EndPaint(hWnd, &ps);
break;
case WM_KEYDOWN://키보드 키가 눌렸을때 메세지 발생
switch (wParam)
{
case VK_LEFT: //왼쪽 방향키
//겹치는 경우
if (rc1.left == rc2.right && rc1.top < rc2.bottom && rc1.top >= rc2.top)
{
rc2.left -= 10;
rc2.right -= 10;
if (rc2.left < 0)
{
rc2.right += 10;
rc2.left += 10;
rc1.right += 10;
rc1.left += 10;
}
}
if (rc1.left == rc2.right && rc1.bottom > rc2.top && rc1.bottom <= rc2.bottom)
{
rc2.left -= 10;
rc2.right -= 10;
if (rc2.left < 0)
{
rc2.right += 10;
rc2.left += 10;
rc1.right += 10;
rc1.left += 10;
}
}
rc1.right -= 10;
rc1.left -= 10;
if (rc1.left < 0)
{
rc1.right += 10;
rc1.left += 10;
}
InvalidateRect(hWnd, NULL, true);
break;
case VK_RIGHT: //오른쪽 방향키
//겹치는 경우
if (rc1.right == rc2.left && rc1.top < rc2.bottom && rc1.top >= rc2.top)
{
rc2.left += 10;
rc2.right += 10;
if (rc2.right > 800)
{
rc2.right -= 10;
rc2.left -= 10;
rc1.right -= 10;
rc1.left -= 10;
}
}
if (rc1.right == rc2.left && rc1.bottom > rc2.top && rc1.bottom <= rc2.bottom)
{
rc2.left += 10;
rc2.right += 10;
if (rc2.right > 800)
{
rc2.right -= 10;
rc2.left -= 10;
rc1.right -= 10;
rc1.left -= 10;
}
}
rc1.right += 10;
rc1.left += 10;
if(rc1.right > 800)
{
rc1.right -= 10;
rc1.left -= 10;
}
InvalidateRect(hWnd, NULL, true);
break;
case VK_UP:
//겹치는 경우
if (rc1.top == rc2.bottom && rc1.right <= rc2.right && rc1.right > rc2.left)
{
rc2.top -= 10;
rc2.bottom -= 10;
if (rc2.top < 0)
{
rc2.top += 10;
rc2.bottom += 10;
rc1.top += 10;
rc1.bottom += 10;
}
}
if (rc1.top == rc2.bottom && rc1.left >= rc2.left && rc1.left < rc2.right)
{
rc2.top -= 10;
rc2.bottom -= 10;
if (rc2.top < 0)
{
rc2.top += 10;
rc2.bottom += 10;
rc1.top += 10;
rc1.bottom += 10;
}
}
rc1.top -= 10;
rc1.bottom -= 10;
if (rc1.top < 0)
{
rc1.top += 10;
rc1.bottom += 10;
}
InvalidateRect(hWnd, NULL, true);
break;
case VK_DOWN:
//겹치는 경우
if (rc1.bottom == rc2.top && rc1.right <= rc2.right && rc1.right > rc2.left)
{
rc2.top += 10;
rc2.bottom += 10;
if (rc2.bottom > 800)
{
rc2.top -= 10;
rc2.bottom -= 10;
rc1.top -= 10;
rc1.bottom -= 10;
}
}
if (rc1.bottom == rc2.top && rc1.left >= rc2.left && rc1.left < rc2.right)
{
rc2.top += 10;
rc2.bottom += 10;
if (rc2.bottom > 800)
{
rc2.top -= 10;
rc2.bottom -= 10;
rc1.top -= 10;
rc1.bottom -= 10;
}
}
rc1.top += 10;
rc1.bottom += 10;
if (rc1.bottom > 800)
{
rc1.top -= 10;
rc1.bottom -= 10;
}
InvalidateRect(hWnd, NULL, true);
break;
case VK_ESCAPE: //esc 키를 누르면 화면종료
PostMessage(hWnd, WM_DESTROY, 0, 0);
break;
}
break;
case WM_DESTROY: //소멸자
PostQuitMessage(0);
return 0;
}
//윈도우 프로시져에서 처리되지 않은 나머지 메세지를 처리해준다
return (DefWindowProc(hWnd, iMessage, wParam, lParam));
}
참고) RectMakeCenter 은 사각형을 중심점과 가로 세로 길이로 처리 할 수 있도록 유저가 만든 함수이다. 각 rc에 RECT에 대응하는 값들을 수치로 넣을 것
예시) rc = {100, 100, 100, 200};
* RECT 구조체 원형
typedef struct tagRECT
{
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT, *PRECT, NEAR *NPRECT, FAR *LPRECT;

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
HDC hdc; //핸들DC
PAINTSTRUCT ps; //페인트구조체
static RECT rc1;
static RECT rc2;
switch (iMessage)
{
case WM_CREATE: //생성자 == 초기화
rc1 = RectMakeCenter(300, WINSIZEY / 2, 100, 100);
rc2 = RectMakeCenter(500, WINSIZEY / 2, 100, 100);
break;
case WM_PAINT://출력에 관한 모든것을 담당한다(문자, 그림, 도형등등 화면에 보이는 모든것)
hdc = BeginPaint(hWnd, &ps);
//이곳에 출력에 관한 코딩을 하면 된다
Rectangle(hdc, rc1.left, rc1.top, rc1.right, rc1.bottom);
Rectangle(hdc, rc2.left, rc2.top, rc2.right, rc2.bottom);
EndPaint(hWnd, &ps);
break;
case WM_KEYDOWN://키보드 키가 눌렸을때 메세지 발생
switch (wParam)
{
case VK_LEFT: //왼쪽 방향키
//겹치는 경우
if (rc1.left == rc2.right && rc1.top < rc2.bottom && rc1.top >= rc2.top)
{
rc2.left -= 10;
rc2.right -= 10;
if (rc2.left < 0)
{
rc2.right += 10;
rc2.left += 10;
rc1.right += 10;
rc1.left += 10;
}
}
if (rc1.left == rc2.right && rc1.bottom > rc2.top && rc1.bottom <= rc2.bottom)
{
rc2.left -= 10;
rc2.right -= 10;
if (rc2.left < 0)
{
rc2.right += 10;
rc2.left += 10;
rc1.right += 10;
rc1.left += 10;
}
}
rc1.right -= 10;
rc1.left -= 10;
if (rc1.left < 0)
{
rc1.right += 10;
rc1.left += 10;
}
InvalidateRect(hWnd, NULL, true);
break;
case VK_RIGHT: //오른쪽 방향키
//겹치는 경우
if (rc1.right == rc2.left && rc1.top < rc2.bottom && rc1.top >= rc2.top)
{
rc2.left += 10;
rc2.right += 10;
if (rc2.right > 800)
{
rc2.right -= 10;
rc2.left -= 10;
rc1.right -= 10;
rc1.left -= 10;
}
}
if (rc1.right == rc2.left && rc1.bottom > rc2.top && rc1.bottom <= rc2.bottom)
{
rc2.left += 10;
rc2.right += 10;
if (rc2.right > 800)
{
rc2.right -= 10;
rc2.left -= 10;
rc1.right -= 10;
rc1.left -= 10;
}
}
rc1.right += 10;
rc1.left += 10;
if(rc1.right > 800)
{
rc1.right -= 10;
rc1.left -= 10;
}
InvalidateRect(hWnd, NULL, true);
break;
case VK_UP:
//겹치는 경우
if (rc1.top == rc2.bottom && rc1.right <= rc2.right && rc1.right > rc2.left)
{
rc2.top -= 10;
rc2.bottom -= 10;
if (rc2.top < 0)
{
rc2.top += 10;
rc2.bottom += 10;
rc1.top += 10;
rc1.bottom += 10;
}
}
if (rc1.top == rc2.bottom && rc1.left >= rc2.left && rc1.left < rc2.right)
{
rc2.top -= 10;
rc2.bottom -= 10;
if (rc2.top < 0)
{
rc2.top += 10;
rc2.bottom += 10;
rc1.top += 10;
rc1.bottom += 10;
}
}
rc1.top -= 10;
rc1.bottom -= 10;
if (rc1.top < 0)
{
rc1.top += 10;
rc1.bottom += 10;
}
InvalidateRect(hWnd, NULL, true);
break;
case VK_DOWN:
//겹치는 경우
if (rc1.bottom == rc2.top && rc1.right <= rc2.right && rc1.right > rc2.left)
{
rc2.top += 10;
rc2.bottom += 10;
if (rc2.bottom > 800)
{
rc2.top -= 10;
rc2.bottom -= 10;
rc1.top -= 10;
rc1.bottom -= 10;
}
}
if (rc1.bottom == rc2.top && rc1.left >= rc2.left && rc1.left < rc2.right)
{
rc2.top += 10;
rc2.bottom += 10;
if (rc2.bottom > 800)
{
rc2.top -= 10;
rc2.bottom -= 10;
rc1.top -= 10;
rc1.bottom -= 10;
}
}
rc1.top += 10;
rc1.bottom += 10;
if (rc1.bottom > 800)
{
rc1.top -= 10;
rc1.bottom -= 10;
}
InvalidateRect(hWnd, NULL, true);
break;
case VK_ESCAPE: //esc 키를 누르면 화면종료
PostMessage(hWnd, WM_DESTROY, 0, 0);
break;
}
break;
case WM_DESTROY: //소멸자
PostQuitMessage(0);
return 0;
}
//윈도우 프로시져에서 처리되지 않은 나머지 메세지를 처리해준다
return (DefWindowProc(hWnd, iMessage, wParam, lParam));
}
댓글
댓글 쓰기