vc++游戏编程指南.docx
- 文档编号:883641
- 上传时间:2022-10-13
- 格式:DOCX
- 页数:43
- 大小:125.84KB
vc++游戏编程指南.docx
《vc++游戏编程指南.docx》由会员分享,可在线阅读,更多相关《vc++游戏编程指南.docx(43页珍藏版)》请在冰豆网上搜索。
vc++游戏编程指南
第七章我没有想好名字
如果你只靠上面几章所讲述的知识编了个游戏,喜欢的人恐怕会不多☺,为什么?
因为没有人会玩一个控制不流畅而且声音效果不佳的游戏。
为了在游戏中更好地管理各种输入设备,我们需要使用DirectInput。
而通过使用DirectXAudio可以在游戏中实现各种更逼真的音乐效果。
它们都是DirectX的重要组成部分。
使用DirectInput前我们需要#include
7.1读取键盘数据
首先,我们必须创建一个DirectInput8对象(DirectX9.0并没有对DInput和DAudio做多大改动),就像这样:
LPDIRECTINPUT8pInput;
DirectInput8Create(GetModuleHandle(NULL),
DIRECTINPUT_VERSION,
IID_IDirectInput8,
(void**)&pInput,
NULL);
然后,我们需要创建一个DirectInput设备:
LPDIRECTINPUTDEVICE8pDev;
pInput->CreateDevice(GUID_SysKeyboard,&pDev,NULL);
设置好它的数据格式:
pDev->SetDataFormat(&c_dfDIKeyboard);
设置它的协作级,这里设为独占设备+前台:
pDev->SetCooperativeLevel(hwnd,DISCL_EXCLUSIVE|DISCL_FOREGROUND);
获取设备:
pDev->Acquire();
像上面那样初始化后,我们就已经把Windows对键盘的控制权剥夺了,以后的键盘消息将不会被送入消息循环,我们可以把消息循环中处理键盘消息的语句拿掉了。
当然,这时我们需要在程序的适当地方,比如说在刷新游戏时,加入对键盘数据进行读取和处理的语句,就像下面的一段程序:
#defineKEYDOWN(key)(buffer[key]&0x80)//定义一个宏,方便处理键盘数据
charbuffer[256];//键盘数据
pDev->GetDeviceState(sizeof(buffer),(LPVOID)&buffer);//得到键盘数据
if(KEYDOWN(DIK_XXX))//如果XXX键被按下…(请参阅附录二)
{
……//处理之
}
……//处理其它键
哈哈,真是挺方便的。
有时候真的有点怀疑DirectX是不是一种回到遥远的可爱的DOS时代的“倒退”。
因为无论是DirectInput还是DirectDraw都是太像DOS下的做法了。
7.2读取鼠标数据
读取鼠标数据和读取键盘数据的步骤差不多,首先也是要创建设备:
pInput->CreateDevice(GUID_SysMouse,&pDev,NULL);
设置数据格式:
pDev->SetDataFormat(&c_dfDIMouse);
设置协作级:
pDev->SetCooperativeLevel(hwnd,DISCL_EXCLUSIVE|DISCL_FOREGROUND);
获取设备:
pDev->Acquire();
那么怎样读取鼠标数据呢?
如果要取得鼠标的当前状态,这样即可:
DIMOUSESTATEmouse_stat;//鼠标状态
//得到鼠标状态
pDev->GetDeviceState(sizeof(DIMOUSESTATE),(LPVOID)&mouse_stat);
得到的mouse_stat是一个DIMOUSESTATE类型的结构,它有四个成员:
lX,lY,lZ和rgbButtons[4]。
其中lX、lY和lZ分别是自上次调用此函数以来鼠标在X轴、Y轴和Z轴(滚轮)方向上移动的距离,而不是鼠标此时的坐标;其距离单位不是像素,但你完全可以把它看做以像素为单位。
所以,我们需要定义两个变量mousex=0和mousey=0,然后把lX和lY累加上去即可。
这样做的好处是鼠标坐标不再受屏幕的制约,而且屏幕中心的mousex和mousey值可以永远是0,不随屏幕分辨率而改变。
rgbButtons是一个存储哪些鼠标键被按下的数组,我们可以这样做来读取它:
//定义一个宏,方便处理鼠标数据
#defineMOUSEBUTTONDOWN(b)(mouse_stat.rgbButtons[b]&0x80)
if(MOUSEBUTTONDOWN(0))//如果左键被按下…
{
……//处理之
}
……//处理右键
(1)和中键
(2)
7.3恢复和关闭DirectInput
7.3.1恢复DirectInput设备
就像在DirectDraw中那样,使用DirectInput的程序被最小化时DirectInput设备会出现"丢失"现象。
恢复的办法很干脆:
先关闭DirectInput再重新初始化即可。
7.3.2关闭DirectInput
关闭DirectInput也是非常简单的(SAFE_RELEASE的定义在4.8节):
pDev->Unacquire();
SAFE_RELEASE(pDev);
SAFE_RELEASE(pInput);
7.4初始化和关闭DirectXAudio
7.4.1初始化DirectXAudio
使用DirectXAudio前,按规矩还是要先初始化。
在下面的这段初始化程序中要用到三个DXAudio提供的对象:
IDirectMusicLoader8、IDirectMusicPerformance8和IDirectMusicSegment8。
IDirectMusicLoader8顾名思义是用来调入音乐的,IDirectMusicPerformance8可以认为是音频设备,而IDirectMusicSegment8就是代表音乐。
#include
IDirectMusicLoader8*pLoader=NULL;
IDirectMusicPerformance8*pPerf=NULL;
IDirectMusicSegment8*pSeg=NULL;
CoInitialize(NULL);//初始化COM
CoCreateInstance(CLSID_DirectMusicLoader,NULL,
CLSCTX_INPROC,IID_IDirectMusicLoader8,
(void**)&pLoader);//创建pLoader对象
CoCreateInstance(CLSID_DirectMusicPerformance,NULL,
CLSCTX_INPROC,IID_IDirectMusicPerformance8,
(void**)&pPerf);//创建pPerf对象
pPerf->InitAudio(
NULL,//这里可以是一个指向IDirectMusic*对象的指针
NULL,//这里可以是一个指向IDirectSound*对象的指针
hwnd,//窗口句柄
DMUS_APATH_SHARED_STEREOPLUSREVERB,//AudioPath类型
//这里打开了立体声及混响,效果很不错
64,//音乐通道数
DMUS_AUDIOF_ALL,//使用声卡的所有特性
NULL//可以指向一个DMUS_AUDIOPARAMS对象,更详细地说明各种参数
);
7.4.2关闭DirectXAudio
关闭DXAudio还是老思路,先按7.5.3节的办法停止音乐,然后Release即可:
pPerf->CloseDown();//关闭
SAFE_RELEASE(pLoader);//释放对象
SAFE_RELEASE(pPerf);
SAFE_RELEASE(pSeg);
CoUninitialize();//停止使用COM
7.5播放MIDI和WAV音乐
MIDI音乐和WAV音乐在游戏编程中经常用到。
其中前者一般是用作背景音乐,而后者多是用在各种音效方面,如发射导弹等等。
虽然我们可以用3.4.4节的方法,但使用DXAudio可以更充分地利用硬件资源,从而实现更少的CPU占用率。
方法如下:
7.5.1调入MIDI和WAV文件
在播放音乐之前,第一步当然是调入音乐文件:
CHARstrSoundPath[MAX_PATH];//存储音乐所在路径
GetCurrentDirectory(MAX_PATH,strSoundPath);//得到程序所在路径
strcat(strSoundPath,"\\Sounds");//这里设置音乐在程序路径下的Sounds子目录
WCHARwstrSoundPath[MAX_PATH];//存储UNICODE形式的路径
//将路径转为UNICODE形式
MultiByteToWideChar(CP_ACP,0,strSoundPath,-1,wstrSoundPath,MAX_PATH);
pLoader->SetSearchDirectory(
GUID_DirectMusicAllTypes,//搜索所有支持的格式
wstrSoundPath,
FALSE
);
WCHARwstr[MAX_PATH];//存储UNICODE形式的文件名
//将文件名转为UNICODE形式
MultiByteToWideChar(CP_ACP,0,"a.mid",-1,wstr,MAX_PATH);
pLoader->LoadObjectFromFile(
CLSID_DirectMusicSegment,//文件类型
IID_IDirectMusicSegment8,//目标对象类型
wstr,//文件名,同样应为UNICODE形式
(LPVOID*)&pSeg//目标对象
);
7.5.2播放MIDI和WAV文件
调入完音乐之后,在适当的时候可以开始播放音乐:
pSeg->SetRepeats(音乐要重复的次数);//DMUS_SEG_REPEAT_INFINITE为无限次
pSeg->Download(pPerf);//将音乐数据传给pPerf
pPerf->PlaySegmentEx(
pSeg,//要播放的音乐
NULL,//现在只能是NULL
NULL,
0,
0,
NULL,
NULL,
NULL//Audiopath,现在先不要管它是什么
);
7.5.3停止播放
停止播放音乐也是非常简单的:
pPerf->Stop(
NULL,//停止哪个通道,NULL代表所有通道
NULL,
0,//经过多少时间才停止播放
0
);
7.6在3D空间中播放音乐
我们的下一个问题是如何使音乐更逼真,最好能使音乐3D化,这将大大加强真实性。
要实现这个其实也不难,首先我们要设定所谓的AudioPath,它可以指定音乐的播放方式。
IDirectMusicAudioPath8*pPath;//AudioPath
pPerf->CreateStandardAudioPath(//创建AudioPath
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- vc 游戏 编程 指南