77范文网 - 专业文章范例文档资料分享平台

游戏编程文章搜集资料(2)

来源:网络收集 时间:2019-04-13 下载这篇文档 手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:或QQ: 处理(尽可能给您提供完整文档),感谢您的支持与谅解。点击这里给我发消息

g_pDisplay = new CDisplay(); //动态开辟一个CDisplay类

if( FAILED( hr = g_pDisplay->CreateFullScreenDisplay( hWnd, SCREEN_WIDTH,

SCREEN_HEIGHT, SCREEN_BPP ) ) ) /*设置程序为全屏,并且 g_pDisplay 就是动态开辟一个CDisplay类的指针,而在这个类的域中,有一个DirectDraw主表面指针,和一个后备缓冲区表面的指针。在从我建议你可以先去阅读一下 ddutil.h 和 ddutil.cpp 文件。*/ {

MessageBox( hWnd, TEXT(\ TEXT(\ return hr; }

if( FAILED( hr = g_pDisplay->CreatePaletteFromBitmap( &pDDPal, MAKEINTRESOURCE( IDB_DIRECTX ) ) ) ) //顾名思义,就是从bmp图片中获得调色板值,并赋值在pDDPal结构指针所指向的结构体中。 return hr;

if( FAILED( hr = g_pDisplay->SetPalette( pDDPal ) ) ) //用刚才从IDB_DIRECTX中获得的调色板制来设置程序调色板

return hr;

SAFE_RELEASE( pDDPal );//释放指针,在用过后,一定要释放,这是良好的编程习惯 // 用IDB_WINXP图片创建一个表面,并用g_pBackSurface指向这个表面 if( FAILED(

hr

=

g_pDisplay->CreateSurfaceFromBitmap(

&g_pBackSurface,

MAKEINTRESOURCE( IDB_WINXP ),

SCREEN_WIDTH, SCREEN_HEIGHT ) ) )

return hr;//设置色彩键码为黑色,0代表黑色,这样在表面的拷贝过程中黑色像素的点将不会被拷贝,这样可以产生镂空效果。当然你可以任意设置关键颜色,而颜色的表示法可以用 RGB 宏定义。例如 红色:RGB( 255,0,0 ), 黑色 RGB( 255,255,255 ) if( FAILED( hr = g_pBackSurface->SetColorKey( RGB( 255,255,255 ) ) ) ) return hr; return S_OK; }

下面的函数是用于更新画面的。

HRESULT DisplayFrame() {

HRESULT hr;

g_pDisplay->Clear( 0 ); //清空后备缓冲区表面

//将g_pBackSurface所指向的图片拷贝到后备缓冲区表面

g_pDisplay->Blt( 0, 0, g_pBackSurface, NULL );//最关键的地方在这里,请看下面的语句,只要我们一执行翻页操作,就可以将改动了的图像了显示在屏幕上了 if( FAILED( hr = g_pDisplay->Present() /*翻页操作*/) ) return hr; return S_OK;

}

下面的函数是用于在程序失去焦点时调用的。

HRESULT RestoreSurfaces() {

HRESULT hr;

LPDIRECTDRAWPALETTE pDDPal = NULL; /*当程序失去焦点,要保存当前的画面,请注意这里,g_pDisplay->GetDirectDraw()函数返回的才是真正的 DirectDraw 对象 */ if( FAILED( hr = g_pDisplay->GetDirectDraw()->RestoreAllSurfaces() ) ) return hr;//在此我们还要重新创建调色板

if( FAILED( hr = g_pDisplay->CreatePaletteFromBitmap( MAKEINTRESOURCE( IDB_DIRECTX ) ) ) ) return hr;//重新设置调色板

if( FAILED( hr = g_pDisplay->SetPalette( pDDPal ) ) ) return hr;

SAFE_RELEASE( pDDPal );//重新画出图画

if( FAILED( hr = g_pLogoSurface->DrawBitmap( MAKEINTRESOURCE( IDB_WINXP ), SPRITE_DIAMETER, SPRITE_DIAMETER ) ) ) return hr; return S_OK; }

&pDDPal,

下面这个函数是释放表面指针所用的。

VOID FreeDirectDraw() {

SAFE_DELETE( g_pBackSurface ); SAFE_DELETE( g_pDisplay ); }

我们的回顾到此结束,下面我们开始本文要介绍的一个关键技术,DirectInput 的使用。

游戏编程可不仅仅是图形程序的开发工作,实际上包含了许多方面,本文所要讲述的就是关于如何使用 DirectInput 来对键盘编程的问题。

而我们为什么要选择用 DirectInput 来处理游戏中的输入问题呢?其实用 Win32 API 函数也完全可以处理这些工作,例如其中,有一个

GetAsyncKeyState() 的函数可以返回一个指定键的当前状态是按下还是松开。这个函数还能返回该指定键在上次调用 GetAsyncKeyState() 函数以后,是否被按下过。虽然这个函数听上去很不错,但需要我们自己轮换查询每个键盘的状态。而在 DirectInput 中我们已经可以脱离这些烦琐的工作,只因它的功能更强大。

由于本文重点在二者的结合,故在此只介绍 DirectInput 中比较简单的,而且最容易上手的立即模式的工作方式。

而这里我们要用到 DirectInput 的 API 函数。有人会问,为什么在 DirectDraw 中用 DirectX 提供的类库编程,而对于 DirectInput 却直接使用要用其 API 函数呢,是因为没有提供 DirectInput 的类库吗?不是!而是因为使用类库并不很方便而且不灵活。

OK,让我们开始我们游戏编程的第二部——DirectInput编程。

前面讲 DirectDraw 时,并没有提到,微软是按 COM 来设计DirectX的,所以就有了一个 DIRECTINPUT 对象来表示输入设备,而某个具体的设备由

DIRECTINPUTDEVICE 对象来表示。也许会感到很无奈,怎么游戏编程需要这么多的知识啊,其实您也无需烦恼,只要知道一下就可以了,其实这并不;影响您的设计,而且就算您不知道,也同样可以驾驭DIRECTINPUT。

实际的建立过程是先创建一个 DIRECTINPUT 对象,然后在通过此对象的 CreateDevice 方法来创建 DIRECTINPUTDEVICE 对象。

#include

#define DINPUT_BUFFERSIZE 16

LPDIRECTINPUT lpDirectInput; // DirectInput 对象实际上是一个com对象 LPDIRECTINPUTDEVICE lpKeyboard; // DirectInput 设备 BOOL InitDInput(HWND hWnd)

{

HRESULT hr;// 创建一个 DIRECTINPUT 对象

if( FAILED( hr = DirectInputCreate(hInstanceCopy, DIRECTINPUT_VERSION, &lpDirectInput, NULL))) {// 失败提示或处理 return hr;

}// 创建一个 DIRECTINPUTDEVICE 界面

//参数 GUID_SysKeyboard 指明了建立的是键盘对象

if( FAILED( hr = lpDirectInput->CreateDevice(GUID_SysKeyboard, &lpKeyboard, NULL))) {

// 失败提示或处理 return hr;

}// 设定为通过一个 256 字节的数组返回查询状态值

if( FAILED(hr = lpKeyboard->SetDataFormat(&c_dfDIKeyboard))) {

// 失败提示或处理 return hr;

}// 设定协作模式为独占模式和前台模式,独占模式表面本程序在运行中占有所有键盘资源,而前台模式指出当程序具有焦点时才可以占有键盘资源

if( FAILED( hr = lpKeyboard->SetCooperativeLevel(hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND)))

{

// 失败提示或处理 return hr; }

// 设定缓冲区大小

// 如果不设定,缓冲区大小默认值为 0,程序就只能按立即模式工作 // 如果要用缓冲模式工作,必须使缓冲区大小超过 0

// 在此,我们没有必要设定,因为我们就用立即模式工作(还有一种缓冲模式),所有我们将其注调了

/* DIPROPDWORD property;

property.diph.dwSize = sizeof(DIPROPDWORD);

property.diph.dwHeaderSize = sizeof(DIPROPHEADER); property.diph.dwObj = 0;

property.diph.dwHow = DIPH_DEVICE; property.dwData = DINPUT_BUFFERSIZE;

if( FAILED(hr = lpKeyboard->SetProperty(DIPROP_BUFFERSIZE, &property.diph))) {

// 失败

return FALSE; } */

//此处是关键,我们要通过这个函数来锁定键盘,记住,所有的DirectInput资源在使用前都要锁定,在此即获得键盘资源,在知识我们刚才设定的键盘模式才能起作用 hr = lpKeyboard->Acquire(); if FAILED(hr) {

// 失败

return FALSE; }

return TRUE; }

在这段代码中,我们首先定义了 lpDirectInput 和 lpKeyboard 两个指针,前者指向 DIRECTINPUT 对象,后者指向一个

DIRECTINPUTDEVICE 界面。其顺序就是这样的。这和其它COM对象的使用方法都一样,即先创建 COM 对象,然后创建界面,然后再获得 硬件资源,然后使用资源,然后释放。

通过 DirectInputCreate(), 我们为 lpDirectInput 创建了一个 DIRECTINPUT 对象。然后我们调用 CreateDevice 来建立一个DIRECTINPUTDEVICE 界面。

完成这些工作以后,我们便调用 DIRECTINPUTDEVICE 对象的 Acquire 方法来激活对设备的访问权限。在此要特别说明一点,任何一个

DIRECTINPUT 设备,如果未经 Acquire,是无法进行访问的。还有,当系统切换到别的进程时,必须用 Unacquire 方法来释放访问权限,在系统切换回本进程时再调用 Acquire 来重新获得访问权限。 立即模式的数据查询

HRESULT ReadImmediateData( HWND hWnd ) {

HRESULT hr;

BYTE diks[256]; // 创建键盘状态数据缓冲区存取键盘信息 int i; // 计数器

if( NULL == g_pKeyboard )

return S_OK;// 键盘状态数据缓冲区清0

ZeroMemory( &diks, sizeof(diks) );// 获得键盘所有键的信息,这只是检查一次 hr = g_pKeyboard->GetDeviceState( sizeof(diks), &diks ); if( FAILED(hr) )

{

// 如果键盘资源丢失,我们要重新获得 hr = g_pKeyboard->Acquire(); while( hr == DIERR_INPUTLOST ) hr = g_pKeyboard->Acquire(); return S_OK;

}// 进行一下轮循,处理键盘信息。 for( i = 0; i < 256; i++ )

{

if( diks[i] & 0x80 ) //记录此键的状态,低字节最高位是 1 表示按下,0 表示松开,一般用 diks[i]&0x80 来测试 {

switch(i) {

//我们可以通过测试计数器i,来判断是哪个键被按下了。 //我们提供几个数据 UP:200 down:208 left:203 right:205 enter:28 space:57

//其实你可以用DirectX中的Samples\\C++\\DirectInput\\Bin\\Keyboard.exe程序来测试,只不过那是用

//16进制显示的。 case 200: break; case 0xc8: break;

百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库游戏编程文章搜集资料(2)在线全文阅读。

游戏编程文章搜集资料(2).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印 下载失败或者文档不完整,请联系客服人员解决!
本文链接:https://www.77cn.com.cn/wenku/zonghe/585864.html(转载请注明文章来源)
Copyright © 2008-2022 免费范文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ: 邮箱:tiandhx2@hotmail.com
苏ICP备16052595号-18
× 注册会员免费下载(下载后可以自由复制和排版)
注册会员下载
全站内容免费自由复制
注册会员下载
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: