网页功能: 加入收藏 设为首页 网站搜索  
用窗口模式运行游戏
发表日期:2006-08-20作者:[转贴] 出处:  

看到有些朋友关心窗口模式的实现,特根据个人实践整理代码出来.
窗口模式前表面的操作范围是整个桌面区域,GetWindowRect(hwnd,&rect);取得实际窗口范围,实际窗口范围包括了我们需要的绘制区和窗口控件,要取得窗口控件的大小,并修正rect.
裁剪只对Blt有效,对GDI装置无效,对表面锁定操作无效,因此所有绘图工作和表面锁定操作应该在后表面进行.

※预定义文档:
取出系统信息,实际客户区是窗口大小扣去窗体控件占用区
#define SafeRelease(lpx) if(lpx!=NULL){lpx->Release();lpx=NULL;} //释放Macro
#define DD_Call(callcode) if(FAILED(callcode))return DD_FALSE //DX调用Macro

#define GSM_CAPTION GetSystemMetrics(SM_CYCAPTION) //标题栏
#define GSM_CXBORDER GetSystemMetrics(SM_CXFIXEDFRAME) //不可调边框
#define GSM_CYBORDER GetSystemMetrics(SM_CYFIXEDFRAME)
#define GSM_CYMENU GetSystemMetrics(SM_CYMENU) //如果有菜单
#define MAXWIDTH 640 //游戏显示区大小
#define MAXHEIGHT 480

※WinMain:
不包含最大化和可调边框
hwnd=CreateWindow(
__T(appname),
__T(wndname),
WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_OVERLAPPED, //注意这里
CW_USEDEFAULT,
CW_USEDEFAULT,
MAXWIDTH+(GSM_CXBORDER<<1), //注意这里
MAXHEIGHT+GSM_CAPTION+(GSM_CYBORDER<<1), //注意这里
GetDesktopWindow(),
NULL,
hinst,
NULL
);

※初始化:
主表面lpddsurmain/ddsdmain,次表面lpddsurback/ddsdback
次表面大小符合游戏区大小
DD_Call(DirectDrawCreateEx(NULL,(void**)&lpdd,IID_IDirectDraw7,NULL));
DD_Call(lpdd->SetCooperativeLevel(hwnd,DDSCL_NORMAL)); //注意这里
DD_Call(MainSurface(hwnd,&lpdd,&lpddsurmain,&ddsdmain));
DD_Call(BackSurface(MAXWIDTH,MAXHEIGHT,&lpdd,&lpddsurback,&ddsdback)); //注意这里

※主表面函数:
HRESULT MainSurface(HWND hwnd,LPDIRECTDRAW7* lplpdd,LPDIRECTDRAWSURFACE7* lplpddsur,DDSURFACEDESC2* lpddsd)
{
memset(lpddsd,0,sizeof(DDSURFACEDESC2));
lpddsd->dwSize=sizeof(DDSURFACEDESC2);
lpddsd->dwFlags=DDSD_CAPS;
lpddsd->ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE;
DD_Call((*lplpdd)->CreateSurface(lpddsd,&(*lplpddsur),NULL));
LPDIRECTDRAWCLIPPER lpclip;
DD_Call((*lplpdd)->CreateClipper(NULL,&lpclip,NULL));
DD_Call((*lplpddsur)->SetClipper(lpclip));
DD_Call(lpclip->SetHWnd(NULL,hwnd)); //注意这里
SafeRelease(lpclip);
return DD_OK;
}
※次表面函数:
HRESULT BackSurface(UINT nWidth,UINT nHeight,LPDIRECTDRAW7* lplpdd,LPDIRECTDRAWSURFACE7* lplpddsur,DDSURFACEDESC2* lpddsd)
{
memset(lpddsd,0,sizeof(DDSURFACEDESC2));
lpddsd->dwSize=sizeof(DDSURFACEDESC2);
lpddsd->dwFlags=DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT;
lpddsd->ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM;
lpddsd->dwWidth=nWidth;
lpddsd->dwHeight=nHeight;
DD_Call((*lplpdd)->CreateSurface(lpddsd,lplpddsur,NULL));
return DD_OK;
}

※游戏循环体:

RECT rect; //这个是主表面的区域
GetWindowRect(hwnd,&rect); //取得整个窗口区域
rect.left+=GSM_CXBORDER; //修正到主表面区域
rect.top+=GSM_CAPTION+GSM_CYBORDER;
rect.right-=GSM_CXBORDER;
rect.bottom-=GSM_CYBORDER;
RECT rectback={0,0,ddsdback.dwWidth,ddsdback.dwHeight}; //这个是次表面的区域

........ //实际在次表面绘图操作

HDC hdc;
DD_Call(lpddsurback->GetDC(&hdc));
TCHAR strbuf[55];
_stprintf(strbuf,"%s",__T("Just A Test!"));
TextOut(hdc,0,0,strbuf,(int)_tcslen(__T("Just A Test!")));
DD_Call(lpddsurback->ReleaseDC(hdc));

DD_Call(lpddsurmain->Blt(&rect,lpddsurback,&rectback,DDBLT_WAIT,NULL));
一切操作在次表面进行,完成后全部Blt到主表面.

我来说两句】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 用窗口模式运行游戏
本类热点文章
  在DirectX 8 中进行2D渲染
  DirectDraw打造极速图形引擎(一)
  用窗口模式运行游戏
  DirectDraw编程基础
  Windows的位图alpha混合技术
  再谈GDI模式作图
  终极优化你的游戏——使用脏矩形技术
  D3D8里面的2D图形编程
  全屏模式
  对2D游戏引擎设计的一些思考
  DirectX8中的二维图形高级技巧
  使用标准GDI实现游戏品质的动画系统
最新分类信息我要发布 
最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放  
Copyright ©2003-2024 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00407