학습목표    1

학습주제    1

예습내용    1

실습방법    1

        1

중요함수    1

배경과 함성된 애니메이션

학습목표

배경과 합성된 애니메이션 프로그램을 만든다.

학습주제

 

예습내용

 

실습방법

   

1.      배경 그림은 리소스에 추가한다. [그림 내려받기]

그림과 같이 “res” 디렉토리에 그림이 복사된 것을 확인 한다.

 

하늘 그림은 ID “IDB_BACK”으로 바꾼다.

그림자의 ID “IDB_MASK” 한다.

아래 그림과 같이 배경을 그리는 함수 “DrawBack” 만든다.

DrawBack() 함수에 아래와 같이 프로그램 하고 이를 OnPaint() 함수에세 실행하게 프로그램 한다.

 

예제1

 

 

void CBmpDlg::OnPaint()

{

              if (IsIconic())

              {

                             CPaintDC dc(this); // 그리기를위한디바이스컨텍스트

 

                             SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

 

                             // 클라이언트사각형에서아이콘을가운데에맞춥니다.

                             int cxIcon = GetSystemMetrics(SM_CXICON);

                             int cyIcon = GetSystemMetrics(SM_CYICON);

                             CRect rect;

                             GetClientRect(&rect);

                             int x = (rect.Width() - cxIcon + 1) / 2;

                             int y = (rect.Height() - cyIcon + 1) / 2;

 

                             // 아이콘을그립니다.

                             dc.DrawIcon(x, y, m_hIcon);

              }

              else

              {

                             DrawBack();

                             CDialog::OnPaint();

              }

}

 

void CBmpDlg::DrawBack(void)

{

              CClientDC dc(this);

 

              // 호환성있는메모리DC를생성

              CDC MemDC;

              MemDC.CreateCompatibleDC(&dc);

 

              // 리소스에서비트맵을읽어들여DC에선택

              CBitmap bitmap;

              bitmap. LoadBitmap(IDB_BACK);

              CBitmap *pOldBitmap = (CBitmap *)MemDC.SelectObject(&bitmap);

 

              // 비트맵블록전송

              dc.BitBlt(0, 0, 256, 192, &MemDC, 0, 0, SRCCOPY);

 

              MemDC.SelectObject(pOldBitmap);

}

 

 

 

 

여기까지 프로그램을 실행하면 아래 그림과 같이 그림이 자연스럽지않다. 다음은 이를 수정하는 프로그램을 만든다.

 

 

마스크는 그림 부분만 검정색(비트0)이다. 이는 다른 그림과 AND 연산을 하여도 0 되어 검정색이 되고 하얀 부분(비트1) AND 연산을 해도 그대로 출력된다. 그러므로 배경은 AND 연산을 하고 아이콘은 OR 연산을 하면 배경과 아이콘을 그대로 살릴 있다.

DrawBitmap 함수를 아래와 같이 수정한다.

 

void CBmpDlg::DrawBitmap(void)

{

              static int nAnimate;

              CClientDC dc(this);

 

              // 호환성있는메모리DC를생성

              CDC MemDC;

              MemDC.CreateCompatibleDC(&dc);

 

              // 리소스에서비트맵읽기

              CBitmap bmpMask, bmpMan, bmpBack;

              bmpMask.LoadBitmap(IDB_MASK);

              bmpMan.LoadBitmap(IDB_MAN);

              bmpBack.LoadBitmap(IDB_BACK);

 

              // 배경다시그리기

              CBitmap *pOldBitmap = (CBitmap *)MemDC.SelectObject(&bmpBack);

              dc.BitBlt(0, 0, 256, 192, &MemDC, 0, 0, SRCCOPY);

 

              // 마스크그리기

              MemDC.SelectObject(&bmpMask);

              dc.BitBlt(50, 50, 32, 32, &MemDC, 32*nAnimate, 0, SRCAND);

 

              // 아이콘그림그리기

              MemDC.SelectObject(&bmpMan);

              dc.BitBlt(50, 50, 32, 32, &MemDC, 32*nAnimate, 0, SRCPAINT);

 

              // 애니메이션카운터를증가시킴

              if(++nAnimate > 3) nAnimate = 0;

 

              MemDC.SelectObject(pOldBitmap);

}

 

 

 

 

 

 

처음

   

