【Visual C++】遊戲開發筆記之十 基礎動畫顯示(三) 透明動畫的實現

來源:互聯網
上載者:User

本系列文章由zhmxy555編寫,轉載請註明出處。 http://blog.csdn.net/zhmxy555/article/details/7376281

作者:毛星雲    郵箱: happylifemxy@qq.com    歡迎郵件交流編程心得

"透明動畫”是遊戲中一定會用到的基本技巧,它通過圖案的連續顯示及圖案本身背景的透明化處理,在背景圖上產生出栩栩如生的動畫效果。


看過之前筆記的朋友們應該知道,在筆記六裡我們介紹了使位元影像背景透明的方法,在筆記八裡我們講解了使用遊戲迴圈顯示動畫的技巧,而這節筆記的內容,剛好是兩者的一個綜合。


如果有沒看過之前筆記系列的朋友,為了便於理解本節的內容,可以先瀏覽一下之前的筆記六和筆記八,下面我給出連結。


【Visual C++】遊戲開發筆記之六——遊戲畫面繪圖(三)透明特效的製作方法


【Visual C++】遊戲開發筆記之八——基礎動畫顯示(二)遊戲迴圈的使用 



為了實現透明動畫的效果,我們採用了一個如所示的恐龍跑動的連續圖,每一張跑動圖的寬高都為95*99。我們知道,透明動畫製作的前提是,必須在一個暫存的記憶體DC上完成每一張跑動圖的透明,然後再貼到視窗上,這樣畫面更新時才不會出現在透明貼圖過程中產生的閃爍現象。





中每一個小恐龍的尺寸為95*99,這個資料在寫代碼過程中比較關鍵。



實現這個程式的關鍵點,當然是MyPaint函數的寫法。

而在MyPaint函數裡面我們主要實現了兩個功能:

1.恐龍跑動圖案的透明背景化

2.更新貼圖的座標,實現動畫效果


下面我們給出MyPaint函數的寫法:

        num = 0;    //顯示圖號x = 640;//貼圖起始X座標y = 360;    //貼圖起始Y座標void MyPaint(HDC hdc){if(num == 8)num = 0;//在mdc中貼上背景圖SelectObject(bufdc,bg);BitBlt(mdc,0,0,640,480,bufdc,0,0,SRCCOPY);//在mdc中進行透明處理SelectObject(bufdc,dra);BitBlt(mdc,x,y,95,99,bufdc,num*95,99,SRCAND);BitBlt(mdc,x,y,95,99,bufdc,num*95,0,SRCPAINT);//將最後的畫面顯示在視窗中BitBlt(hdc,0,0,640,480,mdc,0,0,SRCCOPY);tPre = GetTickCount();     //記錄此次繪圖時間num++;x-=20;   //計算下次貼圖的座標if(x<=-95)x = 640;}

關鍵點的說明:

▲7~17行,  在mdc上進行透明操作並將最後的結果顯示在視窗中。

▲13~14行,進行透明時,按照目前的圖號來取出對應的跑動圖案或者屏蔽圖。

▲22~24行,計算下次恐龍圖貼圖座標,由於我們的程式設定動畫是由右向左跑動的,在Y軸座標不變化,而X軸座標每次向左遞減20,直到圖案跑到左邊視窗外時再將座標設回最右邊,這樣可以看到恐龍不斷由右向左迴圈跑動的效果。




同樣我們利用一個完整的執行個體來瞭解實現透明動畫的具體過程:

#include "stdafx.h"//全域變數聲明HINSTANCE hInst;HBITMAP dra,bg;HDChdc,mdc,bufdc;HWNDhWnd;DWORDtPre,tNow;intnum,x,y;//全域函式宣告ATOMMyRegisterClass(HINSTANCE hInstance);BOOLInitInstance(HINSTANCE, int);LRESULT CALLBACKWndProc(HWND, UINT, WPARAM, LPARAM);voidMyPaint(HDC hdc);//***WinMain函數,程式進入點函數**************************************   int APIENTRY WinMain(HINSTANCE hInstance,                     HINSTANCE hPrevInstance,                     LPSTR     lpCmdLine,                     int       nCmdShow){MSG msg;MyRegisterClass(hInstance);//初始化if (!InitInstance (hInstance, nCmdShow)) {return FALSE;}//訊息迴圈GetMessage(&msg,NULL,NULL,NULL);  //初始化msg    while( msg.message!=WM_QUIT )    {        if( PeekMessage( &msg, NULL, 0,0 ,PM_REMOVE) )        {            TranslateMessage( &msg );            DispatchMessage( &msg );        }else{tNow = GetTickCount();if(tNow-tPre >= 100)MyPaint(hdc);}    }return msg.wParam;}//****設計一個視窗類別,類似填空題,使用視窗結構體*************************   ATOM MyRegisterClass(HINSTANCE hInstance){WNDCLASSEX wcex;wcex.cbSize = sizeof(WNDCLASSEX); wcex.style= CS_HREDRAW | CS_VREDRAW;wcex.lpfnWndProc= (WNDPROC)WndProc;wcex.cbClsExtra= 0;wcex.cbWndExtra= 0;wcex.hInstance= hInstance;wcex.hIcon= NULL;wcex.hCursor= NULL;wcex.hCursor= LoadCursor(NULL, IDC_ARROW);wcex.hbrBackground= (HBRUSH)(COLOR_WINDOW+1);wcex.lpszMenuName= NULL;wcex.lpszClassName= "canvas";wcex.hIconSm= NULL;return RegisterClassEx(&wcex);}//****初始化函數*************************************// 載入位元影像並設定各對象的初始值BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){char filename[20] = "";HBITMAP bmp;hInst = hInstance;hWnd = CreateWindow("canvas", "動畫示範" , WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);if (!hWnd){return FALSE;}MoveWindow(hWnd,10,10,640,480,true);ShowWindow(hWnd, nCmdShow);UpdateWindow(hWnd);hdc = GetDC(hWnd);mdc = CreateCompatibleDC(hdc);bufdc = CreateCompatibleDC(hdc);bmp = CreateCompatibleBitmap(hdc,640,480);SelectObject(mdc,bmp);dra = (HBITMAP)LoadImage(NULL,"dra.bmp",IMAGE_BITMAP,760,198,LR_LOADFROMFILE);bg = (HBITMAP)LoadImage(NULL,"bg.bmp",IMAGE_BITMAP,640,480,LR_LOADFROMFILE);num = 0;    //顯示圖號x = 640;//貼圖起始X座標y = 360;    //貼圖起始Y座標MyPaint(hdc);return TRUE;}//****自訂繪圖函數*********************************// 1.恐龍跑動圖案的透明背景化// 2.更新貼圖座標,實現動畫效果void MyPaint(HDC hdc){if(num == 8)num = 0;//在mdc中貼上背景圖SelectObject(bufdc,bg);BitBlt(mdc,0,0,640,480,bufdc,0,0,SRCCOPY);//在mdc中進行透明處理SelectObject(bufdc,dra);BitBlt(mdc,x,y,95,99,bufdc,num*95,99,SRCAND);BitBlt(mdc,x,y,95,99,bufdc,num*95,0,SRCPAINT);//將最後的畫面顯示在視窗中BitBlt(hdc,0,0,640,480,mdc,0,0,SRCCOPY);tPre = GetTickCount();     //記錄此次繪圖時間num++;x-=20;   //計算下次貼圖的座標if(x<=-95)x = 640;}//****訊息處理函數***********************************LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){switch (message){case WM_DESTROY://視窗結束訊息,撤銷各種DCDeleteDC(mdc);DeleteDC(bufdc);DeleteObject(dra);DeleteObject(bg);ReleaseDC(hWnd,hdc);PostQuitMessage(0);break;default://其他訊息return DefWindowProc(hWnd, message, wParam, lParam);   }   return 0;}

這個程式的運行結果為:





筆記十到這裡就結束了。


本節原始碼請點擊這裡下載:  【Visual C++】Code_Note_10


感謝一直支援【Visual C++】遊戲開發筆記系列專欄的朋友們,也請大家繼續關注我的部落格,我一有空就會把自己的學習心得,覺得比較好的知識點寫出來和大家一起分享。

精通遊戲開發的路還很長很長,非常希望能和大家一起交流,共同學習和進步。

大家看過後覺得有啟發的話可以頂一下這篇文章,讓更多的朋友有機會看到它。也希望大家可以多留言來和我探討編程相關的問題。

最後,謝謝大家一直的支援~~~


The end



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.