vc++游戏编程指南.docx

上传人:b****3 文档编号:883641 上传时间:2022-10-13 格式:DOCX 页数:43 大小:125.84KB
下载 相关 举报
vc++游戏编程指南.docx_第1页
第1页 / 共43页
vc++游戏编程指南.docx_第2页
第2页 / 共43页
vc++游戏编程指南.docx_第3页
第3页 / 共43页
vc++游戏编程指南.docx_第4页
第4页 / 共43页
vc++游戏编程指南.docx_第5页
第5页 / 共43页
点击查看更多>>
下载资源
资源描述

vc++游戏编程指南.docx

《vc++游戏编程指南.docx》由会员分享,可在线阅读,更多相关《vc++游戏编程指南.docx(43页珍藏版)》请在冰豆网上搜索。

vc++游戏编程指南.docx

vc++游戏编程指南

第七章我没有想好名字

如果你只靠上面几章所讲述的知识编了个游戏,喜欢的人恐怕会不多☺,为什么?

因为没有人会玩一个控制不流畅而且声音效果不佳的游戏。

为了在游戏中更好地管理各种输入设备,我们需要使用DirectInput。

而通过使用DirectXAudio可以在游戏中实现各种更逼真的音乐效果。

它们都是DirectX的重要组成部分。

使用DirectInput前我们需要#include并在工程中加入dinput8.lib和dxguid.lib,而使用DirectXAudio前我们需要#include并在工程中加入dsound.lib和dxguid.lib。

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

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 初中教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1