📄 directwnd.cpp
字号:
// DirectWnd.cpp: implementation of the CDirectWnd class.
//
//////////////////////////////////////////////////////////////////////
#include "DirectWnd.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CDirectWnd::CDirectWnd(HINSTANCE hInstance,
int nCmdShow):CWindow(hInstance,nCmdShow)
{
lpDD=NULL;
lpFrontBuffer=NULL;
lpBackBuffer=NULL;
for (int i = 0; i < BkgNum; i++)
{
lpBKGObject[i]=NULL;
}
nBufferCount=1;
}
CDirectWnd::~CDirectWnd()
{
if(lpDD)
{
CleanSurface();
lpDD->Release();
lpDD=NULL;
}
}
void CDirectWnd::CleanSurface()
{
SAFE_RELEASE(lpBackBuffer)
SAFE_RELEASE(lpFrontBuffer)
for (int i = 0; i < BkgNum; i++)
{
SAFE_RELEASE(lpBKGObject[i])
}
return;
}
void CDirectWnd::LoadBitmapResource()
{
lpBKGObject[0] = DDLoadBitmap(lpDD,"pic//loading.bmp",640,480);
lpBKGObject[1] = DDLoadBitmap(lpDD,"pic//bkgnd.bmp",200,200);
lpBKGObject[2] = DDLoadBitmap(lpDD,"pic//bkgnd1.bmp",200,200);
// 创建我机页面
lpBKGObject[3] = DDLoadBitmap(lpDD,"pic//center.bmp",50,60);
lpBKGObject[4] = DDLoadBitmap(lpDD,"pic//left.bmp",50,60);
lpBKGObject[5] = DDLoadBitmap(lpDD,"pic//right.bmp",50,60);
DDSetColorKey(lpBKGObject[3],RGB(0,0,0));
DDSetColorKey(lpBKGObject[4],RGB(0,0,0));
DDSetColorKey(lpBKGObject[5],RGB(0,0,0));
// 创建子弹页面
lpBKGObject[6] = DDLoadBitmap(lpDD,"pic//bullet.bmp",16*5,20);
DDSetColorKey(lpBKGObject[6],RGB(0,0,0));
//创建敌机页面
lpBKGObject[7] = DDLoadBitmap(lpDD,"pic//enemy.bmp",230,130);
DDSetColorKey(lpBKGObject[7],RGB(0,0,0));
//创建爆炸页面
lpBKGObject[8] = DDLoadBitmap(lpDD,"pic//explode.bmp",780,170);
DDSetColorKey(lpBKGObject[8],RGB(0,0,0));
//创建奖励物品页面
lpBKGObject[9] = DDLoadBitmap(lpDD,"pic//bonus.bmp",80,120);
DDSetColorKey(lpBKGObject[9],RGB(0,0,0));
//创建游戏结束页面
lpBKGObject[10] = DDLoadBitmap(lpDD,"pic//gameover.bmp",640,480);
//创建炸弹页面
lpBKGObject[11] = DDLoadBitmap(lpDD,"pic//enemy1.bmp",35,35);
DDSetColorKey(lpBKGObject[11],RGB(4,4,4));
}
BOOL CDirectWnd::InitializeWnd(UINT Width,UINT Height,UINT Bpp)
{
DDSURFACEDESC ddsd ; //表面描述
DDSCAPS ddscaps ;
::ZeroMemory(&ddsd,sizeof(ddsd));//清零(起始,长度)
//创建DirectDraw对象
DirectDrawCreate(NULL,&lpDD,NULL);
//取得独占和全屏模式
lpDD->SetCooperativeLevel(GetHwnd(),DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN);
//设置显示模式
lpDD->SetDisplayMode(Width,Height,Bpp);
//也可以加 HRESULT ddrval; 它是下面三个函数的返回值.
DDCAPS ddcaps;
ddcaps.dwSize=sizeof(ddcaps);
lpDD->GetCaps(&ddcaps,NULL);
//填充主表面信息
ddsd.dwSize=sizeof(ddsd);
ddsd.dwFlags=DDSD_CAPS|DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps=DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP|DDSCAPS_COMPLEX;
ddsd.dwBackBufferCount=nBufferCount;
//创建主表面对象
lpDD->CreateSurface(&ddsd,&lpFrontBuffer,NULL);
//提取后台缓存表面指针
ddscaps.dwCaps=DDSCAPS_BACKBUFFER;
lpFrontBuffer->GetAttachedSurface(&ddscaps,&lpBackBuffer);
LoadBitmapResource();
return TRUE;
}
HRESULT CDirectWnd::FlipScreen()
{
HRESULT hr;
if( NULL == lpFrontBuffer && NULL == lpBackBuffer )
return E_POINTER;
while( 1 )
{
hr = lpFrontBuffer->Flip( NULL, 0 );
if( hr == DDERR_SURFACELOST )
{
lpFrontBuffer->Restore();
lpBackBuffer->Restore();
}
if( hr != DDERR_WASSTILLDRAWING )
return hr;
}
}
HRESULT CDirectWnd::Clear(DWORD dwColor)
{
if( NULL == lpBackBuffer )
return E_POINTER;
DDBLTFX ddbltfx;
ZeroMemory( &ddbltfx, sizeof(ddbltfx) );
ddbltfx.dwSize = sizeof(ddbltfx);
ddbltfx.dwFillColor = dwColor;
return lpBackBuffer->Blt( NULL, NULL, NULL, DDBLT_COLORFILL, &ddbltfx );
}
void CDirectWnd::BltBitMap( LPDIRECTDRAWSURFACE surSrc,
LPDIRECTDRAWSURFACE surDest,
RECT *rtSrc,
RECT *rtDest)
{
surDest->Blt( rtDest,//dest rect
surSrc,//src surface
rtSrc,//src rect
DDBLT_WAIT,
NULL);
}
void CDirectWnd::BltBitMap( LPDIRECTDRAWSURFACE surSrc,
RECT *rtSrc,
RECT *rtDest)
{
lpBackBuffer->Blt( rtDest,//dest rect
surSrc,//src surface
rtSrc,//src rect
DDBLT_WAIT,
NULL);
}
void CDirectWnd::BltObject( LPDIRECTDRAWSURFACE surSrc,
LPDIRECTDRAWSURFACE surDest,
RECT *rtSrc,
RECT *rtDest)
{
surDest->Blt( rtDest,//dest rect
surSrc,//src surface
rtSrc,//src rect
DDBLT_WAIT|DDBLT_KEYSRC,
NULL);
}
void CDirectWnd::BltObject( LPDIRECTDRAWSURFACE surSrc,
RECT *rtSrc,
RECT *rtDest)
{
lpBackBuffer->Blt( rtDest,//dest rect
surSrc,//src surface
rtSrc,//src rect
DDBLT_WAIT|DDBLT_KEYSRC,
NULL);
}
LPDIRECTDRAWSURFACE CDirectWnd::CreateSurface(DWORD width,DWORD height)
{
IDirectDrawSurface *pdds;
DDSURFACEDESC ddsd;
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);
ddsd.dwFlags=DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = width;
ddsd.dwHeight = height;
lpDD->CreateSurface( &ddsd, &pdds, NULL );
return pdds;
}
void CDirectWnd::GetRect(RECT* rect, long left, long top, long width, long height)
{
rect->left=left;
rect->top=top;
rect->right=left+width;
rect->bottom=top+height;
return;
}
void CDirectWnd::ShowText( int x, int y, char *text , COLORREF color )
{
HDC hdc;
lpBackBuffer->GetDC(&hdc);
SetBkMode(hdc,TRANSPARENT);
SetTextColor(hdc,color);
TextOut(hdc,x,y,text,strlen(text));
lpBackBuffer->ReleaseDC(hdc);
}
void CDirectWnd::ShowText( int x, int y, int num , COLORREF color )
{
HDC hdc;
char temp[200];
sprintf(temp,"%d",num);
lpBackBuffer->GetDC(&hdc);
SetBkMode(hdc,TRANSPARENT);
SetTextColor(hdc,color);
TextOut(hdc,x,y,temp,strlen(temp));
lpBackBuffer->ReleaseDC(hdc);
}
IDirectDrawSurface * CDirectWnd::DDLoadBitmap(IDirectDraw *pdd, LPCSTR szBitmap, int dx, int dy)
{
HBITMAP hbm;
BITMAP bm;
DDSURFACEDESC ddsd;
IDirectDrawSurface *pdds;
//
// try to load the bitmap as a resource, if that fails, try it as a file
//
hbm = (HBITMAP)LoadImage(GetModuleHandle(NULL), szBitmap, IMAGE_BITMAP, dx, dy, LR_CREATEDIBSECTION);
if (hbm == NULL)
hbm = (HBITMAP)LoadImage(NULL, szBitmap, IMAGE_BITMAP, dx, dy, LR_LOADFROMFILE|LR_CREATEDIBSECTION);
if (hbm == NULL)
return NULL;
//
// get size of the bitmap
//
GetObject(hbm, sizeof(bm), &bm); // get size of bitmap
//
// create a DirectDrawSurface for this bitmap
//
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = bm.bmWidth;
ddsd.dwHeight = bm.bmHeight;
if (pdd->CreateSurface(&ddsd, &pdds, NULL) != DD_OK)
return NULL;
DDCopyBitmap(pdds, hbm, 0, 0, 0, 0);
DeleteObject(hbm);
return pdds;
}
HRESULT CDirectWnd::DDSetColorKey(IDirectDrawSurface *pdds, COLORREF rgb)
{
DDCOLORKEY ddck;
ddck.dwColorSpaceLowValue = DDColorMatch(pdds, rgb);
ddck.dwColorSpaceHighValue = ddck.dwColorSpaceLowValue;
return pdds->SetColorKey(DDCKEY_SRCBLT, &ddck);
}
HRESULT CDirectWnd::DDCopyBitmap(IDirectDrawSurface *pdds, HBITMAP hbm, int x, int y, int dx, int dy)
{
HDC hdcImage;
HDC hdc;
BITMAP bm;
DDSURFACEDESC ddsd;
HRESULT hr;
if (hbm == NULL || pdds == NULL)
return E_FAIL;
//
// make sure this surface is restored.
//
pdds->Restore();
//
// select bitmap into a memoryDC so we can use it.
//
hdcImage = CreateCompatibleDC(NULL);
if (!hdcImage)
OutputDebugString("createcompatible dc failed\n");
SelectObject(hdcImage, hbm);
//
// get size of the bitmap
//
GetObject(hbm, sizeof(bm), &bm); // get size of bitmap
dx = dx == 0 ? bm.bmWidth : dx; // use the passed size, unless zero
dy = dy == 0 ? bm.bmHeight : dy;
//
// get size of surface.
//
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
pdds->GetSurfaceDesc(&ddsd);
if ((hr = pdds->GetDC(&hdc)) == DD_OK)
{
StretchBlt(hdc, 0, 0, ddsd.dwWidth, ddsd.dwHeight, hdcImage, x, y, dx, dy, SRCCOPY);
pdds->ReleaseDC(hdc);
}
DeleteDC(hdcImage);
return hr;
}
/*
* DDColorMatch
*
* convert a RGB color to a pysical color.
*
* we do this by leting GDI SetPixel() do the color matching
* then we lock the memory and see what it got mapped to.
*/
//获得指定颜色所对应的调色板索引
DWORD CDirectWnd::DDColorMatch(IDirectDrawSurface *pdds, COLORREF rgb)
{
COLORREF rgbT;
HDC hdc;
DWORD dw = CLR_INVALID;
DDSURFACEDESC ddsd;
HRESULT hres;
//
// use GDI SetPixel to color match for us
//
if (rgb != CLR_INVALID && pdds->GetDC(&hdc) == DD_OK)
{
rgbT = GetPixel(hdc, 0, 0); // save current pixel value
SetPixel(hdc, 0, 0, rgb); // set our value
pdds->ReleaseDC(hdc);
}
//
// now lock the surface so we can read back the converted color
//
ddsd.dwSize = sizeof(ddsd);
while ((hres = pdds->Lock(NULL, &ddsd, 0, NULL)) == DDERR_WASSTILLDRAWING)
;
if (hres == DD_OK)
{
dw = *(DWORD *)ddsd.lpSurface; // get DWORD
dw &= (1 << ddsd.ddpfPixelFormat.dwRGBBitCount)-1; // mask it to bpp
pdds->Unlock(NULL);
}
//
// now put the color that was there back.
//
if (rgb != CLR_INVALID && pdds->GetDC(&hdc) == DD_OK)
{
SetPixel(hdc, 0, 0, rgbT);
pdds->ReleaseDC(hdc);
}
return dw;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -