游戏开发模式进化(OpLog协议说明)—— OpWeb框架系列[1]

     目前公司以开发网页游戏为主,这里就从游戏场景说起。

场景描述:

    游戏简化版是这样的,游戏分为养成和战斗,玩家通过不断的战斗获得战利品并升级自己,然后挑战更强力的BOSS,貌似一般游戏都这样!

那么我们就有了2个场景,玩家面板和战斗面板。

玩家面板有几个数据:玩家名字,当前金钱,当前等级,当前经验,装备武器,背包。

战斗过程不说:战斗会玩家会获得经验和物品或金钱。


传统的BS开发模式。

    一般项目都采用传统三层模式,虽然我不喜欢这种模式,觉得比较繁琐,但是我加入之前公司的项目确实是采用这种模式开发。

简单的描述下开发过程:

1.首先定义一张玩家表:

玩家ID,玩家名字,金钱,等级,经验

2.然后有张背包表:

物品ID,玩家ID,装备位置ID


定义好对象,或者通过ORM工具,我们就拥有了 玩家类,和道具列表     


场景

玩家装备了一把剑,然后去战斗,接着获得一些金钱和装备。

UI流程-》玩家面板-》背包面板-》装备武器-》进入战斗(略过)-》结算面板-》返回玩家面板


开发过程是这样的:

1.首先我们需要玩家面板的一个数据请求,我们定为“请求玩家信息服务”

2.然后我们需要一个背包面板,“请求玩家背包服务”

3.战斗后结算信息,“战斗后结算服务”

看看都干了什么?

服务端:

1.查找玩家数据,然后通过“请求玩家信息服务” 返回,包含{名字,金钱,等级,经验}

2.查找玩家背包数据,然后通过“请求玩家背包服务”返回,包含一个道具列表 [{ 道具ID,装备位置ID}]

3.战斗后返回战斗结算服务{金钱,经验,[道具1,道具2]}

客户端:

1.请求 “请求玩家信息服务”并绑定到面板。

2.请求 “请求玩家背包服务”并绑定到面板。

3.战斗后,显示结算数据。

4.第一个面板,执行第一步。

这个简单,看起来没有问题。

然后我们增加了几个新的需求:

1。我们需要在背包面板中显示金钱

两个做法:

1.在请求背包服务器中,返回金钱数据。

2.独立一个金钱服务。

2。如果我们需要在战斗中有个小面板,显示玩家拥有的等级,经验,以及拥有的药水

简单:

一个“战斗中服务”,返回 { 等级,经验,药水数量 }


回头看看,2个服务都需要金钱,2个服务需要等级、经验

独立出来?有个服务叫获取金钱、有个服务叫获取等级经验?


我们有了如下假设1:

如果有个服务,叫:“刷新玩家数据”返回 整个玩家数据 { 名字 ,金钱,等级,经验,背包[{道具ID,装备位置ID}]}

这个完美了,只要能刷到任何数据,我们就能省下几个服务:

1.“请求玩家信息服务”

2.“请求玩家背包服务”

3. “战斗中服务”

就省下2个服务:(看起来爽多了,而且仅需要解析一个)

1.“刷新玩家数据”

2.  战斗后,显示结算数据。


看起来这是一个简化服务的文章么?

以上的假设在理论上是成立的,但是总是刷新真个数据太大了对吧。


然后我们有了第二个假设2:

如果这个服务能根据我的需求返回响应的数据就更好了。

比如一些过滤写法:ret=金钱|等级|经验 (我们实现过。。)

看起来很完美吧。

这个有些致命的问题:

1.客户端需要知道什么时候应该刷新什么。

2.如果需求更改,需要修改相关的请求过滤。

   

额,第三个假设3:

如果我们客户端有个服务端相关对象的镜像副本,并且能保持同步。

那么是否能解决假设2的问题?


看起来很完美,我们需要解决的问题?

1.如何定义对象?

这个比较简单,我们采用服务端先定义,然后采用反射生成客户端对象定义数据。

2.如何同步?

这是本文的重点了:OpLog 协议

OpLog 协议:


   OpLog 我这边称他为操作日志,搜一下MongodbOpLog,理念还是比较类似的,OpWeb便是基于此同步理论做的。

Mongodb的节点间数据同步就是基于OpLog,而OpLog Engine原本出发点用于分布式节点中,内存对象的实时同步。

但是该项目没有完成(甚至没有怎么开始。。)

  

   我们采用Json数据用来存储并同步数据,Json以灵活快捷著称,并且较小的体积,正是我们需要的。

   1.对象定义,玩家

    {  金钱,经验,等级,背包 [    { 道具1,道具位置1 }, {道具2,道具位置2}  ]}

    2.如何定位对象,比如我需要修改金钱:

    { 金钱 : 100 }

    但是我比如需要修改  背包中, 道具1的道具位置1?

     背包->[0]-》道具位置1 : 10

    好像不太合适,比较深的层次呢?

    假如我们的对象永远都只有1层,所有对象都必须拥有一个ID,定义变成这样:

     { ID :1000 ,金钱,经验,等级,背包 [    {ID : 1001  ,道具1,道具位置1 }, {ID:1002, 道具2,道具位置2}  ]}

     我们修改金钱变成:

     {ID : 1000, 金钱 : 100}

     修改  背包中, 道具1的道具位置1?

      {ID:1001,道具位置1 :10 }

     我们从根目录遍历,就能找到ID为1001 并且完成修改,完美!

     

以下是我们完整的协议说明:

{

Ts:时间戳,所有的操作时间戳必须前进(也就是必须大于前一个)

OpSync,Update,Insert,Remove(4种状态)

Rid: 操作的对象父Id

OpStrOpSync则为整个对象内容,

    OpUpdate,则为差异内容,

    OpInsert ,则为子对象内容,

    OpRemove,为空
Ns
:当OpInsert OpRemove时有效,列表的字段名(如上例,添加一个武器 Ns:包裹

Oid:当OpInsert OpRemove时有效,子对象OpId

}

(当OpSync时,直接覆盖OpStr到当前对象)

添加一个对象:

Op:Insert ,Ts : 10001,Rid:1000,OpStr : 新建对象{ OpId 1003,数据1 10 },Ns:列表,Oid1003

删除刚才对象:

Op:Remove ,Ts : 10002,Rid:1000,Ns:列表,Oid1003

更新一个对象:

  { Op:Update ,Ts : 10001,Rid:1000,OpStr :{数据1 10 }



开源OpWeb框架介绍 请移步: http://blog.csdn.net/icesun963/article/details/17194193


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值