小游戏一:win32贴图——TransparentBlt

win32编程 三缓冲  实现透明贴图

一、收获

  1. 三缓冲贴图: 

 

        //以贴背景图为例
        //1.获取DC
        g_hdc = GetDC(hwnd);

        //2.创建兼容DC
        g_mdc = CreateCompatibleDC(g_hdc);
        g_bufdc = CreateCompatibleDC(g_hdc);

        //创建一个和窗口兼容的位图对象
	HBITMAP hBitMap = CreateCompatibleBitmap(g_hdc, WINDOW_WIDTH, WINDOW_HEIGHT);
	SelectObject(g_mdc, hBitMap);

	//3.加载位图
·    g_hBackGround = (HBITMAP)LoadImage(NULL, _T("bg.bmp"), IMAGE_BITMAP, WINDOW_WIDTH, WINDOW_HEIGHT, LR_LOADFROMFILE);

	//贴背景图
	SelectObject(g_bufdc, g_hBackGround);
	BitBlt(g_mdc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, g_bufdc, 0, 0, SRCCOPY);

	//把图片复制到HDC
	BitBlt(g_hdc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, g_mdc, 0, 0, SRCCOPY);                    

  

  2.人物图像贴图方式:

 

        //1.获取DC
	g_hdc = GetDC(hwnd);

	//2.创建兼容DC
	g_mdc = CreateCompatibleDC(g_hdc);
	g_bufdc = CreateCompatibleDC(g_hdc);

	//创建一个和窗口兼容的位图对象
	HBITMAP hBitMap = CreateCompatibleBitmap(g_hdc, WINDOW_WIDTH, WINDOW_HEIGHT);
	SelectObject(g_mdc, hBitMap);

	//3.加载位图
	g_hSprite = (HBITMAP)LoadImage(NULL, _T("goright.bmp"), IMAGE_BITMAP, 480, 108, LR_LOADFROMFILE);
	g_hBackGround = (HBITMAP)LoadImage(NULL, _T("bg.bmp"), IMAGE_BITMAP, WINDOW_WIDTH, WINDOW_HEIGHT, LR_LOADFROMFILE);


	//贴人物
	SelectObject(g_bufdc, g_hSprite);
	TransparentBlt(g_mdc, g_iX, g_iY, 60, 108, g_bufdc, g_iNum * 60, 0, 60, 108, RGB(255, 0, 0));

	//把图片复制到HDC
	BitBlt(g_hdc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, g_mdc, 0, 0, SRCCOPY);
        

  

  3.语法:

 

//1.背景
wnd.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);


//2.EX版本的使用,
//        1 size sizeof(WNDCLASSEX)  2 RegisterClassEx(&wnd)
if (!RegisterClassEx(&wnd))
	{
		return -1;
	}


//3.消息循环
while (msg.message != WM_QUIT)
	{
		if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))  //REMOVE
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			
		}
	}
	
//4.注销窗口
	Game_CleanUp(hwnd);
	UnregisterClass(wnd.lpszClassName, hInstance);    


//5.获取系统时间
			g_tNow = GetTickCount();

			if (g_tNow - g_tPre > 50)
				Game_Paint(hwnd);


//6.没有{}
case WM_CREATE:
		PlaySound(_T("仙剑三·原版景天.wav"), NULL, SND_ASYNC | SND_LOOP | SND_FILENAME);
		Game_Init(hwnd);
		break;

//7.
        DeleteObject(g_hBackGround);
	DeleteObject(g_hSprite);
	DeleteObject(g_mdc);
	DeleteObject(g_bufdc);
	
	ReleaseDC(hwnd, g_hdc); //GetDC()只能被释放 如果删除不释放 就会一直占用着

 

  

 

     4.出现bug::

  原因及解决办法:  函数未被调用,函数名错误。

 

二、完整源代码

  1 #include<Windows.h>
  2 #include<tchar.h>
  3 
  4 #pragma comment(lib,"Msimg32.lib")        //加载静态库
  5 #pragma comment(lib,"winmm.lib")
  6 
  7 #define WINDOW_TITLE _T("透明动画")
  8 #define WINDOW_WIDTH    800
  9 #define WINDOW_HEIGHT    600
 10 
 11 //======================全局函数================================
 12 LRESULT CALLBACK WinProc(HWND, UINT, WPARAM, LPARAM);
 13 void Game_Init(HWND hwnd);    //初始化函数
 14 void Game_Paint(HWND hwnd);    
 15 void Game_CleanUp(HWND hwnd);//释放资源
 16 //==============================================================
 17 
 18 //==========================全局变量============================
 19 DWORD g_tPre, g_tNow;    //用来保存上一次贴图的时间,还有本次贴图的时间
 20 HDC g_hdc, g_mdc, g_bufdc;    //实现三缓冲位图
 21 HBITMAP g_hSprite, g_hBackGround;    //用来加载人物和背景图片
 22 int g_iNum;    //记录图片
 23 int g_iX, g_iY;    //坐标
 24 //==============================================================
 25 
 26 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
 27 {
 28     //1.设计窗口
 29     WNDCLASSEX wnd = { 0 };
 30     
 31     wnd.cbClsExtra = 0;
 32     wnd.cbSize = sizeof(WNDCLASSEX);    //结构体大小
 33     wnd.cbWndExtra = 0;
 34     wnd.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
 35     wnd.hCursor = NULL;
 36     wnd.hIcon = NULL;
 37     wnd.hInstance = hInstance;
 38     wnd.lpfnWndProc = WinProc;
 39     wnd.lpszClassName = _T("逐梦之旅");
 40     wnd.lpszMenuName = NULL;
 41     wnd.style = CS_HREDRAW | CS_VREDRAW;
 42 
 43     //2.注册窗口
 44     if (!RegisterClassEx(&wnd))
 45     {
 46         return -1;
 47     }
 48 
 49     //3.创建窗口
 50     HWND hwnd = CreateWindow(wnd.lpszClassName, WINDOW_TITLE, WS_OVERLAPPEDWINDOW, 100, 100, WINDOW_WIDTH, WINDOW_HEIGHT, NULL, NULL, hInstance, NULL);
 51 
 52     //4.显示和更新
 53     ShowWindow(hwnd, SW_SHOW);
 54     UpdateWindow(hwnd);
 55 
 56     //5.消息循环
 57     MSG msg = { 0 };
 58     while (msg.message != WM_QUIT)
 59     {
 60         if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
 61         {
 62             TranslateMessage(&msg);
 63             DispatchMessage(&msg);
 64         }
 65         else
 66         {
 67             //获取系统时间
 68             g_tNow = GetTickCount();
 69 
 70             if (g_tNow - g_tPre > 50)
 71                 Game_Paint(hwnd);
 72         }
 73     }
 74     
 75     //注销窗口
 76     Game_CleanUp(hwnd);
 77     UnregisterClass(wnd.lpszClassName, hInstance);
 78     return 0;
 79 }
 80 
 81 LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 82 {
 83     switch (message)
 84     {
 85     case WM_CREATE:
 86         PlaySound(_T("仙剑三·原版景天.wav"), NULL, SND_ASYNC | SND_LOOP | SND_FILENAME);
 87         Game_Init(hwnd);
 88         break;
 89 
 90     case WM_DESTROY:
 91         PostQuitMessage(0);
 92         break;
 93         
 94     case WM_KEYDOWN:
 95         if (wParam == VK_ESCAPE)
 96             PostQuitMessage(0);
 97         break;
 98     }
 99     return DefWindowProc(hwnd, message, wParam, lParam);
100 }
101 
102 //初始化
103 void Game_Init(HWND hwnd)
104 {
105     //1.获取DC
106     g_hdc = GetDC(hwnd);
107 
108     //2.创建兼容DC
109     g_mdc = CreateCompatibleDC(g_hdc);
110     g_bufdc = CreateCompatibleDC(g_hdc);
111 
112     //创建一个和窗口兼容的位图对象
113     HBITMAP hBitMap = CreateCompatibleBitmap(g_hdc, WINDOW_WIDTH, WINDOW_HEIGHT);
114     SelectObject(g_mdc, hBitMap);
115 
116     //3.加载位图
117     g_hSprite = (HBITMAP)LoadImage(NULL, _T("goright.bmp"), IMAGE_BITMAP, 480, 108, LR_LOADFROMFILE);
118     g_hBackGround = (HBITMAP)LoadImage(NULL, _T("bg.bmp"), IMAGE_BITMAP, WINDOW_WIDTH, WINDOW_HEIGHT, LR_LOADFROMFILE);
119 
120     //初始化人的坐标
121     g_iNum = 0;    //编号
122     g_iX = 0;
123     g_iY = 350;
124     Game_Paint(hwnd);
125 }
126 
127 void Game_Paint(HWND hwnd)
128 {
129     //判断图片的编号
130     if (g_iNum == 8)
131         g_iNum = 0;
132 
133     //贴背景图
134     SelectObject(g_bufdc, g_hBackGround);
135     BitBlt(g_mdc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, g_bufdc, 0, 0, SRCCOPY);
136 
137     //贴人物
138     SelectObject(g_bufdc, g_hSprite);
139     TransparentBlt(g_mdc, g_iX, g_iY, 60, 108, g_bufdc, g_iNum * 60, 0, 60, 108, RGB(255, 0, 0));
140 
141     //把图片复制到HDC
142     BitBlt(g_hdc, 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, g_mdc, 0, 0, SRCCOPY);
143 
144     //获取本次贴图时间
145     g_tPre = GetTickCount();
146 
147     g_iNum++;
148     g_iX += 10;
149     if (g_iX >= WINDOW_WIDTH)
150     {
151         g_iX = -60;
152     }
153 }
154 
155 void Game_CleanUp(HWND hwnd)
156 {
157     DeleteObject(g_hBackGround);
158     DeleteObject(g_hSprite);
159     DeleteObject(g_mdc);
160     DeleteObject(g_bufdc);
161     
162     ReleaseDC(hwnd, g_hdc); //GetDC()只能被释放 如果删除不释放 就会一直占用着
163 }

 

posted @ 2017-09-22 18:02  千面鬼手大人  阅读(646)  评论(0编辑  收藏  举报
// 侧边栏目录 // https://blog-static.cnblogs.com/files/douzujun/marvin.nav.my1502.css