³ª.´õºí ¹öÆÛ¸µ

È­¸é Ãâ·ÂÀÇ ±ô¹ÚÀÓÀ» ÇØ°áÇÒ ¼ö ÀÖ´Â ±Ùº»ÀûÀÌ°íµµ ¿ÏÀüÇÑ ¹æ¹ýÀº ´õºí ¹öÆÛ¸µ(Double Buffering)»ÓÀÌ´Ù. ´õºí ¹öÆÛ¸µÀ̶õ ¿ë¾î ±×´ë·Î ¹öÆÛ¸¦ µÎ °³(¶Ç´Â ±× ÀÌ»ó) »ç¿ëÇÏ´Â ¹æ½ÄÀε¥ È­¸é¿¡ º¸¿©ÁÙ ¹öÆÛ¿Í ³»ºÎ °è»ê¿¡ »ç¿ëÇÒ ¹öÆÛ¸¦ µû·Î À¯ÁöÇÑ´Ù. ³»ºÎ ¹öÆÛ¿¡ ¹Ì¸® ±×¸²À» ±×¸° ÈÄ È­¸é ¹öÆÛ·Î °í¼Ó Àü¼ÛÇÏ¸ç ±×¸®´Â Áß°£ °úÁ¤À» ¼û°ÜÁø ³»ºÎ ¹öÆÛ¿¡¼­ ó¸®ÇÔÀ¸·Î½á »ç¿ëÀÚ´Â ÃÖÁ¾ °á°ú¸¸ º¸µµ·Ï ÇÏ´Â ±â¹ýÀÌ´Ù.

³»ºÎ ¹öÆÛ¿¡¼­ ÀϾ´Â ÀÏÀº »ç¿ëÀÚ¿¡°Ô º¸ÀÌÁö ¾Ê±â ¶§¹®¿¡ ±×¸²ÀÌ ¾Æ¹«¸® º¹ÀâÇØµµ, È­¸éÀ» ´Ù Áö¿î ÈÄ ´Ù½Ã ±×¸®´õ¶óµµ ±ô¹ÚÀÓÀ» ÀüÇô ¸ñ°ÝÇÒ ¼ö°¡ ¾ø´Ù. »Ó¸¸ ¾Æ´Ï¶ó ±×¸®´Â ¼ø¼­¿¡ µû¶ó À̹ÌÁö°£ÀÇ ¼öÁ÷ÀûÀÎ ¾Æ·¡ À§¸¦ ÁöÁ¤ÇÒ ¼ö ÀÖÀ¸¸ç ¿©·¯ °³ÀÇ À̹ÌÁö¸¦ µ¿½Ã¿¡ ¿òÁ÷ÀÌ´Â °Íµµ ¾ÆÁÖ ºÎµå·´°Ô ó¸®ÇÒ ¼ö ÀÖ´Ù.

´õºí ¹öÆÛ¸µ¿¡ »ç¿ëµÇ´Â ³»ºÎ ¹öÆÛ´Â ±¸Ã¼ÀûÀ¸·Î ¸Þ¸ð¸® ¿µ¿ªÀε¥ ÀÌ ¸Þ¸ð¸® ¿µ¿ªÀº ¿ÜºÎ ¹öÆÛ, Áï È­¸éÀÇ Æ÷¸Ë°ú ȣȯµÇ¾î¾ß ÇÑ´Ù. ±×·¡¾ß ³»ºÎ ¹öÆÛ¿¡ ±×¸° ±×¸²À» º°µµÀÇ Á¶ÀÛ¾øÀÌ ¿ÜºÎ ¹öÆÛ·Î °í¼Ó Àü¼ÛÇÒ ¼ö ÀÖ´Ù. °ú°Å DOS ½ÃÀý¿¡´Â ³»ºÎ ¹öÆÛ¸¦ ºñµð¿À ·¥ÀÇ ¹°¸®ÀûÀÎ Æ÷¸Ë´ë·Î ÀÛ¼ºÇÑ ÈÄ ºñµð¿À ·¥À¸·Î °ð¹Ù·Î Àü¼ÛÇÏ´Â ¹æ½ÄÀ» »ç¿ëÇß¾ú´Ù. ¶Ç´Â ¾Æ¿¹ ºñµð¿À Ä«µå°¡ Çϵå¿þ¾îÀûÀ¸·Î ¿©·¯ °³ÀÇ ÆäÀÌÁö¸¦ Á¦°øÇÏ¿© ÆäÀÌÁö¸¦ ±³Ã¼ÇÏ´Â ¹æ½ÄÀ» »ç¿ëÇϱ⵵ Çß´Ù.

