本系列文章由@二货梦想家张程 所写,转载请注明出处。
本文章链接:http://blog.csdn.net/terence1212/article/details/44224963
作者:ZeeCoder 微博链接:http://weibo.com/zc463717263
我的邮箱:michealfloyd@126.com 欢迎大家发邮件来和我交流编程心得
you are what you read!与大家共勉!
———————————————————–分割线:ZeeCoder————————————————————-
在笔记一中讲到了透明特效的实现,在游戏中,往往需要实现透明动画,这是游戏设计中一定会用到的基本技巧,它通过图案的连续显示及透明效果来产生背景图上的动画效果。
1、准备工作
ps:博主今天现学ps,花了大力气才做成这套图,真是感叹之前没有学好ps,书到用时方恨少啊~
在上图中,每幅小图的尺寸是121*129。
笔记一(【Visual C++】游戏编程学习笔记之一:五毛钱特效之透明和半透明处理)中介绍到,利用上述图还不能完成透明动画的制作,我们需要的是下面这张图(大小:968 * 129):
同样,做好了人物跑动的效果图之后,接下来就是编程实现的思想了。
2、编程思想
实现透明动画需要以下两个步骤:
(1)人物跑动图案的透明化
(2)更新贴图的坐标实现动画效果
3、程序代码(本笔记代码在Visual C++下编写)
(1)声明全局变量
//全局变量声明HBITMAP walker,bg;HDC hdc , mdc , bufdc;HWND hWnd;DWORD tPre , tNow ;int num ,x ,y;//函数声明ATOMMyRegisterClass(HINSTANCE hInstance);BOOLInitInstance(HINSTANCE, int);LRESULT CALLBACKWndProc(HWND, UINT, WPARAM, LPARAM);LRESULT CALLBACKAbout(HWND, UINT, WPARAM, LPARAM);void MyPaint(HDC hdc);
(2)主函数
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){ // TODO: Place code here.MSG msg;HACCEL hAccelTable;// Initialize global stringsLoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);LoadString(hInstance, IDC_MYANIMATION, szWindowClass, MAX_LOADSTRING);MyRegisterClass(hInstance);// Perform application initialization:if (!InitInstance (hInstance, nCmdShow)){return FALSE;}hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_MYANIMATION);// Main message loop: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;}
(3)窗口类函数
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= LoadIcon(hInstance, (LPCTSTR)IDI_MYANIMATION);wcex.hCursor= LoadCursor(NULL, IDC_ARROW);wcex.hbrBackground= (HBRUSH)(COLOR_WINDOW+1);wcex.lpszMenuName= (LPCSTR)IDC_MYANIMATION;wcex.lpszClassName= szWindowClass;wcex.hIconSm= LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);return RegisterClassEx(&wcex);}
(4)初始化函数
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){char filename[20] = "";HBITMAPbmp;hInst = hInstance;hWnd = CreateWindow("MyAnimation", "动画显示", WS_OVERLAPPEDWINDOW,CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);if (!hWnd){return FALSE;}MoveWindow(hWnd , 10 , 10 , 968 ,605 , true);ShowWindow(hWnd , nCmdShow);UpdateWindow(hWnd);hdc = GetDC(hWnd); //获得窗口句柄mdc = CreateCompatibleDC(hdc);bufdc = CreateCompatibleDC(hdc);bmp = CreateCompatibleBitmap(hdc , 968 , 605);SelectObject(mdc , bmp);walker = (HBITMAP)LoadImage(NULL , "1.bmp" , IMAGE_BITMAP , 968 , 258 ,LR_LOADFROMFILE);bg = (HBITMAP)LoadImage(NULL , "res.bmp" , IMAGE_BITMAP , 968 ,605 , LR_LOADFROMFILE);num = 0 ;x = 968 ;y = 300 ;MyPaint(hdc);return TRUE;}
(5)自定义绘图函数
void MyPaint (HDC hdc){if (num == 8){num = 0 ;}//在mdc上贴背景图SelectObject(bufdc , bg);BitBlt(mdc , 0 , 0 , 968 , 605 , bufdc , 0 , 0 ,SRCCOPY);//在mdc上进行透明处理SelectObject(bufdc , walker);BitBlt(mdc , x , y ,121 , 129 ,bufdc , num*121 , 129 , SRCAND);BitBlt(mdc ,x, y , 121, 129 , bufdc , num*121 , 0 , SRCPAINT);//将最后的画面显示在窗口上BitBlt(hdc , 0 ,0 ,968 ,605 ,mdc , 0 , 0 ,SRCCOPY);tPre = GetTickCount();num++;x += 20 ;if (x >= 968){x=0;}}
(6)运行效果
笔记四就写到这里,欢迎大家发邮件和我交流编程经验,同样也希望能够多认识一些志同道合的朋友。
—end
本笔记代码已上传,欢迎下载::【Visual C++】游戏编程学习笔记四配套代码