转:http://school.ogdev.net/ArticleShow.asp?id=6638&categoryid=3
人物移动控制是单机和网游中比较重要的部分,但前单机游戏使用动力学以及IK动画等已经达到了非常逼真的地步,在大型网络游戏中这样的物理模拟同步是很实现的,因此在目前多数网游中仍旧是采取使用一个包围体(盒子或者胶囊)来模拟人物。一个好的移动系统是很重要的,平滑的贴墙滑动以及下滑,跳跃等会带给玩家顺畅的手感否则则会有种奇怪的感觉,本文具体介绍了一下碰撞反应,包括贴墙滑动等的具体实现细节。包括一个demo实例 。
目前物理引擎里面大多自带独立于刚体的人物角色控制,但是物理引擎需要特定的物理模型命名以及比较大的物理模拟开销度。如果需要定制自己的特别功能或者需要简化计算(同时模拟多个延迟或者玩家的反应)。就必须自己完成人物碰撞反应控制的代码。
要完成人物发生碰撞以后的行为控制,需要碰撞检测系统提供以下的碰撞信息,对于每一个碰撞:
1. 碰撞发生的时间
2. 碰撞的法向量
3. 碰撞点
对于基本的人物碰撞控制反应来说,以上3点是必须的,有时还需要提供和包围体发生碰撞的具体三角形信息。
对于场景上的物体首先使用胶囊所在的包围盒AABB或者OBB和场景中的碰撞体包围盒作层次碰撞裁减,至于具体怎么组织可以任意,比如可以采用AABB或者OBB树,也可以采用简单的球树。但碰撞进行到树的叶子节点后开始检测人物的AABB盒和该AABB盒所包围的OBJECT的碰撞情况。如果发现这2个AABB(OBB)盒将会发生碰撞,那么开始使用人物的胶囊体和景物所带的三角面片进行精确到polygon soup级别的比较。这时候仍旧可以优化,比如说我还做了一步把一个Object中的三角形面片打成BSP树的形式存储起来,这样可以大大减少胶囊和三角形碰撞检测的次数,因为这种动态检测是十分耗时的。有关胶囊和三角形面片的比较可以参考:http://dev.gameres.com/Program/Abstract/Arithmetic/capsule.mht中的方法。 对于BSP的划分以及AABB碰撞检测就不用多说了~到处都可以找到文章。
对于地形而言,也是采用同样的方法,只不过对于地形而言三角形信息不用额外存储,只需要使用和渲染相同的三角形(对于景物来说一般不会使用渲染用的三角形而会使用更加简化数量更少的简化网格碰撞模型)。这里可以有很多优化的技巧,因为地形本身是规则的cell一个地形是由若干个patch(一般是16X16)组成的,而每个patch是由若干cell(一般是16X16)组成的。对于patch来说一般已经组织到了一颗QUADTREE中了因为视棱锥裁减也需要这种结构,因此碰撞检测中的AABB-AABB阶段使用这颗已经存在的QUADTREE就可以快速的完成层次碰撞检测了。但发现某个patch中的AABB和人物的AABB发生碰撞后需要检测每一个CELL所在的AABB和人物AABB盒的碰撞,这里可以使用点小技巧比如说首先将AABB盒投影到CELL所在的XY平面上,找出被投影覆盖的那些CELL然后再检测这些CELL的AABB盒是否和人物的发生碰撞。一但确定了某个CELL和人物发生碰撞那么就可以将该CELL中的三角形取出(一般为2个)依次和人物所在的胶囊进行三角形-胶囊的碰撞检测。
这样当碰撞检测系统完成任务以后我们将会获得一个碰撞信息的数组:
class CollideInFo{
public:
GFVECTOR_3D m_worldcdnorm;//碰撞法向量
GFPOINT_3D m_worldpoint;//碰撞点
float m_cdtime;//碰撞时间
};
CollideInFo collidearray[];
然后使用这个数组就可以进行碰撞后的处理了包括,沿墙滑动下滑等等。在具体说明整个人物移动控制算法之前,首先说下动态碰撞检测和静态碰撞检测的区别,动态碰撞检测是指物体A以速度V前进了T时间,在这期间第一次和物体B发生碰撞的时间。这样的碰撞检测必须返回第一次2个物体发生碰撞的时间。而静态检测是指2个不动的物体是否互相相交对于这种检测是不需要返回时间的。动态检测算法比静态的复杂而且也耗用更多的时间。一个完善的碰撞系统需要解决以上2种碰撞检测,如果你不想自己写检测代码,目前比较流行的有OPCODE,SOLID库等检测库 。你可以直接使用他们提供的功能,这里我采用的是自己写检测代码的方法,目前只用到三角形-胶囊,AABB-AABB,OBB-OBB的碰撞检测。 [Page]
完成了包围体(用的是胶囊)和三角形的碰撞,胶囊和BSP,地形的碰撞检测之后,拥有了碰撞的信息 1。碰撞时间。2。碰撞法向量。3。碰撞点。接着就可以处理人物在碰撞后的反应了。
首先人物的一次移动分2个阶段,第一个是初始阶段,使用静态碰撞检测获得该阶段的速度(具体做法在后面说)。第2阶段使用该速度去做动态碰撞检测得到碰撞信息,根据这些碰撞信息去处理碰撞后的反应。
先来看第一阶段,过程对于一个胶囊我们需要获取他周围的临近面片的信息,以决定这个胶囊目前所处平面的倾斜度,是否贴着不可通过的墙等等。我采用的方法是将胶囊体略为膨胀一些,然后调用静态碰撞检测的代码获取和该膨胀后的胶囊体相交的三角形面片碰撞信息如图:
棕色的是原始的胶囊体,红色的表示将胶囊半径略为增加以后的胶囊体,蓝色的2个地形是将胶囊膨胀以后所发生相交的2个三角形,而如果不采用膨胀的话该胶囊是不和任何三角形相交的,具体膨胀数值可以设为胶囊下落的最小高度,比如你设定胶囊离底部物体超过0.6单位属于腾空状态的话你就将膨胀数值设为0.6。在这个例子中我们将会检测到2个碰撞(蓝色部分)这2个碰撞法向量正好是这2个三角面的法向量(在很多情况下也可能不是这个看你的碰撞代码中法向量是如何计算的了)。其中底部的那个是可行走平面,另外一个是不可行走平面,有了这2个碰撞平面就很简单了,如果用户输入的速度和那个不可行走的平面相反(也就是撞向那个不可行走平面),那么那个不可行走平面是有效的,这样他和底部那个可行走的平面所组成的交线就是人物的初始速度,如果用户输入的速度和那个不可行走的平面法向量相同,那么这个不可行走平面没有作用人物最终的速度就是把用户速度投影到该可行走平面上的速度。
0顶一下
具体计算是否能够水平移动以及移动速度的算法:当给出M个不可行走平面和N个可行走平面时:
1首先将速度在N个可行走平面上分解,检查这些分解的速度是否有效(如何判断速度有效下面会说道)
2如果在1的时候存在一个有效的速度直接返回该速度
3没有有效速度,这时检查NXM个平面的交线,将速度在上面分解同时检查是否存在有效速度
4如果存在有效速度返回该速度
5否则检查MXM条交线的,将速度在上面分解同时检查是否存在有效速度
6如果存在有效速度返回该速度
7否则返回0速度
那么如何判定速度是否有效呢,首先我们知道了所有碰撞的信息,给定一个速度,如果该速度和所有碰撞的法向量的夹角都是小于90度那么这就是个有效速度,(说明该分解后速度不会引起和这些碰撞面的在一次碰撞,因为该速度是将物体拉下远离该平面的方向的)。如果只要有一个夹角大于90度那么该速度就是非有效速度,同时在移动时还要判断该速度的倾斜角是否大于最大下滑倾斜角。注意 5是很重要的因为2个不可行走的平面所形成的交线仍旧可能是可以行走的,甚至是水平的。
以上的部分是检查是否能够水平移动的,如果不能水平移动那么该物体会下滑,1如果没有检测到碰撞平面说明物体处于腾空状态,这时候给物体加上重力加速度,产生一个往下的速度和原来的水平速度结合起来(如果存在)。
如图棕色是原始状态胶囊经过上一帧移动后到达蓝色的位置这时通过上诉算法可以检测到胶囊腾空,这时他的速度为水平速度(红色)+下滑速度(绿色)。
2如果检测到碰撞平面但是平面以及它们的交线都是不可行走的(倾斜角大于可行走角度)那么依次将当前速度在碰撞平面分解,以及检测每一条可能下滑的交线。得出速度后检测是否是有效速度具体过程和前面检查水平速度时的方法一样,只是将速度投影到平面上的方法不一样具体方法可以根据程序需要,我这里采用首先去掉原始速度在碰撞平面法线的分量,然后将速度分解为2个速度一个是贴着平面水平移动的速度另外一个是贴着平面下滑的速度。注意如果上一帧更新后物体处于下滑状态那么当前速度就因该是该下滑速度,否则则是用户输入的速度。
如果用户输入的速度是跳跃也就是带Z分量的速度那么,计算初始速度这一步需要略过直接输入给下一阶段用户起跳的速度。
阶段2计算初始速度引起的碰撞
对于多数情况来说,计算完初始速度就不会再发生碰撞了,一旦发生,那么我们依旧传入碰撞面的那些法向量,碰撞点的信息,同样采用前面计算初始速度时所采用的方法,计算出碰撞后的调整速度。 [Page]
整个处理过程基本上就是这样的,其中可能还会出现一些小问题比如说误差控制等。总结一条就是人物行走要么研着平面分解速度要么沿着2个平面的交线行走或者下滑。这个是Demo示例画面(由于没有人帮我做动画。。所以demo中目前只有行走动画,没有起跳,下落等动画。。)
分享到:
相关推荐
网游中人物的碰撞后反应控制.xps网游中人物的碰撞后反应控制.xps网游中人物的碰撞后反应控制.xps
总的来说,网游中人物的碰撞后反应控制是一项技术密集型的工作,需要平衡精度、性能和游戏体验。通过精心设计的包围体、碰撞检测算法和优化技巧,可以创造出既真实又流畅的游戏环境,提升玩家的沉浸感。
首先,我们要理解游戏中的“多角色控制”是指玩家能够同时操作或管理多个游戏角色,这常见于策略游戏、模拟游戏以及某些动作游戏中。实现这一功能需要对游戏逻辑进行精心设计,确保每个角色的行为独立且同步。 ...
在这个主题“js对人物的控制”中,我们将深入探讨如何利用JavaScript来实现网页游戏中人物的动态行为,如左右移动、跳跃、移动弧线跳跃以及碰撞检测。 首先,让我们了解JavaScript在网页中的角色。JavaScript通常与...
在2D游戏中,常见碰撞检测方法有轴对齐边界框(AABB)、圆形碰撞检测(Circle-Circle)以及更复杂的多边形碰撞检测。对于人物移动而言,碰撞检测可以防止角色穿过地形、障碍物或者其他游戏对象,确保游戏逻辑的正确...
帧同步则是确保在网络游戏中,多个客户端之间游戏状态一致的一种技术。在这个主题下,我们将深入探讨Unity中的仿物理碰撞实现以及帧同步的相关知识。 一、Unity中的仿物理碰撞 1. 物理引擎基础:Unity内置了强大的...
在现代计算机游戏中,准确且高效的碰撞检测是构建复杂环境的基础之一。随着游戏环境细节的不断增加,碰撞检测变得越来越困难,并且占据了游戏引擎计算周期的很大一部分。为了帮助游戏开发者更好地理解和实现这一关键...
JavaScript(简称JS)是一种轻量级的编程语言,广泛用于网页和网络应用开发,包括控制网页中的元素动态行为。在这个“js控制人物行走”的主题中,我们主要关注如何使用JavaScript来实现网页上的人物动画,让角色仿佛...
网络游戏中的碰撞检测是游戏开发中的关键技术之一,尤其是在实时性要求高的多人在线游戏中,精确而高效的碰撞检测对于游戏体验至关重要。本文件"网络游戏-用于检测网络上碰撞的方法和装置.zip"包含了一个名为"用于...
网络游戏中的控制模块、控制组件和控制网络是游戏开发与运行的核心组成部分,它们共同构成了网络游戏的骨架,确保游戏的稳定运行和玩家的互动体验。在这个压缩包文件“网络游戏-控制模块、控制组件和控制网络.zip”...
总之,网络游戏中的对象控制是一项涉及多方面技术的工作,需要综合运用编程、物理模拟、人工智能和网络通信等知识。通过深入理解和应用这些技术,开发者可以创造出更加引人入胜、操作流畅的游戏世界。
通过SilverLight,开发者可以构建出具有高度交互性和沉浸感的网络游戏,同时利用精心设计的碰撞检测机制,确保游戏的逻辑正确性和玩家的体验质量。这对于网页游戏制作的技术人员来说,是一个极具价值的技术方向。
半互穿网络(semi-interpenetrating network, semi-IPN)结构乳液则是其中的一种重要形式,它在网络游戏中的应用可能涉及图形渲染、物理模拟等方面,为游戏提供更真实、细腻的视觉效果和交互体验。 有机无机杂化...
本文将主要围绕标题“网络游戏-一种游戏控制器及游戏控制系统”展开,详细讨论游戏控制器及其控制系统在网络游戏中的应用与重要性。 网络游戏通常需要一个交互设备,即游戏控制器,来使玩家能够与虚拟世界进行互动...
碰撞检测是游戏中的关键部分,它决定了两个或多个游戏对象何时发生接触。在AS3.0中,可以使用基本几何形状(如矩形或圆形)进行简单的碰撞检测,或者使用更复杂的算法来处理多边形之间的碰撞。例如,对于球体间的...
这些游戏中的物理碰撞是游戏逻辑的关键部分,任何异常的数据都可能导致游戏的不公正或者降低游戏体验。 一、异常数据的定义与来源 异常数据是指在游戏中不符合正常逻辑或超出预期范围的数据,可能源于玩家作弊、...
网络游戏-控制游戏人物运动的设备及其方法.zip
在网络游戏中,每个玩家的行动都需要实时同步到其他玩家的设备上。这就需要使用到网络编程技术,如UDP或TCP协议,以及专门的网络同步算法,如 Photon 或 Mirror 等网络框架,来确保游戏状态的一致性。 在“游戏装置...
3. **网络优化**:在网络游戏中,延迟和丢包是常见的问题。有效的控制方法会采用预测技术和数据压缩技术,减少网络延迟对游戏的影响。 4. **物理引擎**:高级游戏通常使用复杂的物理引擎来模拟真实世界的物理规则,...