방향키 입력과 사각형 세개의 충돌(FillRect, CreateSolidBrush)
실습 예제
- 같은 크기 큰 사각형 두개를 그리고 1개의 사각형 내부에 색이 칠해진 작은 사각형을 그린다.
- 색 사각형을 포함한 큰 사각형을 움직이게 만들고, 색이 칠해진 사각형은 큰 사각형을 벗어나지 못한다.
- 색이 있는 사각형은 움직이는 사각형 내부에만 존재한다.
- 움직이는 사각형이 나머지 큰 사각형에 부딪히면 움직이는 사각형이 변경된다.
* RECT: 사각형을 나타내는 구조체
typedef struct tagRECT
{
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT, *PRECT, NEAR *NPRECT, FAR *LPRECT;
* CreateSolidBrush: RGB색을 지정하는 브러쉬 함수
* FillRect 함수: 사각형 내부에 색을 채워 출력하는 함수
FillRect(hdc, &rc, CreateSolidBrush(RGB(0, 100, 244)));

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
HDC hdc; //핸들DC
PAINTSTRUCT ps; //페인트구조체
static RECT rc1;
static RECT rc2;
static RECT rc3;
static RECT temp_rc;
switch (iMessage)
{
case WM_CREATE:
rc1 = RectMakeCenter(300, WINSIZEY / 2, 100, 100);
rc2 = RectMakeCenter(500, WINSIZEY / 2, 100, 100);
rc3 = RectMakeCenter((rc1.right + rc1.left) / 2, (rc1.top + rc1.bottom) / 2, 40, 40);
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);
FillRect(hdc, &rc3, CreateSolidBrush(RGB(0, 100, 244)));
EndPaint(hWnd, &ps);
break;
case WM_KEYDOWN: //키보드 키가 눌렸을때 메세지 발생
switch (wParam)
{
case VK_LEFT: //왼쪽 방향키
//좌로갈때 작은 사각형이랑 충돌 처리
if (rc1.right == rc3.right)
{
rc3.left -= 10;
rc3.right -= 10;
}
//겹치고 스왑
if (rc1.left == rc2.right && rc1.top <= rc2.bottom && rc1.top >= rc2.top)
{
temp_rc = rc2;
rc2 = rc1;
rc1 = temp_rc;
rc3 = RectMakeCenter((rc1.right + rc1.left) / 2, (rc1.top + rc1.bottom) / 2, 40, 40);
InvalidateRect(hWnd, NULL, true);
break;
}
if (rc1.left == rc2.right && rc1.bottom >= rc2.top && rc1.bottom <= rc2.bottom)
{
temp_rc = rc2;
rc2 = rc1;
rc1 = temp_rc;
rc3 = RectMakeCenter((rc1.right + rc1.left) / 2, (rc1.top + rc1.bottom) / 2, 40, 40);
InvalidateRect(hWnd, NULL, true);
break;
}
rc1.right -= 10;
rc1.left -= 10;
if (rc1.left < 0)
{
rc1.right += 10;
rc1.left += 10;
rc3.left += 10;
rc3.right += 10;
}
InvalidateRect(hWnd, NULL, true);
break;
case VK_RIGHT: //오른쪽 방향키
//우로갈때 작은 사각형이랑 충돌 처리
if (rc1.left == rc3.left)
{
rc3.left += 10;
rc3.right += 10;
}
//겹치고 스왑
if (rc1.right == rc2.left && rc1.top <= rc2.bottom && rc1.top >= rc2.top)
{
temp_rc = rc2;
rc2 = rc1;
rc1 = temp_rc;
rc3 = RectMakeCenter((rc1.right + rc1.left) / 2, (rc1.top + rc1.bottom) / 2, 40, 40);
InvalidateRect(hWnd, NULL, true);
break;
}
if (rc1.right == rc2.left && rc1.bottom >= rc2.top && rc1.bottom <= rc2.bottom)
{
temp_rc = rc2;
rc2 = rc1;
rc1 = temp_rc;
rc3 = RectMakeCenter((rc1.right + rc1.left) / 2, (rc1.top + rc1.bottom) / 2, 40, 40);
InvalidateRect(hWnd, NULL, true);
break;
}
rc1.right += 10;
rc1.left += 10;
if(rc1.right > 800)
{
rc1.right -= 10;
rc1.left -= 10;
rc3.left -= 10;
rc3.right -= 10;
}
InvalidateRect(hWnd, NULL, true);
break;
case VK_UP://위쪽 방향키
//위로갈때 작은 사각형이랑 충돌 처리
if (rc1.bottom == rc3.bottom)
{
rc3.top -= 10;
rc3.bottom -= 10;
}
//겹치고 스왑
if (rc1.top == rc2.bottom && rc1.right <= rc2.right && rc1.right >= rc2.left)
{
temp_rc = rc2;
rc2 = rc1;
rc1 = temp_rc;
rc3 = RectMakeCenter((rc1.right + rc1.left) / 2, (rc1.top + rc1.bottom) / 2, 40, 40);
InvalidateRect(hWnd, NULL, true);
break;
}
if (rc1.top == rc2.bottom && rc1.left >= rc2.left && rc1.left <= rc2.right)
{
temp_rc = rc2;
rc2 = rc1;
rc1 = temp_rc;
rc3 = RectMakeCenter((rc1.right + rc1.left) / 2, (rc1.top + rc1.bottom) / 2, 40, 40);
InvalidateRect(hWnd, NULL, true);
break;
}
rc1.top -= 10;
rc1.bottom -= 10;
if (rc1.top < 0)
{
rc1.top += 10;
rc1.bottom += 10;
rc3.top += 10;
rc3.bottom += 10;
}
InvalidateRect(hWnd, NULL, true);
break;
case VK_DOWN://아래쪽 방향키
//아래로갈때 작은 사각형이랑 충돌 처리
if (rc1.top == rc3.top)
{
rc3.top += 10;
rc3.bottom += 10;
}
//겹치고 스왑
if (rc1.bottom == rc2.top && rc1.right <= rc2.right && rc1.right >= rc2.left)
{
temp_rc = rc2;
rc2 = rc1;
rc1 = temp_rc;
rc3 = RectMakeCenter((rc1.right + rc1.left) / 2, (rc1.top + rc1.bottom) / 2, 40, 40);
InvalidateRect(hWnd, NULL, true);
break;
}
if (rc1.bottom == rc2.top && rc1.left >= rc2.left && rc1.left <= rc2.right)
{
temp_rc = rc2;
rc2 = rc1;
rc1 = temp_rc;
rc3 = RectMakeCenter((rc1.right + rc1.left) / 2, (rc1.top + rc1.bottom) / 2, 40, 40);
InvalidateRect(hWnd, NULL, true);
break;
}
rc1.top += 10;
rc1.bottom += 10;
if (rc1.bottom > 800)
{
rc1.top -= 10;
rc1.bottom -= 10;
rc3.top -= 10;
rc3.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));
}
- 같은 크기 큰 사각형 두개를 그리고 1개의 사각형 내부에 색이 칠해진 작은 사각형을 그린다.
- 색 사각형을 포함한 큰 사각형을 움직이게 만들고, 색이 칠해진 사각형은 큰 사각형을 벗어나지 못한다.
- 색이 있는 사각형은 움직이는 사각형 내부에만 존재한다.
- 움직이는 사각형이 나머지 큰 사각형에 부딪히면 움직이는 사각형이 변경된다.
* RECT: 사각형을 나타내는 구조체
typedef struct tagRECT
{
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT, *PRECT, NEAR *NPRECT, FAR *LPRECT;
* CreateSolidBrush: RGB색을 지정하는 브러쉬 함수
* FillRect 함수: 사각형 내부에 색을 채워 출력하는 함수
FillRect(hdc, &rc, CreateSolidBrush(RGB(0, 100, 244)));

LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
HDC hdc; //핸들DC
PAINTSTRUCT ps; //페인트구조체
static RECT rc1;
static RECT rc2;
static RECT rc3;
static RECT temp_rc;
switch (iMessage)
{
case WM_CREATE:
rc1 = RectMakeCenter(300, WINSIZEY / 2, 100, 100);
rc2 = RectMakeCenter(500, WINSIZEY / 2, 100, 100);
rc3 = RectMakeCenter((rc1.right + rc1.left) / 2, (rc1.top + rc1.bottom) / 2, 40, 40);
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);
FillRect(hdc, &rc3, CreateSolidBrush(RGB(0, 100, 244)));
EndPaint(hWnd, &ps);
break;
case WM_KEYDOWN: //키보드 키가 눌렸을때 메세지 발생
switch (wParam)
{
case VK_LEFT: //왼쪽 방향키
//좌로갈때 작은 사각형이랑 충돌 처리
if (rc1.right == rc3.right)
{
rc3.left -= 10;
rc3.right -= 10;
}
//겹치고 스왑
if (rc1.left == rc2.right && rc1.top <= rc2.bottom && rc1.top >= rc2.top)
{
temp_rc = rc2;
rc2 = rc1;
rc1 = temp_rc;
rc3 = RectMakeCenter((rc1.right + rc1.left) / 2, (rc1.top + rc1.bottom) / 2, 40, 40);
InvalidateRect(hWnd, NULL, true);
break;
}
if (rc1.left == rc2.right && rc1.bottom >= rc2.top && rc1.bottom <= rc2.bottom)
{
temp_rc = rc2;
rc2 = rc1;
rc1 = temp_rc;
rc3 = RectMakeCenter((rc1.right + rc1.left) / 2, (rc1.top + rc1.bottom) / 2, 40, 40);
InvalidateRect(hWnd, NULL, true);
break;
}
rc1.right -= 10;
rc1.left -= 10;
if (rc1.left < 0)
{
rc1.right += 10;
rc1.left += 10;
rc3.left += 10;
rc3.right += 10;
}
InvalidateRect(hWnd, NULL, true);
break;
case VK_RIGHT: //오른쪽 방향키
//우로갈때 작은 사각형이랑 충돌 처리
if (rc1.left == rc3.left)
{
rc3.left += 10;
rc3.right += 10;
}
//겹치고 스왑
if (rc1.right == rc2.left && rc1.top <= rc2.bottom && rc1.top >= rc2.top)
{
temp_rc = rc2;
rc2 = rc1;
rc1 = temp_rc;
rc3 = RectMakeCenter((rc1.right + rc1.left) / 2, (rc1.top + rc1.bottom) / 2, 40, 40);
InvalidateRect(hWnd, NULL, true);
break;
}
if (rc1.right == rc2.left && rc1.bottom >= rc2.top && rc1.bottom <= rc2.bottom)
{
temp_rc = rc2;
rc2 = rc1;
rc1 = temp_rc;
rc3 = RectMakeCenter((rc1.right + rc1.left) / 2, (rc1.top + rc1.bottom) / 2, 40, 40);
InvalidateRect(hWnd, NULL, true);
break;
}
rc1.right += 10;
rc1.left += 10;
if(rc1.right > 800)
{
rc1.right -= 10;
rc1.left -= 10;
rc3.left -= 10;
rc3.right -= 10;
}
InvalidateRect(hWnd, NULL, true);
break;
case VK_UP://위쪽 방향키
//위로갈때 작은 사각형이랑 충돌 처리
if (rc1.bottom == rc3.bottom)
{
rc3.top -= 10;
rc3.bottom -= 10;
}
//겹치고 스왑
if (rc1.top == rc2.bottom && rc1.right <= rc2.right && rc1.right >= rc2.left)
{
temp_rc = rc2;
rc2 = rc1;
rc1 = temp_rc;
rc3 = RectMakeCenter((rc1.right + rc1.left) / 2, (rc1.top + rc1.bottom) / 2, 40, 40);
InvalidateRect(hWnd, NULL, true);
break;
}
if (rc1.top == rc2.bottom && rc1.left >= rc2.left && rc1.left <= rc2.right)
{
temp_rc = rc2;
rc2 = rc1;
rc1 = temp_rc;
rc3 = RectMakeCenter((rc1.right + rc1.left) / 2, (rc1.top + rc1.bottom) / 2, 40, 40);
InvalidateRect(hWnd, NULL, true);
break;
}
rc1.top -= 10;
rc1.bottom -= 10;
if (rc1.top < 0)
{
rc1.top += 10;
rc1.bottom += 10;
rc3.top += 10;
rc3.bottom += 10;
}
InvalidateRect(hWnd, NULL, true);
break;
case VK_DOWN://아래쪽 방향키
//아래로갈때 작은 사각형이랑 충돌 처리
if (rc1.top == rc3.top)
{
rc3.top += 10;
rc3.bottom += 10;
}
//겹치고 스왑
if (rc1.bottom == rc2.top && rc1.right <= rc2.right && rc1.right >= rc2.left)
{
temp_rc = rc2;
rc2 = rc1;
rc1 = temp_rc;
rc3 = RectMakeCenter((rc1.right + rc1.left) / 2, (rc1.top + rc1.bottom) / 2, 40, 40);
InvalidateRect(hWnd, NULL, true);
break;
}
if (rc1.bottom == rc2.top && rc1.left >= rc2.left && rc1.left <= rc2.right)
{
temp_rc = rc2;
rc2 = rc1;
rc1 = temp_rc;
rc3 = RectMakeCenter((rc1.right + rc1.left) / 2, (rc1.top + rc1.bottom) / 2, 40, 40);
InvalidateRect(hWnd, NULL, true);
break;
}
rc1.top += 10;
rc1.bottom += 10;
if (rc1.bottom > 800)
{
rc1.top -= 10;
rc1.bottom -= 10;
rc3.top -= 10;
rc3.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));
}
댓글
댓글 쓰기