此程序中包涵了一般画法和离屏绘制,相信很快就能看懂。程序中所用到的是369 * 300 名为end.bmp的位图
一般画法会闪烁,而离屏绘制不会,这就是离屏绘制的好处。
#include
#include
#include
#include
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);
}