游戏开发论坛

 找回密码
 立即注册
搜索
查看: 10117|回复: 2

[原创] MMO游戏技能区域算法效率分析

[复制链接]

2

主题

5

帖子

41

积分

注册会员

Rank: 2

积分
41
QQ
发表于 2016-4-4 22:44:41 | 显示全部楼层 |阅读模式
第一部分 攻击区域的类型

  游戏技能攻击区域的计算,关乎服务端的效率。需要确保正确,简洁地计算攻击区域,才能快速寻找攻击对象。

一般情况下攻击区域分为以下几种:

  • 点对点,对个人进行攻击
  • 射线攻击,其实就是矩形区域
  • 扇形攻击
  • 圆形攻击


  当然,还有其他情况,例如多区域和其他奇奇怪怪的形状。不过考虑的实际观赏价值,和精度的问题,多区域,只考虑圆形和扇形,其他形状也不考虑了。

  释放技能需要几个事物,攻击者,主要被攻击者(也可能是攻击地点),其他围观的群众



1.点对点的攻击

  这个是最简单的,只要达到技能释放的距离,就可以释放。只要攻击者和被攻击者的位置小于配置的有效距离即可。



2.射线攻击,矩形区域

  怪物向目标喷出一条长长的火线,在火线上的玩家受到攻击,如下图。A向B喷火。同时也要检测周围的玩家是否中招
20160311185115477.png

  但这个是在矩形的边跟坐标轴平行的情况下的。如果攻击者的攻击方向跟坐标轴不平行,如上图,就无法计算了。

  怎么办呢,如果能转换成相对坐标就简单很多了。

  要从绝对坐标转换成相对坐标,需要确定相对坐标的原点和x轴方向。

  原点是A点,X轴方向从A点指向B点。现在是求图中C点的相对坐标。

  ABC三点确定位置。根据余弦定理可以求出角CAB的余弦,从而可以求出相对坐标。然后在判断是否在矩阵内。



3.扇形区域

  攻击者对前方角度α,长度为L的区域进行攻击。如下图,攻击目标为B,要计算旁边的C是否也受到攻击

20160311200412539.png

  扇形,当然是用极坐标最方便,判断一下距离,在半径范围内,然后判断一下角度是否适合。

  策划配置:扇形半径R和扇形总角度β

  所以构建以A为原点的极坐标。根据中心线的角度α,求出扇形的角度范围为[α-β/2,α+β]。再求出C点的极坐标进行比较

  还有一种方法,就是利用向量的点积。

  通过这两个公式,可以求出夹角。

再说一下多个扇形的情况
20160312103914869.png

分开算就行了,用个for循环,每个扇形分别计算。



4.圆形区域,圆形其实是最简单的了。

20160312104249874.png

  判断是否在攻击者半径范围内就行了。

对于多个圆形区域的计算
20160312104735794.png

  本质上还是一样,用一个for循环,计算出圆心的位置,然后计算点到圆心的距离就完成了。



第二部分 对地图划分格子

  之前已经写过关于攻击区域的算法。但后来,发现别人的游戏(《凡人修真2》其实也不算别人的游戏了)不是这么写的。我居然找不到算矩形之类的代码。找来找去,发现实现思路跟我的差别太大。

  先说一种情况,就是一个玩家的角色在地图上走动的时候,是需要不断的跟服务端同步的。

20160403093241119.jpg

  例如图中坐标系,从位置1走到位置2.这个过程中是要不断的跟服务端同步的。服务端也会不断地跟其他客户端同步。

  在玩家的角度来看,角色A是从位置1到位置2匀速运动。而在同一个屏幕下的其他玩家也是在匀速运动。这是正常情况下,也是理想的情况。

  但客户端不可能没移动一个像素就跟告诉服务端一下,我走了一个点。

  这个是不现实的,首先没有必要,移动一个像素,客户端可能根本没什么变化。

  第二,假如屏幕上有10个人,一个角色移动了,服务端就要广播给10个人,在一瞬间就是发送了10个消息。假如这10个人都在动,就是同时发送10*10个消息

  假如屏幕上有100个人同时在动,就是100*100,假如是1000,就是1000*1000了。我相信这个游戏基本就只能在地图上跑,其他什么都做不了了,甚至跑都跑不动。

  所以可以得出结论:客户端跟服务端必须不是同步的,以减少通信。这样的话就只能走一段距离才同步一下位置。其他客户端收到这个角色在动,就自己做一个匀速运动过去。

  对于客户端来说,角色移动依然是上图的样子,对服务端来说是怎样的呢?

20160403095215174.jpg

  对服务端来说,没收到客户端的一个请求,就改变一下位置,所以从位置1到位置2,是按着图中换色路线闪过去的。

  其他客户端收到同步的消息,就做匀速运动,然角色看起来好像在一直走着。

  那么现在问题来了,客户端跟服务端同步的标准是什么呢?什么情况下需要同步一下?

1、按时间同步

  每隔一段时间同步一下,例如100毫秒。我们的服务端的怪是这样同步的,因为每隔一段时间需要执行一下AI处理,是否遇到玩家,是否需要追击,是否需要释放技能等等。这些都要做,所以移动的话,也就放在这个模块里面了。我不知道会不会有的游戏客户端会这样处理。