1.      프로그램에서 동영상의 좌표를 변화시켜 동작시켜 보자

[전체프로그램 내려받기]

헤더 파일에 다음 변수를 추가 시킨다.

 

public:

              int xLoc,yLoc;

              void DrawBitmap();

              virtual ~CBMPView();

 

다음의 함수를 수정한다.

 

BOOL CBmpDlg::OnInitDialog()

{

        CDialog::OnInitDialog();

 

        // 시스템메뉴에"정보..." 메뉴항목을추가합니다.

 

        // IDM_ABOUTBOX는시스템명령범위에있어야합니다.

        ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

        ASSERT(IDM_ABOUTBOX < 0xF000);

 

        CMenu* pSysMenu = GetSystemMenu(FALSE);

        if (pSysMenu != NULL)

        {

                CString strAboutMenu;

                strAboutMenu.LoadString(IDS_ABOUTBOX);

                if (!strAboutMenu.IsEmpty())

                {

                        pSysMenu->AppendMenu(MF_SEPARATOR);

                        pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

                }

        }

 

        // 이대화상자의아이콘을설정합니다. 응용프로그램의주창이대화상자가아닐경우에는

        //  프레임워크가이작업을자동으로수행합니다.

        SetIcon(m_hIcon, TRUE);                  // 큰아이콘을설정합니다.

        SetIcon(m_hIcon, FALSE);         // 작은아이콘을설정합니다.

 

        // TODO: 여기에추가초기화작업을추가합니다.

        xLoc=150;  yLoc=150;

        SetTimer(0,200,NULL);

        return TRUE;  // 포커스를컨트롤에설정하지않으면TRUE를반환합니다.

}

void CBmpDlg::DrawBitmap(void)

{

        static int nAnimate;

        CClientDC dc(this);

 

        // 호환성있는메모리DC를생성

        CDC MemDC;

        MemDC.CreateCompatibleDC(&dc);

 

        // 리소스에서비트맵읽기

        CBitmap bmpMask, bmpMan, bmpBack;

        bmpMask.LoadBitmap(IDB_MASK);

        bmpMan.LoadBitmap(IDB_MAN);

        bmpBack.LoadBitmap(IDB_BACK);

 

        // 배경다시그리기

        CBitmap *pOldBitmap = (CBitmap *)MemDC.SelectObject(&bmpBack);

        dc.BitBlt(0, 0, 256, 192, &MemDC, 0, 0, SRCCOPY);

 

        // 마스크그리기

        MemDC.SelectObject(&bmpMask);

        dc.BitBlt(xLoc, yLoc, 32, 32, &MemDC, 32*nAnimate, 0, SRCAND);

 

        // 아이콘그림그리기

        MemDC.SelectObject(&bmpMan);

        dc.BitBlt(xLoc, yLoc, 32, 32, &MemDC, 32*nAnimate, 0, SRCPAINT);

 

        // 애니메이션카운터를증가시킴

        if(++nAnimate > 3) nAnimate = 0;

 

        MemDC.SelectObject(pOldBitmap);

}

 

void CBmpDlg::OnTimer(UINT_PTR nIDEvent)

{

        // TODO: 여기에메시지처리기코드를추가및/또는기본값을호출합니다.

        // 그림의좌표값을xLoc,yLoc 로하고이값을변화시킨다.

        xLoc--;

        yLoc--;

        if(xLoc<=0)

                xLoc=150;

        if(yLoc<=0)

                yLoc=150;

 

        DrawBitmap();

        CDialog::OnTimer(nIDEvent);

}

 

 

2.      과제1 동작은 좌측으로 움직이나 이번에는 우측으로 이동하는 프로그램을 만들어 본다. 이는 StretchBlt 함수를 사용하여 그림을 x축으로 회전 시켜 그림을 이동 시킨다. 과제1 프로그램에서 아래 함수와 좌표를 변화시키면 된다.

WalkRight() 함수를 만든다.

[전체프로그램 내려받기]

 

void CBmpDlg::OnTimer(UINT_PTR nIDEvent)

{

        // TODO: 여기에메시지처리기코드를추가및/또는기본값을호출합니다.

        // 그림의좌표값을xLoc,yLoc 로하고이값을변화시킨다.

        xLoc++;

        yLoc--;

        if(xLoc>=150)

                xLoc=0;

        if(yLoc<=0)

                yLoc=150;

 

        //DrawBitmap();

        WalkRight();

        CDialog::OnTimer(nIDEvent);

}

 

