📄 mygame.cpp
字号:
ddrval = lpDDSSlot->Restore ();
ddrval = lpDDSTalkbar->Restore ();
ddrval = lpDDSContinue->Restore ();
ddrval = lpDDSMenuback->Restore ();
ddrval = lpDDSListBox->Restore ();
ddrval = lpDDSScrollArrows->Restore ();
ddrval = lpDDSRectangle->Restore ();
ddrval = lpDDSHandcursor->Restore ();
ddrval = lpDDSWeapon->Restore ();
ddrval = lpDDSArmor->Restore ();
ddrval = lpDDSOptionBox->Restore ();
ddrval = lpDDSMsgBox->Restore ();
return ddrval;
}
LPDIRECTSOUNDBUFFER LoadSoundFX(HWND hwnd,char *filename)
{
if( SoundAble==FALSE ) return FALSE;
LPDIRECTSOUNDBUFFER DSSoundFX=NULL; //临时对象
DSBUFFERDESC dsbd; //结构
LPWAVEFORMATEX wav; //声音格式
DWORD len; //文件长度
BYTE *buf; //临时缓冲区
LPVOID ptr1; //指针1
LPVOID ptr2; //指针2
DWORD size1;
DWORD size2;
DWORD BufferSize; //DirectSoundBuffer 大小
FILE *f;
long WavLong;
if( (f=fopen(filename,"rb"))==NULL )
{
MessageBox(hwnd,"error open file",filename,MB_OK);
return FALSE;
}
fseek(f,0x28,SEEK_SET);
fread(&WavLong,sizeof(long),1,f); //读取声音数据长度
len=WavLong+WAV_HDR_SIZE; //文件长度
BufferSize=len-WAV_HDR_SIZE; //设置缓冲去大小
buf=(BYTE *)GlobalAlloc(GPTR,len);
if( buf==NULL )
{
MessageBox(hwnd,"error buf","error",MB_OK);
return FALSE;
}
fseek(f,0x00,SEEK_SET);
fread(buf,len,1,f);
fclose(f);
//读取声音数据到临时缓冲区
ptr1=buf+20;
wav=(LPWAVEFORMATEX)(ptr1);
memset(&dsbd,0,sizeof(dsbd));
dsbd.dwSize=sizeof(dsbd);
dsbd.dwFlags=DSBCAPS_STATIC;//DSBCAPS_CTRLDEFAULT|
dsbd.dwBufferBytes=len-WAV_HDR_SIZE;
dsbd.lpwfxFormat=wav;
if(lpDSObj->CreateSoundBuffer(&dsbd,&DSSoundFX,NULL)!=DS_OK)
{
MessageBox(hwnd,"error createsoundbuffer","error",MB_OK);
return FALSE;
}
if( (DSSoundFX->Lock(0,BufferSize,&ptr1,&size1,&ptr2,&size2,0))!=DS_OK)
{
MessageBox(hwnd,"error Lock","error",MB_OK);
return FALSE;
}
memcpy(ptr1,buf+WAV_HDR_SIZE,size1); //拷贝数据到声音缓冲区
if(size2)
memcpy(ptr2,buf+size1+WAV_HDR_SIZE,size2);//拷贝数据到声音缓冲区
if( DSSoundFX->Unlock(ptr1,size1,ptr2,size2)!=DS_OK)
{
MessageBox(hwnd,"error UnLock","error",MB_OK);
return FALSE;
}
GlobalFree(buf);
return DSSoundFX;//返回
}
BOOL InitDirectSound(HWND hwnd) //初始化声音设备
{
if( DirectSoundCreate(NULL,&lpDSObj,NULL)!=DS_OK )
{
MessageBox(hwnd,"error on Create","error",MB_OK);
SoundAble=FALSE;
return FALSE;
}
if( lpDSObj->SetCooperativeLevel(hwnd,DSSCL_NORMAL)!=DS_OK)
{
MessageBox(hwnd,"error on set","error",MB_OK);
SoundAble=FALSE;
return FALSE;
}
return TRUE; // 初始化成功
}
void ReleaseDirectSound(void) //释放DirectSound设备
{
SAFE_RELEASE(auCursorMove);
SAFE_RELEASE(auEquip);
SAFE_RELEASE(auRefreshment);
SAFE_RELEASE(auDiscard);
SAFE_RELEASE(auCannot);
SAFE_RELEASE(auMoney);
SAFE_RELEASE(auAttack);
SAFE_RELEASE(auFire);
SAFE_RELEASE(auThunder);
SAFE_RELEASE(lpDSObj);
}
void PlayDirectSound(LPDIRECTSOUNDBUFFER sbuf,DWORD loop=0)//播放声音
{
if( SoundAble==FALSE ) return;
DWORD *Status1=NULL;
if( (sbuf->GetStatus(Status1))!=DS_OK ) goto next;
if( *Status1 & DSBSTATUS_PLAYING == DSBSTATUS_PLAYING ) return;
next:
sbuf->SetCurrentPosition(0);
sbuf->Play(0,0,loop);
}
//读取声音数据
void LoadSoundData()
{
char *Soundsets[]={"Audio\\CursorMove.wav", "Audio\\Equip.wav", "Audio\\Refreshment.wav", "Audio\\Discard.wav",
"Audio\\Cannot.wav", "Audio\\Money.wav", "Audio\\Attack.wav", "Audio\\Fire.wav",
"Audio\\Thunder.wav"};
auCursorMove=LoadSoundFX(hWnd, Soundsets[0]);
auEquip = LoadSoundFX(hWnd, Soundsets[1]);
auRefreshment = LoadSoundFX(hWnd, Soundsets[2]);
auDiscard = LoadSoundFX(hWnd, Soundsets[3]);
auCannot = LoadSoundFX(hWnd, Soundsets[4]);
auMoney = LoadSoundFX(hWnd, Soundsets[5]);
auAttack = LoadSoundFX(hWnd, Soundsets[6]);
auFire = LoadSoundFX(hWnd, Soundsets[7]);
auThunder = LoadSoundFX(hWnd, Soundsets[8]);
}
void InitDI(void)
{
//建立 DirectInput 对象
if(DirectInputCreateEx(GetModuleHandle(NULL), DIRECTINPUT_VERSION,IID_IDirectInput7, (void**)&DI, NULL)!= DI_OK)
{
MessageBox(hWnd,"建立 DirectInput 对象失败!",
"Error",MB_OK);
return;
}
//建立输入装置对象
if(DI->CreateDeviceEx(GUID_SysKeyboard, IID_IDirectInputDevice7,(void**)&DIms, NULL)!= DI_OK)
{
MessageBox(hWnd,"建立键盘输入装置失败!",
"Error",MB_OK);
return;
}
//设定数据格式
if(DIms->SetDataFormat(&c_dfDIKeyboard)!= DI_OK)
{
MessageBox(hWnd,"设定数据格式失败!",
"Error",MB_OK);
return;
}
//设定协调层级
if(DIms->SetCooperativeLevel(hWnd,DISCL_BACKGROUND | DISCL_NONEXCLUSIVE) != DI_OK)
{
MessageBox(hWnd,"设定程序协调层级失败!",
"Error",MB_OK);
return;
}
//取用输入装置
if(DIms->Acquire() != DI_OK)
{
MessageBox(hWnd,"取用输入装置失败!",
"Error",MB_OK);
return;
}
}
void ReleaseDirectInput(void) //释放DirectInput设备;
{
DIms->Unacquire();
SAFE_RELEASE(DIms);
SAFE_RELEASE(DI);
}
HWND 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(BLACK_BRUSH);//窗口背景;
wcex.lpszMenuName=NULL; // 窗口目录;
wcex.lpszClassName= "Mygame"; // 窗口的类名
// 注册窗口类;
RegisterClass(&wcex);
// 创建主窗口;
hwnd=CreateWindowEx(WS_EX_TOPMOST,"Mygame","My RPG",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); // 更新窗口;
return hwnd;
}
LRESULT CALLBACK WinProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
switch(message)
{
case WM_ACTIVATEAPP://
bActive = wParam;
break;
case WM_SETCURSOR:
SetCursor(NULL);
return TRUE;
case WM_TIMER: //背景音乐循环播放
Times++;
if(SoundAble==TRUE && Times>645) //4分18秒;
{
mciSendString("close all", buf, sizeof(buf), NULL);
mciSendString("open Audio\\Background.mid",buf,sizeof(buf),NULL);
mciSendString("play Audio\\Background.mid", buf, sizeof(buf), NULL);
Times=0;
}
break;
case WM_DESTROY: // 退出消息循环;
DestroyWorld();
UninitDDraw();
ReleaseDirectSound();
ReleaseDirectInput();
if( SoundAble==TRUE )
{
mciSendString("close all", buf, sizeof(buf), NULL);
}
PostQuitMessage(0);
break;
}
// 调用缺省消息处理过程;
return DefWindowProc(hWnd,message,wParam,lParam);
}
// Windows的主工作函数,类似Dos下Turbo C编程的main();
int PASCAL WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
LPSTR lpCmdLine,int nCmdShow)
{
MSG msg;
// 初始化主窗口;
hWnd=InitWindow( hInstance, nCmdShow ) ;
if (hWnd == NULL )
return FALSE;
// 初始化DirectDraw环境,并实现DirectDraw功能;
if (!InitDDraw())
{
MessageBox(hWnd,"初始化DirectDraw时出错!",
"Error",MB_OK);
UninitDDraw();
DestroyWindow(hWnd);
return FALSE;
}
InitDirectSound(hWnd); //初始化DirectSound;
LoadSoundData(); //读入声音数据;
InitDI(); //初始化DirectInput;
LoadMaps(); //载入地图;
LoadNpcData(); //载入Npc数据;
LoadTalkText(); //载入对话数据;
LoadItemData(); //载入物品数据;
InitGameData(); //初始化游戏数据;
// 进入消息循环;
while(1)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if(!GetMessage(&msg, NULL, 0, 0 )) return msg.wParam;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else if(bActive)
{
MainLoop(); //进入游戏主循环
}
//等待消息
else WaitMessage();
}
}
//==============和Direct Draw 有关的函数==================
//创建页面
BOOL CreateBitmap(LPDIRECTDRAWSURFACE &lpTemp,int x,int y,char *BitmapFile, DWORD MemoryFlag)
{
DDSURFACEDESC ddsd;
HRESULT ddrval;
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | MemoryFlag;
ddsd.dwWidth = x;
ddsd.dwHeight = y;
ddrval = lpDD->CreateSurface( &ddsd, &lpTemp, NULL );
if( ddrval != DD_OK )
{
return initFail(BitmapFile);
}
if( BitmapFile!=NULL )
DDReLoadBitmap(lpTemp,BitmapFile);
return TRUE;
}
//***********************************************************
//位图拷贝
BOOL Blt(LPDIRECTDRAWSURFACE SS,int x,int y,
LPDIRECTDRAWSURFACE DS,RECT rcRect,BOOL Flog)
{
HRESULT ddrval;
DWORD Flogs= (Flog==FALSE)?DDBLTFAST_NOCOLORKEY:DDBLTFAST_SRCCOLORKEY;
//边界检查
if( x<0 ) { rcRect.left = rcRect.left - x; x=0; }
if( y<0 ) { rcRect.top = rcRect.top - y; y=0; }
if( x+ rcRect.right - rcRect.left > ScreenX ) { rcRect.right = rcRect.left + ScreenX - x; }
if( y+ rcRect.bottom - rcRect.top > ScreenY ) { rcRect.bottom = rcRect.top + ScreenY - y; }
while( 1 )
{
ddrval = SS->BltFast( x, y, DS, &rcRect, Flogs);
if( ddrval == DD_OK )
{
return TRUE;
}
if( ddrval == DDERR_SURFACELOST )
{
ddrval = restoreAll();
ddrval = SS->Restore();
ddrval = DS->Restore();
if( ddrval != DD_OK )
{
return TRUE;
}
}
if( ddrval != DDERR_WASSTILLDRAWING )
{
return FALSE;
}
}
if(ddrval != DD_OK)
{
return FALSE;
}
}
//*****************************************************
//换页
void Flip(void)
{
HRESULT ddrval;
while( 1 )
{
ddrval = lpDDSPrimary->Flip( NULL, 0 );
if( ddrval == DD_OK )
{
break;
}
if( ddrval == DDERR_SURFACELOST )
{
ddrval = restoreAll();
if( ddrval != DD_OK )
{
break;
}
}
if( ddrval != DDERR_WASSTILLDRAWING )
{
break;
}
}
}
//清屏
void Clrscr( DWORD color=RGB(0,0,0) )
{
DDBLTFX ddbltfx;
ddbltfx.dwSize=sizeof(ddbltfx);
ddbltfx.dwFillColor=color;
lpDDSPrimary->Blt(NULL,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
lpDDSBack->Blt(NULL,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
}
//填充实心矩阵;
void Bar(LPDIRECTDRAWSURFACE surf, int x1, int y1, int x2, int y2, DWORD color)
{
DDBLTFX ddbltfx;
RECT dest;
ddbltfx.dwSize = sizeof( ddbltfx );
ddbltfx.dwFillColor = color; //用指定的颜色填充
dest.left = x1;
dest.top = y1;
dest.right = x2;
dest.bottom = y2;
if ( FAILED( surf->Blt( &dest, NULL, NULL,
DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx ) ) )
{
return;
}
}
//初始化失败的处理函数
BOOL initFail(char *str)
{
UninitDDraw();
MessageBox( hWnd, str, "error", MB_OK );
DestroyWindow( hWnd );
return FALSE;
}
//设置矩形;
RECT GetRect(int x1,int y1,int x2,int y2)
{
RECT TempRect={x1,y1,x2,y2};
return TempRect;
}
//转化整数到DIRECTION;
DIRECTION Int2Dir(int n)
{
int m=n%4;
switch(m)
{
case 0:
return DOWN;
case 1:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -