반응형
경일게임아카데미 프로그래밍반 28기 13일차 수업 (2021. 04. 26)
WIN32 API RECT 생성, 이동
#include "stdafx.h"
HINSTANCE _hInstance;
HWND _hWnd;
LPCTSTR _lpszClass = TEXT("경일 28기 :-) ");
void setWindowsSize(int x, int y, int width, int height);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int cmdShow)
{
_hInstance = hInstance;
MSG message;
WNDCLASS wndClass;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hbrBackground = (HBRUSH)GetStockObject(DKGRAY_BRUSH);
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndClass.hInstance = hInstance;
wndClass.lpfnWndProc = (WNDPROC)WndProc;
wndClass.lpszClassName = WINNAME;
wndClass.lpszMenuName = NULL;
wndClass.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wndClass);
_hWnd = CreateWindow(
WINNAME,
WINNAME,
WS_OVERLAPPEDWINDOW,
WINSTARTX,
WINSTARTY,
WINSIZEX,
WINSIZEY,
NULL,
(HMENU)NULL,
hInstance,
NULL);
setWindowsSize(WINSTARTX, WINSTARTY, WINSIZEX, WINSIZEY);
ShowWindow(_hWnd, cmdShow);
while (GetMessage(&message, 0, 0, 0))
{
TranslateMessage(&message);
DispatchMessage(&message);
}
return message.wParam;
}
// 사각형 생성을 위한 RECT (전역변수로 선언해도 무방하다.)
// RECT _rc;
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
// wParam - 모든 키 입력 및 마우스 클릭
// lParam - 마우스 좌표
// 안에서 호출할 땐 static을 꼭 선언하자
static RECT rc;
static RECT rc2;
switch (iMessage)
{
// 윈도우 창이 딱 한번 생성될때 호출되는 것
case WM_CREATE:
rc = RectMakeCenter(WINSIZEX / 2 - 150, WINSIZEY / 2, 100, 100);
rc2 = RectMakeCenter(WINSIZEX / 2, WINSIZEY / 2, 100, 100);
case WM_PAINT:
{
hdc = BeginPaint(hWnd, &ps);
// 사각형 생성
Rectangle(hdc, rc.left, rc.top, rc.right, rc.bottom);
Rectangle(hdc, rc2.left, rc2.top, rc2.right, rc2.bottom);
EndPaint(hWnd, &ps);
break;
}
break;
case WM_KEYDOWN:
// wParam - 모든 키 입력 및 마우스 클릭
switch (wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
break;
case VK_LEFT:
// 왼쪽 벽 바깥으로 못나가게
if (rc.left <= 0) break;
// 이동
rc.left -= 10;
rc.right -= 10;
InvalidateRect(_hWnd, NULL, true);
break;
case VK_RIGHT:
// 이동
rc.left += 10;
rc.right += 10;
// 물체 밀기
if (rc.right >= rc2.left)
{
int width = rc2.right - rc2.left;
rc2.left = rc.right;
rc2.right = rc2.left + width;
}
InvalidateRect(_hWnd, NULL, true);
break;
case VK_UP:
// 이동
rc.top -= 10;
rc.bottom -= 10;
InvalidateRect(_hWnd, NULL, true);
break;
case VK_DOWN:
// 이동
rc.top += 10;
rc.bottom += 10;
InvalidateRect(_hWnd, NULL, true);
break;
}
break;
//윈도우 창 부수는 함수
case WM_DESTROY:
//윈도우 종료함수
PostQuitMessage(0);
return 0;
}
return (DefWindowProc(hWnd, iMessage, wParam, lParam));
}
void setWindowsSize(int x, int y, int width, int height)
{
RECT winRect;
winRect.left = 0;
winRect.top = 0;
winRect.right = width;
winRect.bottom = height;
//얘가 실제 클라이언트 영역 조정 들어가는 함수
AdjustWindowRect(&winRect, WINSTYLE, false);
//조정된 영역으로 다시 한 번 윈도우 위치 잡아주는 함수
SetWindowPos(_hWnd, NULL, x, y, (winRect.right - winRect.left), (winRect.bottom - winRect.top), SWP_NOZORDER | SWP_NOMOVE);
}
RECT를 이용하여 변수 내부/외부 상관없이 사각형을 생성해준다.
해당 소스코드에서는 내부에 사각형을 생성하였다.
이후 WM_CREATE에서 rc, rc2에 사각형을 만드는 함수를 넣어주고
WM_PAINT에서 Rectangle 함수를 이용해 사각형을 그려준다.
그 다음 WM_KEYDOWN을 이용하여 상/하/좌/우키를 누를 때 어떠한 행동을 할 지 작성한다.
VK_LEFT 에서는 왼쪽 벽 바깥으로 나가는 것을 방지하고
VK_RIGHT 에서는 오른쪽에 있는 사각형을 미는 것을 진행했다.
VK_UP, DOWN에서는 키를 누를때에 움직이는 것밖에 하지 않았다.
움직임 결과화면
움직임 충돌 결과화면
반응형
'학원 > 경일게임아카데미' 카테고리의 다른 글
20. 열네번째 수업 (0) | 2022.12.22 |
---|---|
19. 열세번째 수업과제 [사각형 밀기] (0) | 2022.12.22 |
17. 열두번째 수업 (0) | 2022.12.21 |
16. 열한번째 수업과제 [이름 그리기 및 도막사라무 제작] (0) | 2022.12.19 |
15. 열한번째 수업 (0) | 2022.12.16 |