2、按空间同步

  每移动一段距离,就同步一下。但是这个距离怎么算呢?是从上一个点开始算起么?我们没这么算过,可能等我客户端的时候可以这么试试。实际上我们是把地图画了一个个格子。就像上图那样,假如地图是1000*1000的。我每100个像素划分一个格子。就可以得出X轴和Y轴都分成10份了。角色只有从一个格子移动到另外一个格子的情况下,才通知服务端。

  这样做的好处是大大缩减了通信的数量。当然也不是没有代价的,如果卡的时候,就会看到角色从位置1走到位置1.1,然后定住了,过几秒钟,它可能出现在位置2了。如果是在多人同屏夺旗之类(独步天下的帮派战),真是日了狗了,杀过去后发现玩家居然闪过去了。

上面是地图的处理,总结一下:

  无论服务端是把地图分成一个个格子,在同一个格子内,是算同一点的,如果你把格子画得很大很大,例如整个地图就是一格子,那么在服务端看来,所有角色都是堆在同一个位置上面了。

  那么格子需要多大呢?

  问了一下策划,他们回答:肯定是越小越好啦,这样就能越精确。

  问了一下客户端,说:他们没有格子的概念的,服务端分的格子,他们基本上只是判断一下消息发送的时机而已。

  对服务端来说,虽然不可能整个地图就一个格子,但是也是想越大越好啊。

  顺便一说,地图主要是客户端的天下,地图格子是服务端用来做技能处理的。

  对于一般的2d游戏来说,格子大小最好还是先设定好一个值,然后看实际效果,再慢慢调。因为每个游戏的场景、建筑、任务的大小都不同,尤其是像大战神这种可以放大缩小的游戏,更加需要直接看游戏来作调整。一切以实际感官为标准,然后尽量画大一点。

  我们先把格子分好!!!无论用哪个计算方式,都需要先把格子分好。按每个格子CellBase大小为20像素,当然实际应用中可以长宽不同。如下面就是一个220*220的地图,分成11*11个格子。格子中的数字就是其坐标,格子的坐标。

20160403224006957.jpg

  明确好格子的概念,就可以开始思考新的技能攻击区域了。

一般情况下攻击区域分为以下几种:
  • 点对点,对个人进行攻击
  • 射线攻击,其实就是矩形区域
  • 扇形攻击
  • 圆形攻击

  加了格子后,就多了一种计算方法。

我们看一下不同技能在区域在格子上面是怎么表示的。
1.点对点,没变化,就不说了。
2.扇形,如果是小的扇形,其实就是自己所在的那个格子,就判断玩家是否在同一个点就行了。如果扇形很大。

20160403232812600.jpg

图中使用的是相对位置,以攻击者为圆心,这个只考虑了一个朝向。
3.矩形,其实就是一条射线

20160403233123867.jpg

4,再看看圆形:

20160403233339009.jpg

  那么怎么算呢?

  这些点都是通过配置来实现的,用相对位置来配好,直接拿来对比就行了。



第三部分 不同的攻击算法的计算效率如何呢?

  在前面的文章,已经得出结论:由于服务端的承载问题,需要对地图划分格子。

  但是划分格子后,通过格子配置,也可以实现对圆形,扇形,矩形等图形的计算。但是在获得简便的计算之后,却是用精度来做代价。

  所以今天要对两种方式,做一次效率的分析。

先确定一些基础条件:

  • 把地图格子设置为20*20,整个地图就是220*220,分成11*11个格子。
  • 每个格子让一个角色站着。


统计结果:
1459770937_6970.jpeg

柱形图:
1459771072_4428.jpeg

最后总结:

  • 测试了几次,发现相差都不大,就不算平均值了,只取某一次的数据。
  • 对于同一种区域计算,提升执行次数,基本是等比例提升。
  • 扇形可能会同时出现多个,因为在实际游戏中,可能玩家会站得比较近而打不到的情况,这个时候用一个半径比较小,角度比较大的扇形来补充比较合适。
  • 格子少的时候效率是很高的,但是格子多了,效率就降低了。换算一下,一个矩形相当于18个格子的计算量,一个扇形相当于6到七个。至于什么哪个方式比较时候,我建议是各种方式的代码都需要写,到时候在根据具体格子大大小,还有技能区域的大小,判断一下能用多少个格子来表示攻击区域。在进行选择
  • 必须提到一点,一开始函数参数没有使用引用,执行时间差不多是现在给出来的数据的3倍!尤其是格子算法函数调用多,造成很大开销,差距更大。所以没啥事要使用引用,否则老是创建新的对象,消耗很大的。
  • 想不到扇形这些的计算量并不是很大,不要以为算法复杂,计算消耗就大,还是需要实际测试一下,可能出乎你意料!!!!!!




23

主题

325

帖子

3164

积分

论坛元老

Rank: 8Rank: 8

积分
3164
发表于 2016-4-5 14:05:43 | 显示全部楼层
不错,2D客户端游戏的做法。跟我遇见做到一模一样

0

主题

6

帖子

44

积分

注册会员

Rank: 2

积分
44
发表于 2017-8-9 01:46:24 | 显示全部楼层
那几篇文章了,怎么找不到了。。具体算法的那几个。。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-5-10 12:13

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表