游戏中物品的同步

以在背包、仓库中操作物品为例

维护到一份代码看到如下的流程:

假设现在我在背包中把物品从A格子移动到B鸽子


已经有的关键字:

物品类型:普通,特殊,消耗。。。等等

放入函数:使用物品类型掩码判断

(1,2表示步骤)

C1:从落点范围判断是否合法(比如背包格子是1-20,仓库是40-60)。如果满足,发送要移动的包给服务器。这时候UI不做更新,即不执行实际的更新函数

S1:收到包进行校验,比如是否能存放,如果是装备则如何如何(放入函数)。同步计算完后,发送确认包给C

C2:收到后执行实际的更换操作,更新(放入函数)


维护的需求如下,任务物品不能放入仓库,并且给玩家提示。两套方案

1:维持旧的结构,放的时候发一个包,靠服务器返回的一个包来说明是否可以放入。后来发现交换协议包中没有这个成功的字段

2:不发包。服务器的校验直接返回,客户端做本地判断,条件不符合就不发包。比较别扭的地方来。如果不发包,那么服务器就不会发确认包,没法执行客户端的实际"放入函数"。所以只好在C1的坐标中判断这个物品来自哪里,然后直接操作。


      另人感到很不快的是,为什么要通过落点判断呢?物品本身不是有物品类型的设置吗?只要在容器和物品间设置好掩码不就行了?现在就好比有两套的资源结构,又可以落点判断,又可以物品实际属性判断。


想起以前工作中碰到的物品操作流程:

C1:本地做一份操作(实际操作),成功后发给服务器一份通知信息,鼠标锁定

S1:收到后做一份同样操作,发一个解锁命令

C2:解锁


      这两套方案中,我本来还比较排斥第二种,现在反而喜欢了。操作物品的时候最本质的需求是两边要同步,

从代码维护上来说:

      一号方案是让服务器先做,然后自己再做。如果是这样那中间就无所谓在判断是否合法了。但是一些基本的判断你又不得不做。

      二号方案中是直接做,也不要预判断什么。因为一件物品是否能放入,怎么放入,这两个逻辑应该是内聚在一起的。比如通过掩码的方式。然后通过一个解锁命令来同步。如果再通过一些额外的点范围判断,实在是费解


      很多人会说锁会不会影响了操作?其实一样的,一号方案也要在等待服务包的更新通知。(不知道大家有没在游戏中拿起一件物品放一个位置,卡住的时候老放不下。)重要的本质是什么,是同步。即使你这个时候让玩家继续操作(影响到他刚才移物品的),也是无效的。而在实际的表现过程中,网络顺畅时(60-120MS响应),0.15-0.2秒很快就解掉锁了。

      写到这,想起其实可以对一号方案进行改进,C1中直接进行一个放入的步骤预判断,如果成功发消息请求。服务器成功后发送确认,C1再执行最终的放入。还是一分为二的做法。这样的代码你敢重用吗?

     

猜你喜欢

转载自lin-style.iteye.com/blog/762411