À©µµ¿ìÁî¿¡¼­´Â ³»ºÎ ¹öÆÛ¸¦ ¸Þ¸ð¸®¿¡ Á÷Á¢ ÀÛ¼ºÇÒ Çʿ䰡 ¾ø´Âµ¥ ¿Ö³ÄÇÏ¸é ºñÆ®¸ÊÀÌ ³»ºÎ ¹öÆÛ ¿ªÇÒÀ» ÇØ Áֱ⠶§¹®ÀÌ´Ù. È­¸é DC¿Í ȣȯµÇ´Â, Áï »ö»ó Æ÷¸ËÀÌ °°°í Å©±â°¡ µ¿ÀÏÇÑ ºñÆ®¸ÊÀ» »ý¼ºÇÑ ÈÄ ÀÌ ºñÆ®¸Ê¿¡ ±×¸²À» ±×¸®¸é ºñÆ®¸Ê ÀÚü°¡ ³»ºÎ ¹öÆÛ ¿ªÇÒÀ» ÇÏ°Ô µÈ´Ù. ºñÆ®¸Ê¿¡ ±×·ÁÁø ±×¸²À» È­¸éÀ¸·Î Àü¼ÛÇÒ ¶§´Â ¹°·Ð BitBlt ÇÔ¼ö¸¦ »ç¿ëÇÑ´Ù. ¾Õ¿¡¼­ ¸¸µç Bounce ¿¹Á¦¸¦ ´õºí ¹öÆÛ¸µÀ¸·Î ´Ù½Ã ÀÛ¼ºÇØ º¸ÀÚ.

 

#define R 20

int x,y;

int xi,yi;

HBITMAP hBit;

void OnTimer()

{

RECT crt;

HDC hdc,hMemDC;

HBITMAP OldBit;

HPEN hPen,OldPen;

HBRUSH hBrush,OldBrush;

int i;

 

GetClientRect(hWndMain,&crt);

hdc=GetDC(hWndMain);

 

if (hBit==NULL) {

    hBit=CreateCompatibleBitmap(hdc,crt.right,crt.bottom);

}

hMemDC=CreateCompatibleDC(hdc);

OldBit=(HBITMAP)SelectObject(hMemDC,hBit);

 

FillRect(hMemDC,&crt,GetSysColorBrush(COLOR_WINDOW));

 

if (x <= R || x >= crt.right-R) {

    xi*=-1;

}

if (y <= R || y >= crt.bottom-R) {

    yi*=-1;

}

x+=xi;

y+=yi;

 

for (i=0;i<crt.right;i+=10) {

    MoveToEx(hMemDC,i,0,NULL);

    LineTo(hMemDC,i,crt.bottom);

}

 

for (i=0;i<crt.bottom;i+=10) {

    MoveToEx(hMemDC,0,i,NULL);

    LineTo(hMemDC,crt.right,i);

}

 

hPen=CreatePen(PS_INSIDEFRAME,5,RGB(255,0,0));

OldPen=(HPEN)SelectObject(hMemDC,hPen);

hBrush=CreateSolidBrush(RGB(0,0,255));

OldBrush=(HBRUSH)SelectObject(hMemDC,hBrush);

Ellipse(hMemDC,x-R,y-R,x+R,y+R);

DeleteObject(SelectObject(hMemDC,OldPen));

DeleteObject(SelectObject(hMemDC,OldBrush));

 

SelectObject(hMemDC,OldBit);

DeleteDC(hMemDC);

ReleaseDC(hWndMain,hdc);

InvalidateRect(hWndMain,NULL,FALSE);

}

 

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)

