GitHub: https://github.com/cmasfo/cppWindow


이전엔 최소한으로 창을 초기화하는 코드까지만 적었었다.

이번에는 사각형을 띄우고 그것을 WASD로 이동시키는 코드까지 적어볼 것이다.


해당 기능을 위해선 3가지 정도가 필요하다.


1. 사각형을 이동시키기 위한 조작 시스템 구성

2. 이동 속도의 조절을 위한 타이머 시스템 구성

3. 사각형을 띄우기 위한 더블 버퍼링 구조 형성


조작 시스템부터 살펴보도록 하겠다.




WindowsHeader.h





WindowsHeader.cpp


마우스 이동은 지금 쓰이지 않겠지만, 미리 만들어두었다.


핵심을 요약하자면 시스템에 따라 키의 상태가 자동으로 갱신되고,

다른 곳에서 필요에 따라 키의 상태를 체크한다.

키는 윈도우 메시지를 받아서 세팅한다.




이렇게 하면 키보드나 마우스 조작에서 누르거나 뗀 상태들을 갱신할 수 있다.


누른 프레임에서는 JustDown이나 JustUp이 되고

이후 프레임이 끝날 때 Down이나 Up으로 바꿔줄 것이다.




프레임이 시작될 때 마우스 정보를 갱신하고,

프레임이 끝날 때에는 키의 상태들을 갱신해준다.

조작에 대한 정보는 중간에서 필요에 따라 사용한다.


다음은 타이머다.




WindowsHeader.h



WindowsHeader.cpp


LARGE_INTEGER라는 자료형을 활용해

컴퓨터 시스템 고유의 카운터 기능을 사용한다.

Counter는 여태까지 누적된 카운터의 수치를 의미하고,

Frequency는 컴퓨터가 1초에 세는 카운터의 수치를 의미한다.


여기서는 Counter의 차이를 이용해 시간을 잰다.


즉, 카운터의 차이가 10인데 초당 카운터 수가 100이라면

이전 프레임 이후로 0.1초가 지났다는 소리가 된다.

사각형의 이동은 이것을 기반으로 행해질 것이다.


나머지 함수들에 대한 내용도 올리겠지만, 내용은 좀 뻔하다.






이 LimitFPS에 대해서만 설명을 좀 하자면,

현재 상태로는 루프에 제약이 없어 지나치게 많은 성능을 사용한다.

그래서 컴퓨터의 주사율만큼만 갱신을 하도록 하고,

그 이상 하려고 하면 스스로 Sleep으로 제약을 거는 것이다.




이제 사각형을 띄워보도록 하겠다.


Windows API에서 사각형을 띄우는 데 사용되는 함수는 Rectangle이다.

하지만 메인 화면에 사각형을 바로 띄우려고 하면 문제가 생긴다.


Windows API는 기본적으로 메시지가 들어오지 않는 이상 화면을 갱신하려고 하지 않는다.

그래서 여태까지 사각형이 지나갔던 경로가 남게 된다.


그리고 여러 함수를 거쳐 메인 화면에 바로 띄우려고 하면

물체가 빠르게 번갈아가며 나타나 보기에 별로 좋지 않을 것이다.


그래서 백버퍼란 걸 만들어 뒤에서 그려두었다가,

프레임의 최종 단계에 이르렀을 때 그제서야 메인화면에 한번에 표시할 것이다.


백버퍼를 사용하기 위한 함수는 다음과 같다.






코드가 별로 길지 않다.

화면 출력을 위해선 HDC라는 걸 사용하고,

버퍼를 쓰기 위해선 HBITMAP이란 걸 사용해야 한다.

DC는 Device Context를 의미한다.


InitScreen에선 GetDC로 메인 창에 대한 DC를 가져온다.

그리고 그에 호환되는 backDC라는 걸 또 만들어준다.


DC엔 기본적으로 버퍼 개념이 없기 때문에

HBITMAP을 통해서 따로 만들어줘야 한다.


다만 주석에도 적어놓았듯이 주의해야 할 것은

메인DC를 기준으로 만들어야지,

백DC를 기준으로 만들면 출력할 때 이상하게 표시된다.


백DC에 출력할 다른 이미지들은 백DC를 기준으로 만들어도 된다.

다만 최종적으로 보이는 백BMP만큼은 메인DC를 기준으로 만들어야 하는 듯하다.


이제 이를 활용하는 사각형 출력 함수를 만들어보겠다.




가장 기본적인 직사각형과 타원 출력 함수다.


원래 앞에 DC를 받아야 하는데,

여기선 백DC고정이므로 위치 정보만 받아준다.

그리고 물체가 부드럽게 움직이기 위해선 float이어야 하기 때문에

형변환의 귀찮음이 없도록 float 버전의 함수도 만들어준다.


이제 이를 사용하는 RenderObject라는 걸 만들어보도록 하겠다.










렌더모드에 따라 다른 모양을 보여주는 예시를 표현해보았다.


참고로 이동을 저렇게 처리하면 대각선 때 이동을 더 빨리한다.

이동속도를 똑같이 하려면 대각선 때

x y 모두 코사인 45도의 속도로 이동해야 한다.


해결법은 항상 1의 길이를 유지하게끔 normalize 개념을 사용하는 것이지만,

여기선 일단 이동시키는게 목표이므로 인지만 하고 넘어가도록 한다.


이 사각형은 시스템상 필요에 의해 띄우는 게 아니라,

사용자가 원하기 때문에 띄우는 것이므로 클라이언트 측에서 함수를 써보도록 하겠다.



이대로 실행해 보겠다.



사각형이 잘 이동하는 것을 볼 수 있다.


다음번엔 이미지 및 애니메이션 띄우기에 대해서 알아보겠다.


[출처: 프로그램 미니 갤러리 ]