|
|
请教:
关键代码如下:
WinMain.cpp
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
LPSTR lpCmdLine,int nCmdShow)
{
static TCHAR szAppName[]=TEXT("");
static TCHAR szClassName[]=TEXT("MainWinClass");
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
wndclass.style = CS_DBLCLKS | CS_OWNDC |
CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szClassName;
//设置句柄全局变量
main_instance = hInstance;
if(!RegisterClass(&wndclass))
{
MessageBox(NULL,TEXT("This program requires Windows NT !"),
szAppName,MB_ICONERROR);
return 0;
}
hwnd = CreateWindow(szClassName,
TEXT(""),
WS_POPUP | WS_VISIBLE,
0,
0,
320,
240,
NULL,
NULL,
hInstance,
NULL );
ShowWindow(hwnd,nCmdShow);
UpdateWindow(hwnd);
//设置主窗口全局变量
main_window_handle = hwnd;
//游戏初始化
GameInit();
//主循环
while(TRUE)
{
//检测消息
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
//是否退出程序
if (msg.message == WM_QUIT)
break;
//消息转换
TranslateMessage(&msg);
DispatchMessage(&msg);
}
//游戏循环
GameMain();
}
//游戏退出控制
GameShut();
return msg.wParam;
}
GameMain.cpp
#include "../H/GameMain.h"
#include "../H/MyDirectDraw.h"
#include "../H/MyDirectInput.h"
//#include "../H/MyDirectAudio.h"
//键盘定义
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
extern HWND main_window_handle; //外部定义的主窗口变量
extern HINSTANCE main_instance; //外部定义的主句柄
//extern char buffer[80]; //外部定义的临时数组
//////////////////////////////////
//游戏循环
//////////////////////////////////
int GameMain(void)
{
static int placex=400 , placey=300 ;
//获取键盘
lpDInputkey->GetDeviceState(256, (LPVOID)keyboard_state);
//获取鼠标
lpDInputMouse->GetDeviceState(sizeof(DIMOUSESTATE),
(LPVOID)&mouse_state);
//遇Esc键退出
if (keyboard_state[DIK_ESCAPE])
{
SendMessage(main_window_handle,WM_CLOSE,0,0);
}
//鼠标位置
placex += mouse_state.lX;
placey += mouse_state.lY;
//清屏
memset(&ddbltfx,0,sizeof(ddbltfx));
ddbltfx.dwSize=sizeof(ddbltfx);
ddbltfx.dwFillColor = _RGB16BIT565(0,0,0);
if (FAILED(lpDDback->Blt(NULL, NULL, NULL,
DDBLT_COLORFILL | DDBLT_WAIT,&ddbltfx)))
{
MessageBox(NULL,TEXT("Back surface fill color error!"),
TEXT("Wrong!"),MB_OK);
return(1);
}
//将备用画面背景部分拷贝到后备画面
SurfaceToBack(lpDDbpic,0,0,799,599,lpDDback,0,0,799,599);
//绘制鼠标
SurfaceToBack(lpDDbpic,360,665,390,697,lpDDback,
placex,placey,placex+30,placey+37);
//锁住后备画面
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);
if (FAILED(lpDDback->Lock(NULL,&ddsd,
DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
NULL)))
{
MessageBox(NULL,TEXT("primary surface lock error!"),
TEXT("Wrong!"),MB_OK);
return(1);
}
//解锁后备画面
if (FAILED(lpDDback->Unlock(NULL)))
{
MessageBox(NULL,TEXT("primary surface unlock error!"),
TEXT("Wrong!"),MB_OK);
return(1);
}
//翻页
while (FAILED(lpDDprimary->Flip(NULL, DDFLIP_WAIT)));
return 0;
}
//////////////////////////////////
//游戏初始化
//////////////////////////////////
int GameInit(void)
{
//DirectDraw初始化
MyDirectDrawInit();
//剪切序列
RECT rect_list[1] = {{0,0,799,599}};
//建立剪切区
if (FAILED(lpDDclip = CreatDDClipper(lpDDback,1,rect_list)))
{
MessageBox(NULL,TEXT("primary surface Blt error!"),
TEXT("Wrong!"),MB_OK);
return(0);
}
if(!(lpDDbpic = CreatePicSurface(" ic/BackGround1.bmp" , 0 , 0)))
{
MessageBox(NULL,TEXT("Create Pic Background Surface error!"),
TEXT("Wrong!"),MB_OK);
return(1);
}
//DirectInput初始化
MyDirectInputInit();
//隐藏鼠标
ShowCursor(FALSE);
GameStart();
return 0;
}
//////////////////////////////////
//游戏结束
//////////////////////////////////
int GameShut(void)
{
//DirectDraw结束
MyDirectDrawShut();
//DirectInput结束
MyDirectInputShut();
return 0;
}
//////////////////////////////////
//游戏开始
//////////////////////////////////
int GameStart(void)
{
//清屏
memset(&ddbltfx,0,sizeof(ddbltfx));
ddbltfx.dwSize=sizeof(ddbltfx);
ddbltfx.dwFillColor = _RGB16BIT565(0,0,0);
if (FAILED(lpDDback->Blt(NULL, NULL, NULL,
DDBLT_COLORFILL | DDBLT_WAIT,&ddbltfx)))
{
MessageBox(NULL,TEXT("Back surface fill color error!"),
TEXT("Wrong!"),MB_OK);
return(1);
}
//将备用画面背景部分拷贝到后备画面
SurfaceToBack(lpDDbpic,0,0,799,599,lpDDback,0,0,799,599);
// + 提示
SurfaceToBack(lpDDbpic,360,665,390,697,lpDDback,
380,220,410,252);
//翻页
while (FAILED(lpDDprimary->Flip(NULL, DDFLIP_WAIT)));
//是否开始
for(;;)
{
//获取键盘
lpDInputkey->GetDeviceState(256, (LPVOID)keyboard_state);
//遇Esc键退出
if (keyboard_state[DIK_ESCAPE])
{
SendMessage(main_window_handle,WM_CLOSE,0,0);
}
//获取鼠标
lpDInputMouse->GetDeviceState(sizeof(DIMOUSESTATE),
(LPVOID)&mouse_state);
//按键开始
if (mouse_state.rgbButtons[MOUSE_LEFT_BUTTON]&0x80)
break;
}
return 0;
}
MyDirectDraw.cpp
extern HWND main_window_handle; //外部定义的主窗口变量
extern HINSTANCE main_instance; //外部定义的主句柄
extern char buffer[80]; //外部定义的临时数组
//Directdraw 变量
LPDIRECTDRAW7 lpDDraw7 = NULL; //Directdraw对象
LPDIRECTDRAWSURFACE7 lpDDprimary = NULL; //Directdraw主画面
LPDIRECTDRAWSURFACE7 lpDDback = NULL; //Directdraw后备画面
LPDIRECTDRAWSURFACE7 lpDDbpic = NULL; //Directdraw备用画面
DDSURFACEDESC2 ddsd; //Directdraw表面描述界面
DDBLTFX ddbltfx; //Directdraw图形变换变量
LPDIRECTDRAWCLIPPER lpDDclip = NULL; //Directdraw剪切板
BMPPIC bitmap; //BMP图
/////////////////////////////////////////////
//DirectDraw初始化
/////////////////////////////////////////////
int MyDirectDrawInit(void)
{
LPDIRECTDRAW lpDDraw_temp; //Directdraw对象
//创建Directdraw界面
if (FAILED(DirectDrawCreate(NULL, &lpDDraw_temp, NULL)))
{
MessageBox(NULL,TEXT("Direct Draw Create error!"),
TEXT("Wrong!"),MB_OK);
return(0);
}
//查询Directdraw界面
if (FAILED(lpDDraw_temp->QueryInterface(IID_IDirectDraw7,
(LPVOID *)&lpDDraw7)))
{
MessageBox(NULL,TEXT("DirectDraw QueryInterface error!"),
TEXT("Wrong!"),MB_OK);
return(0);
}
//设置协作等级
if (FAILED(lpDDraw7->SetCooperativeLevel(main_window_handle,
DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX |
DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)))
{
MessageBox(NULL,TEXT("DirectDraw SetCooperativeLevel error!"),
TEXT("Wrong!"),MB_OK);
return(0);
}
//设置显示模式
if (FAILED(lpDDraw7->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,0,0)))
{
MessageBox(NULL,TEXT("DirectDraw SetDisplayMode error!"),
TEXT("Wrong!"),MB_OK);
return(0);
}
//创建主画面及后备画面
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);
//设置dwFlags
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
//定义设置一个后备画面
ddsd.dwBackBufferCount = 1;
//定义ddsCaps.dwCaps
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
//创建主画面
if (FAILED(lpDDraw7->CreateSurface(&ddsd, &lpDDprimary, NULL)))
{
MessageBox(NULL,TEXT("DirectDraw Create primary Surface error!"),
TEXT("Wrong!"),MB_OK);
return(0);
}
//设置ddsCaps.dwCaps
ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
//连接主画面及后备画面
if (FAILED(lpDDprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpDDback)))
{
MessageBox(NULL,TEXT("DirectDraw Create back Surface error!"),
TEXT("Wrong!"),MB_OK);
return(0);
}
return(1);
}
/////////////////////////////////////////////
//DirectDraw结束
/////////////////////////////////////////////
int MyDirectDrawShut(void)
{
//释放备用画面指针
if (lpDDbpic)
{
lpDDbpic->Release();
lpDDbpic = NULL;
}
//释放后备画面指针
if (lpDDback)
{
lpDDback->Release();
lpDDback = NULL;
}
//释放主画面指针
if (lpDDprimary)
{
lpDDprimary->Release();
lpDDprimary = NULL;
}
//释放DirectDraw7界面
if (lpDDraw7)
{
lpDDraw7->Release();
lpDDraw7 = NULL;
}
return(1);
}
/////////////////////////////////////////////
//DirectDraw剪切板
/////////////////////////////////////////////
LPDIRECTDRAWCLIPPER CreatDDClipper(LPDIRECTDRAWSURFACE7 lpDDraw,
int Clipnumber,
LPRECT clipsqe)
{
int index;
LPDIRECTDRAWCLIPPER lpDDtempclip; //Directdraw剪切板
LPRGNDATA clipregion; //剪切区域序列
//创建剪切板
if (FAILED(lpDDraw7->CreateClipper(0,&lpDDtempclip,NULL)))
{
MessageBox(NULL,TEXT("DirectDraw Create clipper error!"),
TEXT("Wrong!"),MB_OK);
return(NULL);
}
//定义剪切区
clipregion = (LPRGNDATA)malloc(sizeof(RGNDATAHEADER)+Clipnumber*sizeof(RECT));
memcpy(clipregion->Buffer, clipsqe, sizeof(RECT)*Clipnumber);
clipregion->rdh.dwSize = sizeof(RGNDATAHEADER);
clipregion->rdh.iType = RDH_RECTANGLES;
clipregion->rdh.nCount = Clipnumber;
clipregion->rdh.nRgnSize = Clipnumber*sizeof(RECT);
clipregion->rdh.rcBound.left = 80000;
clipregion->rdh.rcBound.top = 80000;
clipregion->rdh.rcBound.right = -80000;
clipregion->rdh.rcBound.bottom = -80000;
for (index=0; index<Clipnumber; index++)
{
if (clipsqe[index].left < clipregion->rdh.rcBound.left)
clipregion->rdh.rcBound.left = clipsqe[index].left;
if (clipsqe[index].right > clipregion->rdh.rcBound.right)
clipregion->rdh.rcBound.right = clipsqe[index].right;
if (clipsqe[index].top < clipregion->rdh.rcBound.top)
clipregion->rdh.rcBound.top = clipsqe[index].top;
if (clipsqe[index].bottom > clipregion->rdh.rcBound.bottom)
clipregion->rdh.rcBound.bottom = clipsqe[index].bottom;
}
if (FAILED(lpDDtempclip->SetClipList(clipregion, 0)))
{
free(clipregion);
return(NULL);
}
if (FAILED(lpDDraw->SetClipper(lpDDtempclip)))
{
free(clipregion);
return(NULL);
}
free(clipregion);
return(lpDDtempclip);
}
/////////////////////////////////////////////
//读取BMP文件
/////////////////////////////////////////////
int LoadBMPFile(BMP_FILE bitmap, char *filename)
{
int file_handle; //文件句柄
UCHAR *temp_buffer = NULL;
OFSTRUCT file_data;
//打开文件
if ((file_handle = OpenFile(filename,&file_data,OF_READ))==-1)
{
MessageBox(NULL,TEXT("Open bmp File error!"),
TEXT("Wrong!"),MB_OK);
return(0);
}
//读取文件头
_lread(file_handle, &bitmap->bitmapfileheader,sizeof(BITMAPFILEHEADER));
//是否BMP图形格式
if (bitmap->bitmapfileheader.bfType!=BITMAP_ID)
{
//关闭文件
_lclose(file_handle);
MessageBox(NULL,TEXT("bmp File ID error!"),
TEXT("Wrong!"),MB_OK);
return(0);
}
//读取文件头
_lread(file_handle, &bitmap->bitmapinfoheader,sizeof(BITMAPINFOHEADER));
//读数据
_lseek(file_handle,-(int)(bitmap->bitmapinfoheader.biSizeImage),SEEK_END);
//将24位转为16位
if (bitmap->bitmapinfoheader.biBitCount==16 || bitmap->bitmapinfoheader.biBitCount==24)
{
//删除已有信息
if (bitmap->buffer)
free(bitmap->buffer);
//分配空间
if (!(bitmap->buffer = (UCHAR *)malloc(bitmap->bitmapinfoheader.biSizeImage)))
{
//关闭文件
_lclose(file_handle);
MessageBox(NULL,TEXT("bmp File buffer error!"),
TEXT("Wrong!"),MB_OK);
return(0);
}
//读取
_lread(file_handle,bitmap->buffer,bitmap->bitmapinfoheader.biSizeImage);
}
else
{
//出错
MessageBox(NULL,TEXT("bmp File read error!"),
TEXT("Wrong!"),MB_OK);
return(0);
}
//关闭文件
_lclose(file_handle);
//翻转图形
FlipBMPFile(bitmap->buffer,
bitmap->bitmapinfoheader.biWidth*(bitmap->bitmapinfoheader.biBitCount/8),
bitmap->bitmapinfoheader.biHeight);
return(1);
}
/////////////////////////////////////////////
//释放BMP文件
/////////////////////////////////////////////
int UnloadBMPFile(BMP_FILE bitmap)
{
if (bitmap->buffer)
{
free(bitmap->buffer);
bitmap->buffer = NULL;
}
return(1);
}
/////////////////////////////////////////////
//翻转BMP文件
/////////////////////////////////////////////
int FlipBMPFile(UCHAR *image, int bytes_per_line, int height)
{
UCHAR *buffer;
int index;
// 分配空间
if (!(buffer = (UCHAR *)malloc(bytes_per_line*height)))
{
MessageBox(NULL,TEXT("flip bmp File buffer error!"),
TEXT("Wrong!"),MB_OK);
return(0);
}
//翻转
memcpy(buffer,image,bytes_per_line*height);
for (index=0; index < height; index++)
memcpy(&image[((height-1) - index)*bytes_per_line],
&buffer[index*bytes_per_line], bytes_per_line);
free(buffer);
return(1);
}
/////////////////////////////////////////////
//创建BMP画面
/////////////////////////////////////////////
LPDIRECTDRAWSURFACE7 CreatePicSurface(char *filename , int mem_flags , int colorkey)
{
DDSURFACEDESC2 ddsd;
LPDIRECTDRAWSURFACE7 picsurface = NULL;
//读取BMP文件
if (!LoadBMPFile(&bitmap , filename))
{
MessageBox(NULL,TEXT("Load Bitmap File error!"),
TEXT("Wrong!"),MB_OK);
return(0);
}
//创建画面
memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize=sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CKSRCBLT;
ddsd.dwWidth = bitmap.bitmapinfoheader.biWidth;
ddsd.dwHeight= bitmap.bitmapinfoheader.biHeight;
ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = _RGB16BIT565(0,0,0);
ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = _RGB16BIT565(0,0,0);
if(mem_flags == 0)
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN |DDSCAPS_VIDEOMEMORY;
else
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN |DDSCAPS_SYSTEMMEMORY;
if(FAILED(lpDDraw7->CreateSurface(&ddsd,&picsurface,NULL)))
{
MessageBox(NULL,TEXT("DirectDraw Create Pic Surface error!"),
TEXT("Wrong!"),MB_OK);
return(NULL);
}
//设置色彩关键色
DDCOLORKEY color_key;
color_key.dwColorSpaceLowValue = _RGB16BIT565(0,0,255);
color_key.dwColorSpaceHighValue = _RGB16BIT565(0,0,255);
if(FAILED(picsurface->SetColorKey(DDCKEY_SRCBLT , &color_key)))
{
MessageBox(NULL,TEXT("DirectDraw SetColorKey error!"),
TEXT("Wrong!"),MB_OK);
return(NULL);
}
//写入BMP数据
if (FAILED(picsurface->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL)))
{
MessageBox(NULL,TEXT("DirectDraw picsurface lock error!"),
TEXT("Wrong!"),MB_OK);
return(NULL);
}
//得到指针
USHORT *pic_buffer = (USHORT *)ddsd.lpSurface;
//将位图写入画面
for (int index_y = 0; index_y < bitmap.bitmapinfoheader.biHeight; index_y++)
{
for (int index_x = 0; index_x < bitmap.bitmapinfoheader.biWidth; index_x++)
{
//读取色彩
UCHAR blue = (bitmap.buffer[index_y*bitmap.bitmapinfoheader.biWidth*3 + index_x*3]) >> 3,
green = (bitmap.buffer[index_y*bitmap.bitmapinfoheader.biWidth*3 + index_x*3 + 1]) >> 3,
red = (bitmap.buffer[index_y*bitmap.bitmapinfoheader.biWidth*3 + index_x*3 + 2]) >> 3;
pic_buffer[index_x + (index_y*ddsd.lPitch >> 1)] = _RGB16BIT565(red,green,blue);
}
}
if (FAILED(picsurface->Unlock(NULL)))
{
MessageBox(NULL,TEXT("DirectDraw picsurface Unlock error!"),
TEXT("Wrong!"),MB_OK);
return(NULL);
}
//释放BMP
UnloadBMPFile(&bitmap);
return (picsurface);
}
/////////////////////////////////////////////
//画面数据交换
/////////////////////////////////////////////
int SurfaceToBack(LPDIRECTDRAWSURFACE7 sourcesurface , int x1 , int y1,
int x2 , int y2,
LPDIRECTDRAWSURFACE7 destsurface , int x3 , int y3,
int x4 , int y4)
{
RECT dest_rect, // the destination rectangle
source_rect; // the source rectangle
dest_rect.left = x3;
dest_rect.top = y3;
dest_rect.right = x4;
dest_rect.bottom = y4;
source_rect.left = x1;
source_rect.top = y1;
source_rect.right = x2;
source_rect.bottom = y2;
if (FAILED(destsurface->Blt(&dest_rect, sourcesurface,
&source_rect,(DDBLT_WAIT | DDBLT_KEYSRC),
NULL)))
{
MessageBox(NULL,TEXT("DirectDraw backsurface blt error!"),
TEXT("Wrong!"),MB_OK);
return(1);
}
return (0);
}
请教:
各位大哥:
我在 GameStart
已经 将备用画面背景部分拷贝到后备画面
SurfaceToBack(lpDDbpic,0,0,799,599,lpDDback,0,0,799,599);
为什么在 GameMain 还需要将备用画面背景部分拷贝到后备画面
SurfaceToBack(lpDDbpic,0,0,799,599,lpDDback,0,0,799,599);
呢?
如果我在 GameMain 在 将 SurfaceToBack(lpDDbpic,0,0,799,599,lpDDback,0,0,799,599);
注释掉 ,左单鼠标,则是黑屏的。
各位大哥,这是为什么啊?
谢谢!
[em16] [em20] [em21] [em3] |
|