{

HDC hdc,hMemDC;

PAINTSTRUCT ps;

HBITMAP OldBit;

RECT crt;

 

switch(iMessage) {

case WM_CREATE:

    x=50;

    y=50;

    xi=4;

    yi=5;

    SetTimer(hWnd,1,25,NULL);

    return 0;

case WM_TIMER:

    OnTimer();

   return 0;

case WM_PAINT:

    hdc=BeginPaint(hWnd, &ps);

    GetClientRect(hWnd,&crt);

    hMemDC=CreateCompatibleDC(hdc);

    OldBit=(HBITMAP)SelectObject(hMemDC, hBit);

    BitBlt(hdc,0,0,crt.right,crt.bottom,hMemDC,0,0,SRCCOPY);

    SelectObject(hMemDC, OldBit);

   DeleteDC(hMemDC);

    EndPaint(hWnd, &ps);

    return 0;

case WM_DESTROY:

    if (hBit) {

       DeleteObject(hBit);

    }

    PostQuitMessage(0);

    KillTimer(hWnd,1);

    return 0;

}

return(DefWindowProc(hWnd,iMessage,wParam,lParam));

}

 

Àü¿ª ºñÆ®¸Ê ÇÚµé hBit°¡ ¼±¾ðµÇ¾î ÀÖÀ¸¸ç ÀÌ ºñÆ®¸ÊÀº ÀÛ¾÷¿µ¿ª°ú µ¿ÀÏÇÑ Å©±â´ë·Î »ý¼ºµÈ´Ù. OnTimer¿¡¼­ ¸Þ¸ð¸® DC¸¦ »ý¼ºÇϰí ÀÌ DC¿¡ ºñÆ®¸ÊÀ» ¼±ÅÃÇÑ ÈÄ ¸Þ¸ð¸® DC¿¡ ±×¸²À» Ãâ·ÂÇÏ¸é ¸ðµç Ãâ·ÂÀÌ ºñÆ®¸Ê¿¡ ÀÛ¼ºµÉ °ÍÀÌ´Ù. Bounce ¿¹Á¦ÀÇ WM_PAINT¿¡ ÀÖ´ø ±×¸®±â ÄÚµåµéÀÌ ¸ðµÎ OnTimer·Î À̵¿µÇ¾ú´Ù. OnTimer´Â ºñÆ®¸Ê¿¡ ±×¸²À» ±×¸° ÈÄ InvalidateRect ÇÔ¼ö¸¦ È£ÃâÇÏ¿© ÀÛ¾÷¿µ¿ªÀ» ¹«È¿È­Çϱ⸸ ÇÑ´Ù. À̶§ ºñÆ®¸ÊÀ¸·Î È­¸éÀ» ¿ÏÀüÈ÷ µ¤À» ¼ö ÀÖÀ¸¹Ç·Î ÀÛ¾÷ ¿µ¿ªÀº Áö¿ï Çʿ䰡 ¾øÀ¸¸ç ¸¶Áö¸· Àμö´Â FALSE·Î ÁÖ¾î¾ß ÇÑ´Ù.

ÀÌ ¿¹Á¦¿¡¼­ OnTimer ÇÔ¼ö´Â ³»ºÎ ¹öÆÛ¿¡ ¹Ì¸® ±×¸²À» ±×·Á µÎ´Â ÀÛ¾÷À» Çϴµ¥ ÀÌ ÇÔ¼ö°¡ ´õºí ¹öÆÛ¸µÀÇ ÇÙ½ÉÀÌ´Ù. OnTimerÀÇ Á÷Á¢ÀûÀÎ °á°ú¹°Àº hBit¿¡ ±×·ÁÁø ±×¸²»ÓÀ̸ç ÀÌ ºñÆ®¸Ê¿¡ ±×¸²À» ±×¸®´Â °úÁ¤Àº ¾Æ¹«·¡µµ »ó°ü¾ø´Ù. ¸ðµÎ Áö¿î ÈÄ ±×¸®µç, ¾þ¾î¼­ ±×¸®µç ¾îÂ÷ÇÇ »ç¿ëÀÚ¿¡°Ô´Â º¸ÀÌÁö ¾Ê´Â´Ù.

ÀÌ Äڵ忡¼­ ÈçÈ÷ ¿ÀÇØÇϱ⠽¬¿î °ÍÀÌ Àִµ¥ ¸Þ¸ð¸® ºñÆ®¸ÊÀÎ hBit¿Í ¸Þ¸ð¸® DCÀÎ hMemDC¿ÍÀÇ °ü°èÀÌ´Ù. GDI Ãâ·Â ÇÔ¼öµéÀº ¹Ýµå½Ã DC ÇÚµéÀ» ¿ä±¸ÇÏ¸ç ºñÆ®¸Ê¿¡ Ãâ·ÂÇϱâ À§Çؼ­´Â ÀÌ ºñÆ®¸ÊÀ» ¼±ÅÃÇϰí ÀÖ´Â ¸Þ¸ð¸® DCÀÇ ÇÚµéÀÌ ÇÊ¿äÇÏ´Ù. ±×·¡¼­ È­¸é DC¿Í ȣȯµÇ´Â(=ºñÆ®¸Ê°ú ȣȯµÇ´Â) hMemDC¸¦ »ý¼ºÇÏ°í ¿©±â¿¡ ºñÆ®¸ÊÀ» ¼±ÅÃÇÑ ÈÄ Ãâ·ÂÇß´Ù. ÀÌ DC´Â ¾îµð±îÁö³ª ºñÆ®¸Ê Ãâ·ÂÀ» À§ÇÑ Àӽà DCÀ̹ǷΠºñÆ®¸ÊÀ» ´Ù ÀÛ¼ºÇÏ°í ³­ ´ÙÀ½¿¡´Â ÇØÁ¦µÇ¾î¾ß ÇÑ´Ù.

´õºí ¹öÆÛ¸µ¿¡¼­ ³»ºÎ ¹öÆÛ¶ó°í ĪÇÏ´Â °ÍÀº ºñÆ®¸ÊÀÌÁö ¸Þ¸ð¸® DC°¡ ¾Æ´Ï´Ù. ¸Þ¸ð¸® DC´Â ºñÆ®¸ÊÀ» ¼±ÅÃÇϱâ À§ÇØ Àá½Ã¸¸ »ç¿ëµÇ´Â DCÀÏ »ÓÀε¥ ¾Ë´Ù½ÃÇÇ ºñÆ®¸ÊÀ» ¼±ÅÃÇÒ ¼ö ÀÖ´Â DC´Â ¸Þ¸ð¸® DC¹Û¿¡ ¾ø±â ¶§¹®ÀÌ´Ù. ±×·¡¼­ Àü¿ªÀ¸·Î ÀúÀåÇØ¾ß ÇÒ ´ë»óÀº hBit ºñÆ®¸ÊÀÌÁö hMemDC°¡ ¾Æ´Ï´Ù.

WM_PAINT¿¡¼­´Â OnTimer°¡ ÀÛ¼ºÇØ ³õÀº ºñÆ®¸ÊÀ» È­¸éÀ¸·Î Àü¼ÛÇϱ⸸ ÇÑ´Ù. Áï, ÀÌ¹Ì ±×·ÁÁ® ÀÖ´Â ±×¸²(³»ºÎ ¹öÆÛ)À» È­¸é(¿ÜºÎ ¹öÆÛ)À¸·Î º¹»ç¸¸ ÇÏ´Â °ÍÀÌ´Ù. ½ÇÇà °á°ú´Â ´ÙÀ½°ú °°´Ù. Áö¸éÀ¸·Î º¸±â¿¡´Â °á°ú°¡ µ¿ÀÏÇÏÁö¸¸ ½ÇÁ¦·Î ½ÇÇàÇØ º¸¸é ±ô¹ÚÀÓÀ» ÀüÇô ´À³¥ ¼ö ¾øÀ» °ÍÀÌ´Ù. ¾Ö´Ï¸ÞÀ̼ÇÀÌ ¾ÆÁÖ ºÎµå·´°Ô ½ÇÇàµÈ´Ù.

ÀÌ °æ¿ìµµ OnTimer¿¡¼­ FillRect ÇÔ¼ö¸¦ È£ÃâÇÏ¿© ÀÌÀü ±×¸²À» Áö¿ì±â´Â Çϴµ¥ ³»ºÎ ¹öÆÛ¿¡¼­ ÀϾ´Â ÀÏÀ̱⠶§¹®¿¡ È­¸éÀ» Áö¿î »óÅ´ »ç¿ëÀÚ ´«¿¡ º¸ÀÌÁö ¾ÊÀ¸¸ç µû¶ó¼­ ±ô¹ÚÀÓÀÌ ÀüÇô ¾ø´Â °ÍÀÌ´Ù. ÀÌ·± ¹æ½Ä´ë·Î¶ó¸é ¿©·¯ °³ÀÇ °øÀ» ÇѲ¨¹ø¿¡ ¿òÁ÷ÀÌ´õ¶óµµ ÀüÇô ¹«¸®°¡ ¾ø´Ù. Bounce3 ¿¹Á¦´Â ÇѲ¨¹ø¿¡ 10°³ÀÇ °øÀ» ¿òÁ÷ÀδÙ.

 

#define R 20

int x[10],y[10];

int xi[10],yi[10];

HBITMAP hBit;

void OnTimer()

{

RECT crt;

HDC hdc,hMemDC;

HBITMAP OldBit;

HPEN hPen,OldPen;

HBRUSH hBrush,OldBrush;

int i,ball;

 

GetClientRect(hWndMain,&crt);

hdc=GetDC(hWndMain);

 

if (hBit==NULL) {

    hBit=CreateCompatibleBitmap(hdc,crt.right,crt.bottom);

}

hMemDC=CreateCompatibleDC(hdc);

OldBit=(HBITMAP)SelectObject(hMemDC,hBit);

 

FillRect(hMemDC,&crt,GetSysColorBrush(COLOR_WINDOW));

for (i=0;i<crt.right;i+=10) {

    MoveToEx(hMemDC,i,0,NULL);

    LineTo(hMemDC,i,crt.bottom);

}

 

for (i=0;i<crt.bottom;i+=10) {

    MoveToEx(hMemDC,0,i,NULL);

    LineTo(hMemDC,crt.right,i);

}

 

hPen=CreatePen(PS_INSIDEFRAME,5,RGB(255,0,0));

OldPen=(HPEN)SelectObject(hMemDC,hPen);

hBrush=CreateSolidBrush(RGB(0,0,255));

OldBrush=(HBRUSH)SelectObject(hMemDC,hBrush);

 

for (ball=0;ball<10;ball++) {

    if (x[ball] <= R || x[ball] >= crt.right-R) {

       xi[ball]*=-1;

    }

    if (y[ball] <= R || y[ball] >= crt.bottom-R) {

       yi[ball]*=-1;

    }

    x[ball]+=xi[ball];

    y[ball]+=yi[ball];

 

    Ellipse(hMemDC,x[ball]-R,y[ball]-R,x[ball]+R,y[ball]+R);

}

 

 

DeleteObject(SelectObject(hMemDC,OldPen));

DeleteObject(SelectObject(hMemDC,OldBrush));

 

SelectObject(hMemDC,OldBit);

DeleteDC(hMemDC);

ReleaseDC(hWndMain,hdc);

InvalidateRect(hWndMain,NULL,FALSE);

}

 

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage,WPARAM wParam,LPARAM lParam)

{

HDC hdc,hMemDC;

PAINTSTRUCT ps;

HBITMAP OldBit;

RECT crt;

int ball;

 

switch(iMessage) {

case WM_CREATE:

    for (ball=0;ball<10;ball++) {

       x[ball]=50;

       y[ball]=50;

    }

    xi[0]=4;yi[0]=5;

    xi[1]=5;yi[1]=4;

    xi[2]=3;yi[2]=4;

    xi[3]=8;yi[3]=3;

    xi[4]=3;yi[4]=8;

    xi[5]=2;yi[5]=1;

    xi[6]=10;yi[6]=12;

    xi[7]=12;yi[7]=16;

    xi[8]=3;yi[8]=3;

    xi[9]=6;yi[9]=7;

    SetTimer(hWnd,1,25,NULL);

    return 0;

case WM_TIMER:

    OnTimer();

    return 0;

case WM_PAINT:

    hdc=BeginPaint(hWnd, &ps);

    GetClientRect(hWnd,&crt);

    hMemDC=CreateCompatibleDC(hdc);

    OldBit=(HBITMAP)SelectObject(hMemDC, hBit);

    BitBlt(hdc,0,0,crt.right,crt.bottom,hMemDC,0,0,SRCCOPY);

    SelectObject(hMemDC, OldBit);

    DeleteDC(hMemDC);

    EndPaint(hWnd, &ps);

    return 0;

case WM_DESTROY:

    if (hBit) {

       DeleteObject(hBit);

    }

    PostQuitMessage(0);

    KillTimer(hWnd,1);

    return 0;

}

return(DefWindowProc(hWnd,iMessage,wParam,lParam));

}

 