void CBmpDlg::WalkRight(void)

{

        static int nAnimate;

        CClientDC dc(this);

 

        // 호환성있는메모리DC를생성

        CDC MemDC;

        MemDC.CreateCompatibleDC(&dc);

 

        // 리소스에서비트맵읽기

        CBitmap bmpMask, bmpMan, bmpBack;

        bmpMask.LoadBitmap(IDB_MASK);

        bmpMan.LoadBitmap(IDB_MAN);

        bmpBack.LoadBitmap(IDB_BACK);

 

        // 배경다시그리기

        CBitmap *pOldBitmap = (CBitmap *)MemDC.SelectObject(&bmpBack);

        dc.BitBlt(0, 0, 256, 192, &MemDC, 0, 0, SRCCOPY);

 

        // 마스크그리기

        MemDC.SelectObject(&bmpMask);

        dc.StretchBlt(xLoc, yLoc, 32, 32, &MemDC, 32*(1+nAnimate), 0, -32, 32, SRCAND);

        // 아이콘그림그리기

        MemDC.SelectObject(&bmpMan);

        dc.StretchBlt(xLoc, yLoc, 32, 32, &MemDC, 32*(1+nAnimate), 0, -32, 32, SRCPAINT);

 

        // 애니메이션카운터를증가시킴

        if(++nAnimate > 3) nAnimate = 0;

 

        MemDC.SelectObject(pOldBitmap);

}

 

BOOL CBmpDlg::OnInitDialog()

{

        // ==============프로그램생략==============================

        // TODO: 여기에추가초기화작업을추가합니다.

        xLoc=0;  yLoc=150;

        SetTimer(0,200,NULL);

        return TRUE;  // 포커스를컨트롤에설정하지않으면TRUE를반환합니다.

}

 

 

3.      과제1 과제2 합성하여 좌우로 움직이는 에니메이션을 만드시오

int nModeWalk; 선언하고 OnInitDialog () 함수에 초기치를 0으로 한다.

 0 WalkRight() 프로그램을 1 WalkLeft() 프로그램이 타이머 함수에서 동작 하도록 한다.

   [전체프로그램 내려받기]

 

BOOL CBmpDlg::OnInitDialog()

{

        CDialog::OnInitDialog();

 

        // 시스템메뉴에"정보..." 메뉴항목을추가합니다.

 

        // IDM_ABOUTBOX는시스템명령범위에있어야합니다.

        ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

        ASSERT(IDM_ABOUTBOX < 0xF000);

 

        CMenu* pSysMenu = GetSystemMenu(FALSE);

        if (pSysMenu != NULL)

        {

                CString strAboutMenu;

                strAboutMenu.LoadString(IDS_ABOUTBOX);

                if (!strAboutMenu.IsEmpty())

                {

                        pSysMenu->AppendMenu(MF_SEPARATOR);

                        pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);

                }

        }

 

        // 이대화상자의아이콘을설정합니다. 응용프로그램의주창이대화상자가아닐경우에는

        //  프레임워크가이작업을자동으로수행합니다.

        SetIcon(m_hIcon, TRUE);                  // 큰아이콘을설정합니다.

        SetIcon(m_hIcon, FALSE);         // 작은아이콘을설정합니다.

 

        // TODO: 여기에추가초기화작업을추가합니다.

        nModeWalk=0;

        xLoc=0;  yLoc=10;

        SetTimer(0,200,NULL);

        return TRUE;  // 포커스를컨트롤에설정하지않으면TRUE를반환합니다.

}

 

void CBmpDlg::OnTimer(UINT_PTR nIDEvent)

{

        // TODO: 여기에메시지처리기코드를추가및/또는기본값을호출합니다.

        // 그림의좌표값을xLoc,yLoc 로하고이값을변화시킨다.

        if(xLoc>=220)

                nModeWalk = 1;

        else if(xLoc<=0)

                nModeWalk = 0;

 

        if(nModeWalk==0){

                xLoc+=10;

                WalkRight();

        }

        else {

                xLoc-=10;

                WalkLeft();

        }

        CDialog::OnTimer(nIDEvent);

}

 

void CBmpDlg::WalkLeft(void)

{

        DrawBitmap();

}

 

 

중요함수