最简单的游戏程序代码~
#include <windows.h>#include <ddraw.h> // DirectDraw所使用的头文件;
#define MAP_X 64
#define MAP_Y 48
// 变量、声明函数;
LPDIRECTDRAW lpDD; // DirectDraw对象;
LPDIRECTDRAWSURFACE lpDDSPrimary; //主页面,就是你看到的屏幕
LPDIRECTDRAWSURFACE lpDDSBack; //后备页面,用于翻转屏幕
LPDIRECTDRAWSURFACE lpBK; //地图页面
LPDIRECTDRAWSURFACE lpPlayer; //英雄页面
LPDIRECTDRAWSURFACE lplogo; //logo页面
LPDIRECTDRAWSURFACE lphays; //海斯
int MAP={
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,1,1,1,1,0,1},
{1,0,0,1,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,1,0,1},
{1,0,0,1,0,0,1,1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,1,1,0,1},
{1,0,0,1,0,0,0,1,0,1,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,1,0,0,0,0,0,1},
{1,0,0,1,0,0,0,1,0,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,1},
{1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}};
int SX=0,SY=0;//地图坐标
int old_SX=0,old_SY=0;
RECT rect;//blt用的巨型
int speed=10;
typedef struct{
int x,y; //当前坐标
int old_x,old_y; //旧的坐标
int Way; //方向
int Stats; //状态
}Role;
Role Hero={1,
1,
0,
0,
0};
//函数声明列表
RECT GetRect(int x1,int y1,int x2,int y2);
void MainLoop();
void Gamehead();
void BackGround();
LPDIRECTDRAWSURFACE bitmap_surface(char* file_name);
DWORD DDColorMatch(IDirectDrawSurface *pdds, COLORREF rgb);
HRESULT DDSetColorKey(IDirectDrawSurface *pdds, COLORREF rgb);
LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
void Delay(long time); //时间函数
BOOL InitWindow(HINSTANCE hInstance, int nCmdShow); // 创建主工作窗口;
BOOL InitDDraw(void); // 初始化DirectDraw并且打印字
#define SafeRelease(x) if (x) { x->Release(); x=NULL; }
void Cleanup(void); // 卸载DirectDraw函数;
BOOL InitWindow(HINSTANCE hInstance, int nCmdShow)
{
HWND hwnd; // 窗口句柄;
WNDCLASS wcex; // 窗口类结构;
// 设置窗口类结构;
wcex.style=0; // 风格;
wcex.lpfnWndProc=WinProc; // 窗口处理程序;
wcex.cbClsExtra=0; // 扩充风格;
wcex.cbWndExtra=0; // 扩充程序;
wcex.hInstance=hInstance; // 应用程序hInstance句柄;
wcex.hIcon=LoadIcon(hInstance,IDI_APPLICATION); // 读入默认的图标;
wcex.hCursor=LoadCursor(NULL,IDC_ARROW); // 读入默认鼠标形状;
wcex.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);//窗口背景;
wcex.lpszMenuName=NULL; // 窗口目录;
wcex.lpszClassName= "DirectX--Hello"; // 窗口的类名
// 注册窗口类;
RegisterClass(&wcex);
// 创建主窗口;
hwnd=CreateWindowEx(WS_EX_TOPMOST,"DirectX--Hello","",WS_POPUP|WS_VISIBLE,
0,0,GetSystemMetrics(SM_CXSCREEN),
GetSystemMetrics(SM_CYSCREEN),NULL,NULL,hInstance,NULL);
if(!hwnd) return FALSE;
ShowWindow(hwnd,nCmdShow); // 显示窗口;
UpdateWindow(hwnd); // 更新窗口;
SetTimer(hwnd,1,30,NULL);
return TRUE;
}
LRESULT CALLBACK WinProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message)
{
case WM_TIMER:
lpDDSPrimary->Flip( NULL, 0 );
break;
case WM_KEYDOWN: // 如果击键;
switch(wParam)
{
case VK_UP:
Hero.Way=3;
if (SY<=0 && Hero.y<=240) //往上走
{
SY=old_SY;
Hero.y-=speed;
}
else if(SY>=MAP_Y-48 && Hero.y>=240)
{
SY=old_SY;
Hero.y-=speed;
}
else SY--;
break;
case VK_DOWN:
Hero.Way=0;
if (SY>MAP_Y-48 && Hero.y>=240) //往下走
{
SY=old_SY;
Hero.y+=speed;
}
else if (SY<=0 && Hero.y<=240)
{
SY=old_SY;
Hero.y+=speed;
}
else SY++;
break;
case VK_LEFT:
Hero.Way=1;
if (SX<=0 && Hero.x<=320) //往左边走
{
SX=old_SX;
Hero.x-=speed;
}
else if (SX>=MAP_X-32 && Hero.x>=320)
{
SX=old_SX;
Hero.x-=speed;
}
else SX--;
break;
case VK_RIGHT:
Hero.Way=2;
if (SX>=MAP_X-32 && Hero.x>=320) //往右边走
{
SX=old_SX;
Hero.x+=speed;
}
else if (SX<=0 && Hero.x<=320)
{
SX=old_SX;
Hero.x+=speed;
}
else SX++;
break;
}
Hero.Stats++;
if( Hero.Stats>=3 ) Hero.Stats=0;
break;
case WM_DESTROY: // 退出消息循环;
Cleanup();
PostQuitMessage(0);
break;
}
// 调用缺省消息处理过程;
return DefWindowProc(hWnd,message,wParam,lParam);
}
// 本程序的最核心内容,即DirectDraw的基本功能与用法;
BOOL InitDDraw(void)
{
DDSURFACEDESC ddsd;
HDC hdc;
DDSCAPS ddscaps;
// 创建DirectDraw对象;
if (DirectDrawCreate(NULL,&lpDD,NULL)!=DD_OK) return FALSE;
// 设置为全屏模式;
if (lpDD->SetCooperativeLevel(GetActiveWindow(),
DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN)!=DD_OK)
return FALSE;
// 设置显示模式;
if (lpDD->SetDisplayMode(640,480,16)!=DD_OK) return FALSE;
// 设置主页面信息;
ddsd.dwSize=sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
DDSCAPS_FLIP |
DDSCAPS_COMPLEX;
ddsd.dwBackBufferCount = 1;
// 创建一个表面,类似开辟一块屏幕大小的显示内存;
if (lpDD->CreateSurface(&ddsd,&lpDDSPrimary,NULL)!=DD_OK)
MessageBox(NULL,"SDSDSDSD","sdsdsdsdsd",0);
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
if ( lpDDSPrimary->GetAttachedSurface(&ddscaps, &lpDDSBack)!=DD_OK)
MessageBox(NULL,"SDSDSDSD","sdsdsdsdsd",0);
lpBK = bitmap_surface("map1.bmp");
lplogo = bitmap_surface("logo.bmp");
lphays = bitmap_surface("hays.bmp");
lpPlayer = bitmap_surface("PLAYER.bmp");
DDSetColorKey(lpPlayer,RGB(255,238,187));
return TRUE;
}
void Cleanup(void)
{
SafeRelease(lpBK);
SafeRelease(lpPlayer);
SafeRelease(lpPlayer);
SafeRelease(lpDDSBack);
SafeRelease(lpDD);
SafeRelease(lplogo);
}
// Windows的主工作函数,类似Dos下Turbo C编程的main();
int PASCAL WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
LPSTR lpCmdLine,int nCmdShow)
{
MSG msg;
// 初始化主窗口;
if (!InitWindow(hInstance,nCmdShow)) return FALSE;
// 初始化DirectDraw环境,并实现DirectDraw功能;
if (!InitDDraw())
{
MessageBox(GetActiveWindow(),"初始化DirectDraw时出错!",
"Error",MB_OK);
void Cleanup();
DestroyWindow(GetActiveWindow());
return FALSE;
}
Gamehead();
// 进入消息循环;
while(1)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if(!GetMessage(&msg, NULL, 0, 0 )) return msg.wParam;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
MainLoop();
}
return msg.wParam;
}
//游戏需要用到的函数
void Gamehead()
{
RECT rect1={0,0,178,145};
int x=80,y=100;
int i;
lpDDSPrimary->BltFast( 130+80, 202+120, lphays , &rect1, DDBLTFAST_NOCOLORKEY);
for (i=0;i<6;i++)
{
rect1=GetRect(i*65,0,i*65+65,202);
lpDDSPrimary->BltFast( x+=65, y, lplogo , &rect1, DDBLTFAST_NOCOLORKEY);
Delay(500);
}
Delay(3000);
}
void BackGround() //画地图
{
int i,j;
for (i=SY;i<SY+15;i++)
for (j=SX;j<SX+20;j++)
if (MAP==1)
{
rect=GetRect(0,0,32,32);
lpDDSBack->BltFast( (j-SX)*32, (i-SY)*32, lpBK , &rect, DDBLTFAST_NOCOLORKEY);
}
else
{
rect=GetRect(0,32,32,64);
lpDDSBack->BltFast( (j-SX)*32, (i-SY)*32, lpBK , &rect, DDBLTFAST_NOCOLORKEY);
}
}
RECT GetRect(int x1,int y1,int x2,int y2) //获取对象巨型
{
RECT TempRect={x1,y1,x2,y2};
return TempRect;
}
void MainLoop() //游戏循环
{
BackGround();
RECT rect2={Hero.Stats*32, Hero.Way*48, Hero.Stats*32+32, Hero.Way*48+48};
lpDDSBack->BltFast( Hero.x, Hero.y, lpPlayer , &rect2, DDBLTFAST_SRCCOLORKEY);
if( Hero.x<0 ) Hero.x=0;
if( Hero.x>640-32 ) Hero.x=640-32;
if( Hero.y<0 ) Hero.y=0;
if( Hero.y>480-48 ) Hero.y=480-48;
Hero.old_x=Hero.x;
Hero.old_y=Hero.y;
old_SX = SX; old_SY = SY;
}
void Delay(long time) //时间函数
{
static long old_clock, new_clock; //延时变量
new_clock=old_clock=GetTickCount();
while( new_clock < old_clock + time )
{
new_clock=GetTickCount();
}
}
//下面是dx相关的函数
LPDIRECTDRAWSURFACE bitmap_surface(char* file_name) //位图载入
{
HDC hdc;
HBITMAP bit;
LPDIRECTDRAWSURFACE surf;
bit=(HBITMAP) LoadImage(NULL,file_name,IMAGE_BITMAP,0,0,
LR_DEFAULTSIZE|LR_LOADFROMFILE);
if (!bit)
return NULL;
BITMAP bitmap;
GetObject( bit, sizeof(BITMAP), &bitmap );
int surf_width=bitmap.bmWidth;
int surf_height=bitmap.bmHeight;
HRESULT ddrval;
DDSURFACEDESC ddsd;
ZeroMemory(&ddsd,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT ;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY;
ddsd.dwWidth = surf_width;
ddsd.dwHeight = surf_height;
ddrval=lpDD->CreateSurface(&ddsd,&surf,NULL);
if (ddrval!=DD_OK) {
DeleteObject(bit);
return NULL;
} else {
surf->GetDC(&hdc);
HDC bit_dc=CreateCompatibleDC(hdc);
SelectObject(bit_dc,bit);
BitBlt(hdc,0,0,surf_width,surf_height,bit_dc,0,0,SRCCOPY);
surf->ReleaseDC(hdc);
DeleteDC(bit_dc);
}
DeleteObject(bit);
return surf;
}
DWORD 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;
}
/*
* DDSetColorKey
*
* set a color key for a surface, given a RGB.
* if you pass CLR_INVALID as the color key, the pixel
* in the upper-left corner will be used.
*/
HRESULT DDSetColorKey(IDirectDrawSurface *pdds, COLORREF rgb) //关键色设置
{
DDCOLORKEY ddck;
ddck.dwColorSpaceLowValue= DDColorMatch(pdds, rgb);
ddck.dwColorSpaceHighValue = ddck.dwColorSpaceLowValue;
return pdds->SetColorKey(DDCKEY_SRCBLT, &ddck);
}
我花了一小时写的!!!!!!!!!!!!!!!!!!!!!!
游戏下载地址 hays2002.51.net/game1.rar
干什么的?走迷宫?
还有,代码中混杂英语和中文注译,我怀疑英文部分不是你原创 楼主牛,我一小时只能读懂程序结构和实现方法。
不过void Delay(long time) 函数有问题,把CPU时间都白白吃光了,应该改成Sleep() 不是吧,这样的程序都叫"最"简单了啊,我看来都是在写白痴程序了 绝对原创。。。。。。void Delay(long time) 函数的功能就是用来延时的。。。。。。 以下是引用hays2002在2004-4-10 15:23:06的发言:
绝对原创。。。。。。void Delay(long time) 函数的功能就是用来延时的。。。。。。
延时还有比Sleep(int)更好的吗?不浪费cpy啊,你用循环来拖延真是大胆创新啊 循环延时有是有的,不过会造成不同配置上的延时的不一致
再问一次,这个游戏到底是游的什么??? 是什么游戏啊 以下是引用hays2002在2004-4-10 15:23:06的发言:
绝对原创。。。。。。void Delay(long time) 函数的功能就是用来延时的。。。。。。
void Delay(long time) 确实可以用来延时,而且延时也比较准,但是Delay()是用CPU满负荷运行换来的。
在你的程序中把Delay(long time) 换成Sleep(long time) ,然后看看CPU的负荷就知道了。
按理说能够在一小时内编出这个游戏的人不会不知道考虑CPU效率的,除非你喜欢让CPU发烧。
timeSetEvent 这个winAPI来定时不是更好马,毫秒精度应该也可以了
另外好像是用mfc还是什么的,mfc总是把我盟在雇里
rpg吗?呵呵 楼主的编码风格真好,一会用C++的风格,一会儿用C的风格,不知道楼主是不是学这两种语言的时候走火入魔了。
页:
[1]