°øÀÇ ÁÂÇ¥¸¦ ±â¾ïÇÏ´Â x,y¿Í ÁÂÇ¥ÀÇ ÁõºÐ°ªÀÎ ix,iy¸¦ Å©±â 10ÀÇ ¹è¿­·Î Á¤ÀÇÇßÀ¸¸ç OnTimer¿¡¼­ 10¹ø ·çÇÁ¸¦ µ¹¸é¼­ °ø 10°³¸¦ ÇѲ¨¹ø¿¡ À̵¿½ÃŲ´Ù. °¢ °øÀÇ À̵¿ ÁõºÐÀ» ´Ù¸£°Ô ÁÖ¾î À̵¿ ¼Óµµ¸¦ ´Ù¾çÇÏ°Ô Ã³¸®ÇØ º¸¾Ò´Ù. Á÷Á¢ ½ÇÇàÇØ º¸¸é ¾Ë°ÚÁö¸¸ ÇѲ¨¹ø¿¡ 10°³ÀÇ ¹°Ã¼°¡ º¹ÀâÇÏ°Ô ¿òÁ÷ÀÌ´õ¶óµµ ÀüÇô ±ô¹Ú°Å¸®Áö ¾ÊÀ¸¸ç ¼Óµµ°¡ ½ÉÇÏ°Ô ´À·ÁÁö´Â °Íµµ ¾Æ´Ï´Ù.

´õºí ¹öÆÛ¸µÀÇ ´ÜÁ¡À̶ó¸é ÀÏ´Ü ³»ºÎ ¹öÆÛ¿¡ ±×¸²À» ±×¸° ÈÄ ´Ù½Ã ¿ÜºÎ ¹öÆÛ·Î Àü¼ÛÇϱ⠶§¹®¿¡ ÀüüÀûÀÎ ¼Óµµ°¡ ´À·ÁÁú ¼ö ÀÖ´Ù´Â Á¡ÀÌ´Ù. À̶§ 1ÃÊ¿¡ ¸î¹ø¾¿ Àü¼ÛÇÒ ¼ö Àִ°¡¸¦ ÇÁ·¹ÀÓ ·¹ÀÌÆ®(Frame Rate)¶ó°í Çϴµ¥ ³»ºÎ ¹öÆÛ¿¡ ±×¸²À» ÁغñÇÏ´Â °úÁ¤ÀÌ º¹ÀâÇÒ¼ö·Ï ÇÁ·¹ÀÓ ¼ö°¡ ¶³¾îÁø´Ù. ´ÙÇàÈ÷ º¸Åë »ç¶÷ÀÇ ´«Àº 1ÃÊ¿¡ 16¹ø ÀÌ»óÀÇ º¯È­¸¦ °¨ÁöÇÏÁö ¸øÇϱ⠶§¹®¿¡ 16ÇÁ·¹ÀÓ ÀÌ»ó¸¸ µÇ¸é ºÎµå·¯¿î ¿òÁ÷ÀÓÀ» ±¸ÇöÇÒ ¼ö ÀÖ´Ù. ¹°·Ð ±×º¸´Ù ÇÁ·¹ÀÓ ¼ö°¡ ´õ ³ôÀ¸¸é ¾Ö´Ï¸ÞÀ̼ÇÀÇ Ç°ÁúÀº ´õ¿í ³ô¾ÆÁú °ÍÀÌ´Ù.