이번에는 입력에 의한 제어가 아닌

 

일정 시간 간격으로 메세지를 보내는 타이머 메세지이다.

 

1
2
3
4
5
6
UINT_PTR SetTimer(
    HWND hWnd,
    UINT_PTR nIDEvent,
    UINT uElapse,
    TIMERPROC lpTimerFunc
    );
cs

 

SetTimer() 함수를 이용한다.

 

nIDEvent : 타이머의 ID로 정수값 (여러개의 타이머를 쓸 경우 구분하기위함)

uElapse : 시간 간격으로 단위는 밀리초 ex) 1000 이 1초

lpTimerFunc : 타이머가 보내는 WM_TIMER 메세지를 받을 함수 이름 NULL 이면 WndProc() 가 WM_TIMER 메세지를 받는다.

 

 

 

 

타이머의 동작을 중간에 정지시킬 떄는 KillTimer() 함수를 사용한다. KillTimer() 함수로 정지시킨 타이머는 SetTimer() 로 다시 동작시킬 수 있다.

 

 

 

1
2
3
4
BOOL KiLLTimer(
    HWND hWnd,
    UINT_PTR nIDEvent,
    );
cs

 

nIDEvent : 동작 중인 타이머의 ID

 

 

 

이제 이를 이용하여 타이머를 설정하고 

 

타이머를 이용하여 원이 자동으로 움직이게 만들어보면

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
    
    HDC hdc;
    PAINTSTRUCT ps;
    static int x,y;
    static RECT rectView;
    
    switch(Message) {
        
        /* Upon destruction, tell the main thread to stop */
        case WM_CREATE:
            x=20; y=20;
            GetClientRect(hwnd,&rectView);
            break
            
        case WM_PAINT:
            hdc = BeginPaint(hwnd,&ps);
            
            Ellipse(hdc,x-20,y-20,x+20,y+20);
            EndPaint(hwnd,&ps);
            break;
        case WM_KEYDOWN:
            if(wParam == VK_RIGHT)
            {
                SetTimer(hwnd,1,70,NULL);
                
            }
            
            break;
        case WM_TIMER:
            x+=40;
            if(x+20>rectView.right)
            {
                x-=40;
            }
            InvalidateRgn(hwnd,NULL,TRUE);    
            
            break;
        case WM_DESTROY: {
            KillTimer(hwnd,1);
            PostQuitMessage(0);
            break;
        }
    
        /* All other messages (a lot of them) are processed using default procedures */
        default:
            return DefWindowProc(hwnd, Message, wParam, lParam);
    }
    return 0;
}
cs

 

이렇게 만들어서 실행해보면 오른쪽 방향키를 누르는 순간 원이 자동으로 오른쪽으로 이동한다.

 

하지만 오른쪽방향키를 꾹 누르고 있는 경우 공이 멈춰버리는데 

 

정확한것은 아니지만

 

내 예상으로는 SetTimer가 설정되고 그 타이머가 WM_TIMER 메세지를 보내기전에 또다시  SetTimer가 만들어져서(오른쪽 방향키를 계속 누르고있으니 WM_KEYDOWN 메세지가 엄청빨리 보내짐) WM_TIMER가 메세지가 발생하지 않았을 것이라 생각된다(SetTimer가 덮어써지는 현상일듯?)

 

 

출처 :

 

핵심 API로 배우는 윈도우 프로그래밍,   강경우 지음   출판사 : 한빛아카데미

이번에는 원을 그리고 키보드로 원을 움직이는 것을 해보겠다

 

먼저 원을 그려야 하는데 

 

원을 그려주는 Ellipse 함수를 이용한다.

 

좌표 2개를 입력으로 받는다 (X1,Y1) , (X2, Y2) 이 두 좌표를 이용하여 사각형을 만들었을때 

 

그 안을 내접하는 원을 만들어준다.

 

예를들어 (0,0)    (40,40) 이라면

 

중심이 (20,20)인 원

 

 

 

1
2
3
4
5
6
7
Bool Ellipse(
    HDC hdc,
    int X1,
    int Y1,
    int X2,
    int Y2
    );
