3D多人在线角色扮演游戏毕业论文.doc_第1页
3D多人在线角色扮演游戏毕业论文.doc_第2页
3D多人在线角色扮演游戏毕业论文.doc_第3页
3D多人在线角色扮演游戏毕业论文.doc_第4页
3D多人在线角色扮演游戏毕业论文.doc_第5页
已阅读5页,还剩26页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

毕 业 设 计 报 告课题名称:3D多人在线角色扮演游戏野兽斗兽场摘要本毕业设计的内容是C/S版的野兽斗兽场。C+语言写的客户端和服务端,运用到了微软的DX9.0c 版本的API。大体完成一个可运行的3D游戏框架。在里面实现了游戏地图,角色与角色的行为动作,角色技能,多人PK等等。报告对游戏的内容,游戏的方案,游戏的设计,游戏的难点实现,游戏性能优化的考量。虽然游戏与市面上大多数商业游戏没有可比性,但项目所体现出来的是让本团队了解与学习3D网络游戏开发。在局域网内,这些功能的实现跟广域网相比更加简单,因为局域网的网络结构本身比广域网要复杂。但是又可以借些理解网络协议,以及网络通信实现游戏连网原理,所以任然极具研究价值。目录1. 游戏概览41.1 游戏类型41.2 基本问题41.2.1 这是什么游戏41.2.2 为什么要做这个游戏41.2.3 这个游戏放在哪里运行51.2.4 我怎样控制这个游戏51.2.5 可以控制哪些角色51.2.6 游戏主要焦点是什么51.2.7 与同类游戏有什么不同之处51.3 游戏特征51.4 互联要求61.5 胜利条件61.6 地图生成61.7 VC+开发工具以及DirectX61.8源文件部署62. 游戏方案62.1 游戏功能72.2 技术选型82.3 网络架构93. 游戏详细设计93.1 界面设计93.1.1界面93.2 客户端框架设计133.3 服务端框架设计133.4 类说明133.5 流程图143.5.1 客户端流程图143.5.2 服务端流程图143.6 TCP/TP协议153.6.1 TCP协议介绍153.6.2 TCP连接的建立153.6.3 TCP连接终止163.6.4 TCP提供可靠性的方式163.7 C/S模式以及SOCKET173.7.1 C/S模式173.7.2 P2P模式173.8 可维护性设计184.游戏难点实现184.1 游戏内核的创立184.1.1系统内核184.1.2图形内核194.1.3输入内核244.1.4声音内核244.1.5网络内核244.2 游戏3D渲染实现254.3 游戏角色移动与转向实现254.4 游戏通信实现264.5 游戏消息处理264.6 游戏碰撞检测275. 游戏性能优化275.1 性能考量指标275.2 代码用法优化285.3 通信机制优化285.4 碰撞检测优化285.5 事件处理优化285.6 动画渲染优化295.7优化前后性能比较与分析296. 其他处理296.1 游戏防盗版296.2 游戏防外挂296.3 游戏故障处理296.4 数据传输安全307. 总结307.1做得比较好的方面307.2没有做好,做完,做细,做强的各类功能与问题307.3下一步完善的方向308. 符号或术语汇编319. 参考资料目录311. 游戏概览本游戏是一款多人在线角色扮演3D游戏。游戏提供了多人同时在线PK,以及华丽的技能。1.1 游戏类型3D 渲染摄像角度:Y轴360旋转1.2 基本问题1.2.1 这是什么游戏这是一款有着优美画面与激烈战斗系统的Online Action RPG游戏。作为款半动作游戏,其战斗系统非常简单,通过简单基本的操作,就可以实现KOF般的快感。竞技场自由PK,古战场1080P逼真还原,24小时昼夜更替。1.2.2 为什么要做这个游戏研发这款游戏本着学习的精神,制作这款毕业设计项目。这款游戏是全3D图像渲染,与其他小组和以往学习和制作的作品有所区别。在开发这款游戏就是在不断的学习新D3D技术,和其他同学有所区别其他同学不能做到,而自己能做到。1.2.3 这个游戏放在哪里运行游戏服务端在局域网内或者互联网上运行。此游戏客户端的运行平台windows XP以上系统,直接双击可运行文件exe就可以进入游戏中,但在windows平台中必须安装directx 9.0c版本以上。1.2.4 我怎样控制这个游戏游戏通过WASD四键控制方向,鼠标为辅控制视角。空格键或鼠标左键为普通攻击键,数字1键为技能键。1.2.5 可以控制哪些角色暂时不可选着角色。1.2.6 游戏主要焦点是什么游戏主要的焦点为3D与多人PK。1.2.7 与同类游戏有什么不同之处别公司的同类游戏专为一款开发,而咋们都是东拼西凑而成,几百家之所长,圆自身之短。1.3 游戏特征庞大的游戏世界地图多人同时在线全3D渲染图像32-bit色深多人游戏特征超过10万人的游戏在线简单有趣的一款游戏在简单有趣的庞大游戏世界中找到朋友可以聊天,语音链接最大玩家数目取决服务器的选择,目前测试运行最大玩家数目在20人左右是否可持续游戏世界是不断的可扩展的,不断加入巨大的地图模型进入游戏,就能实现游戏世界持续的。是否可存盘与加载这是一款网络游戏,是绝对不允许玩家自己储存游戏进程。1.4 互联要求游戏采用一套自定义协议传输通信,而不是在网络上传输class内容。客户端与服务器的通信每秒在5KBs之内,普通互联网宽带都能满足要求。1.5 胜利条件玩家如何胜利?服务器一次性容纳所有玩家进入游戏世界,所以的玩家在PK场内互相释放技能对打,不管通过任何手段最后还存在场上的玩家就是胜利者。时间限制游戏中不针对时间作为限制。游戏玩家在内互相殴斗,死亡率以倍数的消失。1.6 地图生成游戏地图使用网格制作,使用.x文件的高度图,加入雾化效果,环境光,地面材质,加以沙漠纹理贴图,并对纹理设置纹理和寻址模式,让地形的高度比较平滑,真实,地图大小为256*256。天空制作使用Mesh技术,制作一个固定大小的天空盒。Mesh需要设置子集和属性缓存,绘制天空盒子的Mesh需要绘制所有的子集,并用相对应的材质和纹理数组进行循环渲染,每个子集项与纹理数组相对应的项必须一一对应。1.7 VC+开发工具以及DirectXVisual C+是Microsoft公司提供的在Windows环境下进行应用程序开发的C/C+编译器。相比其他的编程工具而言,VisualC+在听过可视化的编程方法的同时,也适用与编写直接对系统进行底层操作的程序。随Visual C+一起提供的Microsoft多媒体类库(Microsoft Direct eXtension)对Windows 9x / NT所用的win32多媒体程序接口进行了十分彻底的封装,这使得Windows 9x / NT多媒体程序的开发可以使用完全面向对象的方法进行,从而能够大量地节省程序的开发周期,降低开发成本,也使得Windows游戏开发程序员从大量的复杂劳动中解脱出来,而且获得这重方便是不需要在对市面上所有的显卡进行编辑。1.8源文件部署1 安装VC+6.02 安装 directx sdk3 打开VC+6.0 工具-选项-目录4 选择include file 把directx sdk include目录导入选着 library file 把 directx sdk LIB目录导入2. 游戏方案2.1 游戏功能客户端:功能1 场景地图硬盘加载功能2 角色模型加载功能3 角色动画生成功能4 三维视角的世界观,体现真实游戏画面功能5 角色技能,华丽而又优美.服务端:功能1 网络通信,数据的交换功能2 数据分发到连接上的客户端功能3 数据分析,分析与处理不同ID的数据功能4 判断游戏进行所产生的逻辑问题2.2 技术选型 2.3 网络架构3. 游戏详细设计3.1 界面设计3.1.1界面界面图启动服务端启动客户端服务端监控客户端对战区域描述:区域1:主界面是一个3D视角的区域区域2:主界面中间是玩家的角色所在位置操作说明:(1)Mouse点击左键或者按下空格键,为角色普通攻击(2)Mouse移动改变摄像机的视角(3)键盘W键为角色正面前进(4)键盘S键为角色后面倒退(5)键盘A键为角色左移动(6)键盘D键为角色右移动(7)键盘1键为角色技能释放控制键界面交互图3.2 客户端框架设计3.3 服务端框架设计3.4 类说明类说明cApp主类,包含了进入游戏,渲染游戏,添加网格对象等cClient客户端类继承与cNetworkClientcFrustum检查多维数据集或矩形CNodeTreeMesh树节点,包含一些对象3D坐标sCreatePlayerMessage创建一个玩家消息sDestroyPlayerMessage摧毁一个玩家消息sMessage消息队列中的消息结构sMessageHeader在所有的消息中使用的消息头结构sPlayer玩家类里面包含玩家的属性sRequestPlayerInfoMessage请求玩家参考消息sStateChangeMessage状态信息的变化3.5 流程图3.5.1 客户端流程图3.5.2 服务端流程图3.6 TCP/TP协议3.6.1 TCP协议介绍TCP传输控制协议。TCP是一种面向连接的、可靠的、基于字节流的传输层通信协议,在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能。在因特网协议族中TCP层是位于IP层之上,应用层之下的中间层,不通主机的应用层之间经常需要可靠的、像管道一样的连接,但是IP层不提供这样的流机制,而是提供不可靠的包交换、TCP所提供的服务的主要特点:(1) 面向连接的传输(2) 端到端的通信(3) 高可靠性,确保传输数据的正确性,不出现丢失或乱序(4) 全双工方式传输(5) 采用字节流方式,即以字节为单位传输字节序列(6) 紧急数据传送功能3.6.2 TCP连接的建立TCP协议通过桑报文段完成连接的建立,这个过程成为三次握手,过程如下图所示,其中isn为初始序号3.6.3 TCP连接终止建立一个连接需要三次握手,而终止一个连接要经过四次握手,这是由TCP的半关闭造成的。具体过程如下图所示。3.6.4 TCP提供可靠性的方式应用数据被分割成TCP认为最合适发送的数据块。这和UDP完全不同,应用程序产生的数据包长度保持不变,由TCP传递给IP的信息单位称为报文段或段TCP如何确定报文段的长度。当TCP发生一个段后,它启动一个定时器,等待目的端确认收到这个报文段,如果在不能即时收到一个确认,将重发这个报文段。当TCP收到发自TCP连接另一端的数据,它将发送一个确认。这个确认不是立即发送,通常将推迟几分之一秒。TCP将保持它首部和数据的检验和。这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到的端的检验和有差错,TCP将丢弃这个报文段和不确认收到此报文段。既然TCP报文段作为IP数据报来传输,而IP数据包的到达可能会失序,因此TCP报文段的到达也可能会失序。如果必要,TCP将对收到的数据进行重新排序,将收到的数据以正确的顺序交给应用层。既然IP数据报会发生重复,TCO的接收端必须丢弃重复的数据。TCP还能提供流量控制。TCP连接的每一方都有一个固定大小的缓冲空间。TCP的接收端只允许另一端大宋接收端缓冲区所能接纳的数据,这将防止较快主机导致较慢主机的缓冲区溢出。3.7 C/S模式以及SOCKET3.7.1 C/S模式C/S(client/server)模式。它是软件系统体系结构,通过Client端和Server端的分配完成指定任务。C/S模式也是当前游戏程序中很流行的一种方式。油漆是网络技术的发展,使得当前很多系统都采用这种方式进行构造,其最大的优点是将计算机工作任务分别由客户端呵呵服务端来共同完成,这样有利于充分合理的利用系统资源。另外它的服务器端还可以将信息集中起来,任何客户机都可以通过访问服务器而获得所需的信息。Clinet/Server 模型最终可归结为一种“请求/应答”关系。一个请求总是首先被客户发出,然后服务器总是被动地接受请求,返回客户需要的结果。在客户发出一个请求之前,服务器进程一直处于休眠状态。一个客户提出请求后,服务进程被“唤醒”并且创立线程为用户提供服务(但也有使用线程池,而不需要创立),对客户的请求做出所需应答,如图所示。3.7.2 P2P模式P2P作为一种点对点通信模式,它有别于传统的C/S模式。传统的C/S模式一般都有预定义的客户端和服务器。而在P2P模式转并没有明确的客户端和服务器,但其实在P2P模型中每一台计算机都可以是服务器,也可以看成是客户机。在网络中,传统上的客户机/服务器通信模式中,发送服务请求或接收数据的计算机成为服务器。而在P2P网络模式中,计算机不仅接收数据,还有发送数据,不仅提出服务请求,还有接收对方的服务请求。3.8 可维护性设计通过充分应用面向对象设计原则,代码具有较强的可维护性。满足原则1:DRY(Dont repeat yourself)。即不要写重复的代码,而是用“GameCore”库来抽象公有的东西。通过对世界坐标系、IDirect3D9初始化、灯光等功能进行包装,较好地实现了该目标。满足原则2、3:封装变化、开闭原则。服务端的简单工厂设计模式使用,对扩展开放,对修改关闭,详情见3.8。可以在不修改原有的模块的基础上,扩展功能,其灵活性使得之后引进新代码不会对现有的代码造成影响。符合开闭原则、封装变化的宗旨。满足原则4:单一职责原则。项目的客户端类数目接近40个,从静态类图可知,除“游戏视图类”这个核心类外,其它类相互关联非常简洁明了。这种专注于单一的功能的设计,使类被修改的几率变小。“游戏视图类”因为将多个功能放在同一个类中,功能之间就形成了关联,改变其中一个功能,有可能中止另一个功能,需要新一轮的改进来避免可能出现的问题。满足原则5:优先利用组合而非继承。以上静态类图表明所有类继承层次不超过三层。如果可能的话,该设计还可以更加优先利用组合而不是继承,可进一步改进。组合允许在运行期间通过设置类的属性来改变类的行为,也可以通过使用接口来组合一个类,它提供了更高的灵活性,并可以随时实现。满足原则6:接口分离原则。针对世界坐标系、IDirect3D9初始化、灯光等功能,设计独立出 “core_Graphics类”、“cWorldPosition”、“cLight类”接口,避免应用限入具体细节。4.游戏难点实现游戏的难点有以下几点:1. 使用directx 3D 中的渲染2. 游戏与服务器的网络通信3. 区分系统消息和玩家消息4. 游戏的碰撞检测5. 三维世界中的世界矩阵变换6. 三维网格动画设置7. 键盘输入设备的创立4.1 游戏内核的创立游戏内核是用来简化DirectX和windows编程的一些库的集合。游戏内核几乎含有一个游戏工程需要的所有函数,这些函数一般用于绘制图像、播放声音、处理用户输入以及处理应用程序的处理过程。也就是说,使用游戏内核,就无需在每次开始一个新的游戏工程时,再去处理底层DirectX或Windows代码。4.1.1系统内核用于处理Windows处理过程,包括注册窗口类,创建应用程序窗口以及处理进程、状态和数据包。使用cApplication核心对象:cApplication是系统内核中最有用的核心对象,它可以用于创建应用程序的窗口和控制程序流。此对象能够注册窗口类、创建应用程序窗口以及进入处理应用程序窗口消息的消息泵,并且在适当的时候调用内部的类函数。cApplication通过调用重载函数:Init、Shutdown和Frame来处理应用程序。使用cStateManager处理状态:当创建游戏时,就能发现cStateManager要比游戏程序流的功能强很多。新的状态管理引入了两个概念:调用目的以及添加一个用户自定义的数据指针,此指针指向cStateManager中的函数。进程和cProcessManager栈上的每一个函数在每帧都要被调用,除了这点小的不同以外,cProcessManager和cStateManager非常相。cStateManager一样,新的cProcessManager也在cProcessManager的基础上加入了调用目的以及一个用户自定义的指针。cProcessManager的类声明同cStateManage的类声明类似,因此可以直接跳到后面使用cProcessManager的例子。使用cDataPackage管理数据:通过加入两个函数来对创建的数据包管理器进行修改,这两个函数分别用于返回数据缓冲区的大小以及指向数据缓冲区的指针。4.1.2图形内核用于绘制图形。使用诸如动画网格之类的3D方法渲染场景。类说明cCraphics处理Direct3D的初始化,启用状态渲染以及设置纹理、材质和光照cTexture含有一个纹理以及一个用于将纹理的2-D部分绘制到显示器上的函数cMaterial含有一个材质的定义cLight包含一个光照的定义cFont封装了ID3DXFont对象cVertexBuffer使对顶点缓冲的处理变得更容易cWorldPosition操纵世界变换矩阵,使程序员能够快速定位、缩放和旋转对象cCamera包含一个观察变换矩阵,可以使用对象的接口修改此矩阵cMesh包含一个.X文件加载的网格的列表以及这些网格的材质。cMesh类要同cObject类结合起来使用cObject表示3-D世界中的一个对象。cObject类控制了对象的方位、网格以及动画状态cAnimation包含一个.X文件加载的动画列表。cAnimation类要同cObject类结合起来图形系统和cCraphics:cCraphics用于设置显示模式和渲染状态以及清除设备等等。一旦初始化了cCraphics对象,就能够同几乎所有图形内核的类组件结合起来使用。如果没有使用Z缓冲,就不要调用Clear函数,而要使用ClearDisplay函数,因为Clear函数需要一个Z缓冲值。cGraphics部分代码如下: BOOL SetPerspective(float FOV=D3DX_PI / 4.0f, float Aspect=1.3333f, float Near=1.0f, float Far=10000.0f); BOOL SetWorldPosition(cWorldPosition *WorldPos); BOOL SetCamera(cCamera *Camera); BOOL SetLight(long Num, cLight *Light); BOOL SetMaterial(cMaterial *Material); BOOL SetTexture(short Num, cTexture *Texture); BOOL SetAmbientLight(char Red, char Green, char Blue);图像和cTexture:纹理使3-D看起来更加货真价实。使用全彩色成像可以使简单的多边形显得更逼真。cTextre部分代码如下: BOOL Free(); / 空闲的纹理对象 BOOL IsLoaded(); / 返回TRUE,如果加载纹理 long GetWidth(); / 返回宽度(间距)的纹理 long GetHeight(); / 返回高度(间距)的纹理 D3DFORMAT GetFormat(); /返回纹理存储格式颜色和cMaterial:通过改变绘制表面的颜色值,就可以改变渲染对象的外观。cMaterial部分代码如下: BOOL SetDiffuseColor(char Red, char Green, char Blue); BOOL GetDiffuseColor(char *Red, char *Green, char *Blue); BOOL SetAmbientColor(char Red, char Green, char Blue); BOOL GetAmbientColor(char *Red, char *Green, char *Blue); BOOL SetSpecularColor(char Red, char Green, char Blue); BOOL GetSpecularColor(char *Red, char *Green, char *Blue); BOOL SetEmissiveColor(char Red, char Green, char Blue); BOOL GetEmissiveColor(char *Red, char *Green, char *Blue);使用cLight:cLight处理光照光照同材质一样简单。使用光照可以通过很多方式实现很多效果。cLight部分代码如下:/ /设置一个默认的光点 ZeroMemory(&m_Light, sizeof(D3DLIGHT9); SetType(D3DLIGHT_POINT); Move(0.0f, 0.0f, 0.0f); SetDiffuseColor(255,255,255); SetAmbientColor(255,255,255); SetRange(1000.0f); SetAttenuation0(1.0f);使用cFont:cFont处理文本和字体虽然ID3DXFont对象处理起来比较容易,但是设置字体却让人痛苦不堪。不要紧,使用cFont类就能快速并容易地得到字体。cFont部分代码如下:BOOL cFont:Create(cGraphics *Graphics, char *Name, long Size, BOOL Bold, BOOL Italic, BOOL Underline, BOOL Strikeout)LOGFONT lf;if(Graphics = NULL | Name = NULL)return FALSE; if(Graphics-GetDeviceCOM() = NULL)return FALSE; / 清除字体结构 ZeroMemory(&lf, sizeof(LOGFONT); / 设置字体名称和高度 strcpy(lf.lfFaceName, Name); lf.lfHeight = -Size; lf.lfWeight = (Bold = TRUE) ? 700 : 0; lf.lfItalic = Italic; lf.lfUnderline = Underline; lf.lfStrikeOut = Strikeout; / 创建的字体对象 if(FAILED(D3DXCreateFontIndirect(Graphics-GetDeviceCOM(),&lf, &m_Font)return FALSE; return TRUE;定点和cVertexBuffer:顶点是个麻烦的东西,有时对它束手无策。通过提供一种快速创建、设置以及渲染顶点集合的方法,cVertexBuffer类能够减少次烦恼。cVertexBuffer部分代码如下:世界变换和cWorldPosition:虽然处理世界变换矩阵并不难,但使用一个类来处理诸如世界坐标、旋转值以及缩放因子等所有细,就更简单明了。cWorldPosition部分代码如下:/移动世界矩阵BOOL cWorldPosition:MoveRel(float XAdd, float YAdd, float ZAdd)return Move(m_XPos + XAdd, m_YPos + YAdd, m_ZPos + ZAdd);/旋转世界矩阵BOOL cWorldPosition:Rotate(float XRot, float YRot, float ZRot)m_XRotation = XRot;m_YRotation = YRot;m_ZRotation = ZRot; D3DXMatrixRotationYawPitchRoll(&m_matRotation, m_YRotation, m_XRotation, m_ZRotation);return TRUE;观察变换和cCamera:cCamera类和cWorldPosition类非常类似,但cCam类处理的是观察变换矩阵。cCamera部分代码如下:BOOL cCamera:MoveRel(float XAdd, float YAdd, float ZAdd) return Move(m_XPos + XAdd, m_YPos + YAdd, m_ZPos + ZAdd);/移动摄像机方法BOOL cCamera:Rotate(float XRot, float YRot, float ZRot) D3DXMATRIX matXRotation, matYRotation, matZRotation; m_XRot = XRot; m_YRot = YRot; m_ZRot = ZRot; D3DXMatrixRotationX(&matXRotation, -m_XRot); D3DXMatrixRotationY(&matYRotation, -m_YRot); D3DXMatrixRotationZ(&matZRotation, -m_ZRot); m_matRotation = matZRotation; D3DXMatrixMultiply(&m_matRotation, &m_matRotation, &matYRotation); D3DXMatrixMultiply(&m_matRotation, &m_matRotation, &matXRotation); return TRUE;/旋转摄像机方法使用cMesh加载可加载的网络:处理网格很难。当然,这里除了要讲述蒙皮网格外,还要讲述标准网格。cMesh部分代码如下:BOOL cMesh:Load(cGraphics *Graphics, char *Filename, char *TexturePath)/ 创建的文件对象 if(FAILED(DirectXFileCreate(&pDXFile) return FALSE; / 注册模板 if(FAILED(pDXFile-RegisterTemplates(LPVOID)D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES) pDXFile-Release(); return FALSE; / 创建一个枚举对象if(FAILED(pDXFile-CreateEnumObject(LPVOID)FilenameDXFILELOAD_FROMFILE, &pDXEnum) pDXFile-Release();return FALSE;使用cObject绘制对象:要绘制网格,必须在网格定义和显示器之间搭设一道桥梁。为什么不使用cMesh对象处理渲染呢?原因在于内存使用(memory usage)。如果要反复使用相同的网络,该怎么办?cObject部分代码如下:BOOL EnableBillboard(BOOL Enable = TRUE);BOOL AttachToObject(cObject *Object, char *FrameName = NULL);BOOL Move(float XPos, float YPos, float ZPos);BOOL MoveRel(float XAdd, float YAdd, float ZAdd);BOOL Rotate(float XRot, float YRot, float ZRot);BOOL RotateRel(float XAdd, float YAdd, float ZAdd);BOOL Scale(float XScale, float YScale, float ZScale);BOOL ScaleRel(float XAdd, float YAdd, float ZAdd);使用cAnimation移动网格:cAnimation类是网格动画组件,也是图形内核的最后一个类。使用cAnimation,就能够从.X文件加载一连串动画集,把它们同cObject结合起来创建网格动画。cAnimation部分代码如下:/添加网格对象BOOL Load(char *Filename, cMesh *MapMesh = NULL);BOOL Free();BOOL MapToMesh(cMesh *Mesh);/设置动画BOOL SetLoop(BOOL ToLoop, char *Name = NULL);4.1.3输入内核处理来自键盘、鼠标和游戏杆的用户输入。使用cInput初始化DirectInput:使用输入系统的第一步就是初始化DirectInput,这也是cInput类的用途。输入设备和cInputDevice类是输入内核种真正起作用的类。cInputDevice类用于初始化一种特定的输入设备(键盘、鼠标或游戏杆),并提供一种取得游戏使用的设备信息的方法。使用输入内核使用起来比较容易,只要实例化一个cInput类对象及多个cInputDevice类对象即可,但是要记得在使用之前,初始化各个cInputDevice类对象。4.1.4声音内核让用户享受多声道的声音和音乐。此内核能够改变乐器声音并带来独特的音乐感受。游戏声音游戏中未实现,类图不上。4.1.5网络内核此内核用于讲客户端连接到Internet以及一些大型的在线服务器。使用此内核,就能够畅游网络。使用cNetworkAdapter查询网络配适器:cNetworkAdapter类用于枚举系统上安装了TCP/IP设备。为了同客户端建立连接,必须知道设备的GUID,这正是cNetworkAdapter类的用途。使用cNetowrkServer处理服务器:处理网络服务器端,需要使用cNetowrkServer类,这个类用于初始化DirectPlay服务器对象、主持游戏回话,处理收到和发送的网络消息。使用cNetworkClient处理客户端:cNetworkClient,它用于处理网络的客户端,cNetworkClient对象的使用方法同cNetworkServer对象的使用方法相似,但是有一点不同,那就是连接到网络的方法。要使用cNetworkClient:Connect建立连接,首先必须使用cNetworkAdapter类对象选出一个网络配适器。 4.2 游戏3D渲染实现图形渲染cGraphics类,cGraphics用于设置显示模式和渲染状态以及清楚设备等等。一旦初始化了cGraphics对象,就能够同几乎所有图形内核的类组件结合起来使用。首先要调用Init,然后就可以枚举各种显示模式或调用SetMode最少只需要一个父窗口的句柄。缺省情况下,显示模式被设置成使用不带Z换成区的窗口镜像输出。要设置和启用光照,需要调用EnableLighting函数。Alpha混合能够带来奇妙的效果,而且还允许程序员指定精确的混合值。在cTexture类能够从磁盘上的一幅图像文件或现有的IDirect3DTexhure9对象加载纹理。在3D渲染中如果不使用灯光,那么屏幕上一切都是黑色的。光照同材质一样简单。使用光照可以通过很多方式实现很多效果,基于这个原因,这里就讲有关光照的一切都汇总到一个名为cLight的类中。需要实力cLight类,然后挑选一种要使用的光源类型设置光源的颜色,并将光源置于任何适当的位置。经过以上的准备,就可以使用Render函数渲染多边形了。实现代码如下: m_Graphics.SetCamera(&m_Camera); Frustum.Construct(&m_Graphics); m_Playersi.Body.UpdateAnimation(timeGetTime()/32,TRUE); m_Playersi.Body.Render();4.3 游戏角色移动与转向实现角色的移动需要cWorldPosition类,计算世界变换矩阵。虽然处理世界变换矩阵并不难,但是用一个类来处理诸如世界坐标、旋转值以及缩放因子等所有细节,就更简单明了。GetMatrix函数返回当前的世界变换矩阵。确保传递给GetMatrix函数的是当前正在用来计算矩阵,用矩阵的值改变角色的移动。观察变换矩阵,用cCamera类实现。它与cWorldPosition类非常类似。它同cWorldPosition类唯一的不同就是加上了Point SetStartTrack SetEndTrack以及Track函数。Point函数用来确定观察点的方位并在瞬间将它指向一个特定的方向。3个同追踪有关的函数随着时间追踪摄像机的移动路径。要使用摄像机追踪方位。实现代码如下:m_Playersi.Body.Move(m_Playersi.XPos, m_Playersi.YPos,m_Playersi.ZPos);m_Playersi.Body.Rotate(0.0f, m_Playersi.Direction,0.0f);4.4 游戏通信实现服务端的创建:用Socket()函数来创建一个在通信中使用的套接字,然后调用bind(),将套接字描述符和一个指针传递给一个地址结构 &DPN_APPLICATION_DESC,同时也传递地址结构的长度。我们已经创建套接字,并且赋给了它一个地址,现在我们需要有一种方式来建立客户端的连接,为了做的哦啊这一点我们需要使用listen()函数,它告诉套接字开始侦听客户端的连接请求。一旦将套接字设置成了侦听连接,实际的连接就可以由accept()函数来完成。如果连接被成功地接收,accept()函数将返回一个新的套接字描述符,这个新的套接字将用来处理新的连接;如果这里出现了一个错误,accept()函数将返回INVALID_SOCKOET,这时我们需要调用WSAGetLastError()以得到更多的有关错误的细节。原来的套接字将继续侦听新的连接请求,而新的请求可以通过accept()函数的再一次笤俑而获得接受。客户端的创建:客户端的创建比较简单,首先创建一个空的套接字,然后调用connect()函数向服务端发起一个请求,但是我们必须有服务端的IP,不然我们就无法进行连接,完成这些后我们就可以进行和服务端的通信。4.5 游戏消息处理要实现消息处理,必须创建消息处理回调函数。该函数非常简单,它仅仅需要区分接收到的是哪一种消息,并尽可能快地处理消息。可以将消息处理函数想象成一个漏斗,如图所示。每一个网络对象都需要知道一些要主持或要加入的会话的信息。这些信息包含在一个个体结构中:ty pedef struc_DPN_APPLICATION_DESC DWORO dwSize; /结构体的大小 DWORO dwFlags; /会话标志 GUID guidlnstance; /NULL GUID guidApplication; /设置应用程序 GUID DWORD dwMaxPlayers; /设置允许的最大玩家数DWORD dwCurrentPlayers; /当前玩家数WCHAR *pwszSessionName; /会话名称WCHAR *pwszPassword; /会话密码(如果有的话)PVOID pvReservedData; /未使用DWORD dwReservedDataSize; /未使用PVOID pvApplicationReservedData; /NULLDWORD dwApplicationReservedDataSize; /0 DPN_APPLICATION_DESC;前面讲述过,并不需要DPN_APPLICATION_DESC结构体中的所有信息。4.6 游戏碰撞检测在游戏中,大多数角色并不是超级英雄,所以他们并不能穿透墙壁。出于这个原因,在角色发生与物体(如一堵墙)碰撞前三维引擎需要知道何时该堵塞角色的道路。为了检测一个多边形是否堵塞了节点之间的道路,可以在两个点之间“发射”出一条想象中的射线,以检测它是否与一个平面相交。应为平面是无穷大的,所以一条射线只要他不是平行于平面的,总是能够与平面相交。出于这个原因,必须告之相交点是否位于多边形的边缘之内,而完成之一点有点难度。该D3DX登场了!有一个功能函数负责执行交集的测试,以确保射线与平面的相交点是位于多边形里的,并给出那个相交点的确切坐标,同时,显示从射线的开始点到相交点的距离长度。他是一个非常有用的功能函数。他是cNodeTreeMesh:CheckIntersect函数实现代码如下: D3DXVec3Normalize(&vecDir, &D3DXVECTOR3(XDiff, YDiff, ZDiff); D3DXIntersect(m_Mesh-m_Mesh,&D3DXVECTOR3(XStart,YStart,ZStart), &vecDir, &Hit, &FaceIndex, &u, &v, &Dist, NULL, NULL); if(Hit = TRUE) Size = (float)sqrt(XDiff*XDiff+YDiff*YDiff+ZDiff*ZDiff); if(Dist Size) Hit = FALSE; else if(Length != NULL) *Length = Dist; 5. 游戏性能优化5.1 性能考量指标服务器的性能指标考量,是通过是否能容纳最大用户500人最大在线。服务器是否能进行150人线同时PK考量。服务器是否能通过平均在线300人承受。客户日方面的性能指标考量,客户端在进行大规模PK战斗时候是否会出现位置bug,在进行大规模渲染时是否会造成客户端软件或者系统崩溃重新启动。5.2 代码用法优化在进行优化之前,我们首先应该做的是发现我们代码的瓶颈在哪里。然后当你做了这件事情的时候切忌从debug-version进行推断,因为debug-version中包含了许多额外的代码。一个debug-version可执行体要比release-version大出40%。那些额外的代码都是用来支持调试的。程序中变量和对象的声明放在什么位置将会对性能产生显著影响。同样,对postfix和prefix运算符的选择也会影响性能。这一部分我们集中讨论四个问题:初始化v.s 赋值,在程序确实要使用的地方放置声明,构造函数的初始化列表,prefix v.s postfix运算符。在C+中声明可以出现在程序的任何位置。这样做的目的是希望把对象的声明拖延到确实要使用它的时候再进行。这样做可以有两个好处:1. 确保了对象在它被使用前不会被程序的其他部分恶意修改。如果对象在开头就被声明然而却在20行以后才被使用的话,就不能做这样的保证。2. 使我们有机会通过用初始化取代赋值来达到性能的提升,从前声明只能放在开头,然而往往开始的时候我们还没有获得我们想要的值,因此初始化所带来的好处就无法被应用。但是现在我们可以在我们获得了想要的值的时候直接进行初始化,从而省去了一步。5.3 通信机制优化该实现由于是多个客户端与服务端使用网络通迅,因此数据包装定义采用了类似windows的消息机制,这种通行对于流量来说比较少能提高服务端的压力,而客户端不易出现延时情况。优化可以收集完用客户端事件需要同步的所有数据储存在缓冲中一般大小设置4K,再统一包装一次发送,而不是任何一个游戏对象的状态改变了,就立即更新的方式,大大降低通迅频率提高客户端与服务端的时时通信效率。5.4 碰撞检测优化为了优化CheckSphereIntersect功能函数,可以在功能函数调用的代码中不使用sqrt,而是自己编写函数,计算两者间距离公式 距离 = X*X+Y*Y+Z*Z,然后计算球半径距离公式 球半径= (Radius1 + Radius2)*( Radius1 + Radius2)*3.0 最后在判断两者。如下代码:Distance = XDiff*XDiff + YDiff*YDiff + ZDiff*ZDiff;Float RadiuseDistance = (Radius1 +

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论