此程序中包涵了一般画法和离屏绘制,相信很快就能看懂。程序中所用到的是369 * 300 名为end.bmp的位图
一般画法会闪烁,而离屏绘制不会,这就是离屏绘制的好处。
#include <iostream> #include <string.h> #include <windows.h> #include <stdlib.h> using namespace std; #define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0) HWND main_window_handle = NULL; HDC windowDC = NULL; //windows屏幕设备 HDC endDC = NULL; //游戏终结图像内存设备 HBITMAP endBMP = NULL; //游戏终结图像内存句柄 HDC bufferDC = NULL; //缓冲设备环境 HBITMAP bufferBMP = NULL; //缓冲位图句柄 RECT g_ClientRect; void game_main(); //消息回调函数 LRESULT CALLBACK textprom(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { // this is the main message handler of the system PAINTSTRUCT ps; HDC hdc; int result; switch (msg) { case WM_CREATE: return 0; case WM_CLOSE: result = MessageBox(hwnd,"你确定离开游戏么?","离开游戏",MB_YESNO|MB_ICONQUESTION); if(result == IDYES) return (DefWindowProc(hwnd,msg,wparam,lparam)); //释放资源 ReleaseDC(main_window_handle, endDC); ReleaseDC(main_window_handle, bufferDC); ReleaseDC(main_window_handle, windowDC); return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); EndPaint(hwnd, &ps); return 0; case WM_DESTROY: //释放资源 ReleaseDC(main_window_handle, endDC); ReleaseDC(main_window_handle, bufferDC); ReleaseDC(main_window_handle, windowDC); PostQuitMessage(0); return 0; default: break; } return DefWindowProc(hwnd, msg, wparam, lparam); } /* 绘制矩形 **************************************************************************/ int Draw_Rectangle(int x1, int y1, int x2, int y2, int color) { // this function uses Win32 API to draw a filled rectangle HBRUSH hbrush; HDC hdc; RECT rect; SetRect(&rect, x1, y1, x2, y2); hbrush = CreateSolidBrush(color); hdc = GetDC(main_window_handle); FillRect(hdc, &rect, hbrush); ReleaseDC(main_window_handle, hdc); DeleteObject(hbrush); return 1; } //写文本 int DrawText_GUI(TCHAR *text, int x, int y, int color) { HDC hdc; hdc = GetDC(main_window_handle); SetTextColor(hdc, color); SetBkMode(hdc, TRANSPARENT); TextOut(hdc, x, y, text, lstrlen(text)); ReleaseDC(main_window_handle, hdc); return 1; } int APIENTRY WinMain(HINSTANCE hCurrentInst, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){ WNDCLASS wndClass; HWND hWnd; MSG msg; //定义窗口 wndClass.style=CS_HREDRAW | CS_VREDRAW; wndClass.lpfnWndProc=textprom; wndClass.cbClsExtra=0; wndClass.cbWndExtra=0; wndClass.hInstance=hCurrentInst; wndClass.hIcon=LoadIcon(NULL,MAKEINTRESOURCE(101)); wndClass.hCursor=LoadCursor(NULL,IDC_ARROW); wndClass.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH); wndClass.lpszMenuName=NULL; wndClass.lpszClassName="Snake_CLASS"; //注册窗口 RegisterClass(&wndClass); //创建窗口 hWnd=CreateWindow( "Snake_CLASS", "skyblue snake", WS_DLGFRAME | WS_MINIMIZEBOX | WS_SYSMENU, 100,100, 600,600, NULL,NULL, hCurrentInst, NULL); main_window_handle = hWnd; //显示窗口 ShowWindow(hWnd,nCmdShow); UpdateWindow(hWnd); //获取当前主窗口设备与windowDC关联 windowDC=GetDC(NULL); //创建与windowDC兼容的内存设备环境 bufferDC=CreateCompatibleDC(windowDC); endDC=CreateCompatibleDC(windowDC); //位图的初始化和载入位图 bufferBMP=CreateCompatibleBitmap(windowDC,600,600); endBMP = (HBITMAP)LoadImage(NULL,"end.bmp",IMAGE_BITMAP ,369,300,LR_LOADFROMFILE); //声明位图与设备环境的关联 SelectObject(bufferDC,bufferBMP); SelectObject(endDC,endBMP); while(GetMessage(&msg,NULL,0,0)) { game_main(); TranslateMessage(&msg); DispatchMessage(&msg); } return 0; } void game_main(){ if (KEY_DOWN(VK_ESCAPE)) //按ESC键时 PostMessage(main_window_handle, WM_DESTROY, 0, 0); //这个是为了离屏绘制,获得窗口距屏幕左顶角的坐标 GetWindowRect(main_window_handle, &g_ClientRect); /*关于bitblt: 第2、3个参数是所要绘制的图像左上角距画布左上角的横纵坐标 第3、4个是所要绘制的图像的大小 第7、8是从图片的什么位置开始画 */ //绘制外壳区域到缓冲 BitBlt(bufferDC, 30, 40, 369, 300, endDC, 0, 0, SRCCOPY); SetBkMode(bufferDC, TRANSPARENT); SetTextColor(bufferDC, RGB(250, 250, 250)); char szText[30] = "ESC键退出"; TextOut(bufferDC, 160, 12, szText,strlen(szText)); //将整个画面从缓冲DC拷贝出屏幕 BitBlt(windowDC, g_ClientRect.left + 20, g_ClientRect.top + 26, 580, 570, bufferDC,0,0,SRCCOPY); Draw_Rectangle(30, 0, 130, 30, RGB(204, 204, 204)); DrawText_GUI("黄雀在行动", 35, 7, RGB(0, 0, 0)); }
另外一些图形绘制,给出简要代码
//绘制椭圆
void Draw_Ellipse(HDC &hdc, int type, int x, int y){
int color = RGB(0, 255, 0);
HBRUSH brush = CreateSolidBrush(color);
SelectObject(bufferDC, brush);
Ellipse(bufferDC, x, y, x + 50, y + 50);
DeleteObject(brush);
}
绘制多边形
void Draw_Polygon(HDC &hdc){
int color = RGB(255, 0, 0);
HBRUSH brush = CreateSolidBrush(color);
POINT point_list[4];
point_list[0].x = 40;
point_list[0].y = 40;
point_list[1].x = 60;
point_list[1].y = 60;
point_list[2].x = 40;
point_list[2].y = 80;
point_list[3].x = 20;
point_list[3].y = 60;
SelectObject(hdc, brush);Polygon(hdc, point_list, 4);//4表示4边形
DeleteObject(brush);
}