cs

 

ex)

 

 

 

 

1
2
hdc = BeginPaint(hwnd,&ps);
Ellipse(hdc,x-20,y-20,x+20,y+20);
cs

 

 

 

이제 이를 이용하여

 

 

dd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
    
    HDC hdc;
    PAINTSTRUCT ps;
    static int x,y;
    static RECT rectView;
    
    switch(Message) {
        
        /* Upon destruction, tell the main thread to stop */
        case WM_CREATE:
            x=20; y=20;
            break
            
        case WM_PAINT:
            hdc = BeginPaint(hwnd,&ps);
            Ellipse(hdc,x-20,y-20,x+20,y+20);
            EndPaint(hwnd,&ps);
            break;
        case WM_KEYDOWN:
            if(wParam == VK_RIGHT)
            {
    
                x+=40;
            
            }
            InvalidateRgn(hwnd,NULL,TRUE);    
            break;
        case WM_KEYUP:
            
            InvalidateRgn(hwnd,NULL,TRUE);
            break;
        case WM_DESTROY: {
            PostQuitMessage(0);
            break;
        }
    
        /* All other messages (a lot of them) are processed using default procedures */
        default:
            return DefWindowProc(hwnd, Message, wParam, lParam);
    }
    return 0;
}
cs

 

 

이 코드의 경우

 

오른쪽 방향키를 누르면 x가 40만큼 증가하여 원이 오른쪽으로 이동하는 것 처럼 보이게 만들 수 있다.

 

하지만 계속 누르는 경우 윈도우 밖으로 나가버린다.

 

이를 막기 위해 윈도우 크기를 알아내어 해당 윈도우 크기만큼만 이동시킬 수 있는데 

 

GetClientRect()함수로 윈도우 크기를 알아낼 수 있다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
LRESULT CALLBACK WndProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) {
    
    HDC hdc;
    PAINTSTRUCT ps;
    static int x,y;
    static RECT rectView;
    
    switch(Message) {
        
        /* Upon destruction, tell the main thread to stop */
        case WM_CREATE:
            x=20; y=20;
            GetClientRect(hwnd,&rectView);
            break
            
        case WM_PAINT:
            hdc = BeginPaint(hwnd,&ps);
            
            Ellipse(hdc,x-20,y-20,x+20,y+20);
            EndPaint(hwnd,&ps);
            break;
        case WM_KEYDOWN:
            if(wParam == VK_RIGHT)
            {
                
                x+=40;
                if(x+20>rectView.right)
                {
                    x-=40;
                }
            }
            InvalidateRgn(hwnd,NULL,TRUE);    
            break;
        case WM_KEYUP:
            
            InvalidateRgn(hwnd,NULL,TRUE);
            break;
        case WM_DESTROY: {
            PostQuitMessage(0);
            break;
        }
    
        /* All other messages (a lot of them) are processed using default procedures */
        default:
            return DefWindowProc(hwnd, Message, wParam, lParam);
    }
    return 0;
}
cs

 

 

 

 

 

 

 

실행 하면 현재 윈도우 크기 만큼만 원이 이동함을 알 수 있다.

 

하지만 예상대로 윈도우를 최대화로 늘려도 그 이상 이동되진 않았다.

 

이경우는 윈도우의 크기가 변하면 발생하는 WM_SIZE 메세지를 이용한다.

 

 

 

출처 :

 

핵심 API로 배우는 윈도우 프로그래밍,   강경우 지음   출판사 : 한빛아카데미

 

 

망겜을 주로 하다보니 이번 플레이영상은 

 

스타유즈맵 장르인 폭탄피하기 중 puma bound 2라는 맵이다.

 

폭피 유저라면 거의 다 아는 맵이다

 

예전에는 이맵을 깨면 열손가락에 드는 초고수였는데

 

런쳐가 나온이후 저글링의 반응속도가 빨라지면서 지금은 깨는 사람이 많아졌다.

 

나같은 경우만 해도 런쳐가 나오기전 반응으로는 5탄도 깨본적이 없었지만

 

지금은 간단하게 클리어 할 수 있게 되었다.

+ Recent posts