分类: C/C++ 游戏开发2012-09-13 14:30 574人阅读 评论(6) 收藏 举报

源地址:http://blog.codingnow.com/2007/11/inertia_thinking.html

晚上在办公室晃荡,对面的同事在加班写代码。我凑上去看看在写什么。我向他了解了后明白了,大约是服务器上角色 buff 的实现吧。

BUFF 这个术语是现在网络游戏中非常常见的。给角色加一个 BUFF 通常意味着对虚拟角色的一些数值上的临时修正:例如,攻击力 +5 ,防御 -10% ,速度加倍,等等。

玩过魔兽世界的朋友应该很容易理解这些。通常游戏里的 BUFF 设定比我上述的例子更加的复杂。

这里不谈游戏设定,谈谈实现。

同事在做的实现框架,给 BUFF 留了几个接口,其中有两个吸引了我的目光。

一个叫做 start 一个 stop 。分别用于 BUFF 产生的时候需要处理的逻辑,和一个用于 BUFF 消失时处理的逻辑。这是一个很自然的设计。尤其在 C++ 程序编写的习惯里,就相当于一个构造过程,一个析构过程。

比如,一个攻击 +5 的 BUFF ,可以在 start 事件处理里修正攻击值(+5),然后在 stop 里做一次逆运算(-5)。

我突然有一种直觉,感觉这个设计不是特别合理。因为它要求程序员去实现一对互逆的逻辑。这段时间我对需要编写事物处理的成对可逆处理的设计特别反感。所以立刻就意识到了实际问题所在。

首先,许多逻辑上成立的可逆运算都是事实上有漏洞的。比如某些特定条件下的浮点加减运算就有可能不可逆(暂时没有去构造一个例子,但是我认为是可以构造出来的);定点数的乘除运算就很容易导致不可逆。

还有更严重的,如果一个 BUFF 会把某个值设置成固定值(比如清 0 或设为 max),那么不借助缓存变量,这个效果就完全不可逆。

当然有经验的数值策划,会把公式里的乘法规则提取出来,安排合理的次序去计算。比如大多数游戏中,乘法加成系数都是先累加再一次乘起来的。(btw, 早期刚接触 diablo 的时候,我完全不能理解:为啥两个加 20% 的装备装到一起是 40% 的效果而不是 44% :D 也有游戏设计的更复杂一些,例如 Eve 里,就有所谓的叠加惩罚。哦,好象又写跑题了。)

我问了一下同事,诸如一些特殊情况如何处理的问题:比如玩家顶着 BUFF 断线,重新上线的数值恢复问题。还有如果在 BUFF 有效期间,人物升级或更换装备导致基本数值变更,怎么保证 BUFF 消失时的逆运算正确性……

这些自然可以找到方法在现在的框架下正确的处理。但前提是实现的人考虑完备,或是多记录一些中间数据。当两件有关联的操作(BUFF 出现和消失)在不同的代码中实现时,BUG 就有可能滋生。

接下来我又询问了一下别的项目的同事,咨询了一下类似的设计他们是如何实现的。居然,大家都用的相同的手段。看来,思维还真是有惯性啊。


我后来想到的解决方案其实很简单。取消 start / stop 接口,改提供一个 apply 。角色永远记录两套数值,一套基础数值,一套产生实际效果的临时数值。

每次状态改变(增加新的 BUFF、改变基础数值,或是改变装备等),都激发所有存在的 BUFF 的 apply 方法在基础数值上全部重新计算一遍,得到新的临时数值。这样有可能会增加一些计算量,但是系统设计会更简洁一点。

论游戏中Buff的实现 [转]的更多相关文章

  1. 浅谈游戏中BUFF的设计要点

    其实这类帖子并没有多少的设计理论,对于策划的提升和帮助也并不大,原因其实在于其适用性太窄,当我要设计XX象棋的时候,它就滚一边去了. 废话不多说切入正题: 游戏中的BUFF/DEBUFF我们见过很多, ...

  2. 地图四叉树一般用在GIS中,在游戏寻路中2D游戏中一般用2维数组就够了

    地图四叉树一般用在GIS中,在游戏寻路中2D游戏中一般用2维数组就够了 四叉树对于区域查询,效率比较高. 原理图

  3. FPS中受伤UI在VR游戏中的实现思路

    FPS中受伤UI在VR游戏中的实现思路 希望实现的效果 这几天一直在尝试各种解决方案,现在算是不完美的解决啦,记录一下心路历程,思路有了算法都比较简单. V_1 玩家胶囊体指向的方向作为正方向,计算出 ...

  4. 游戏中的人工智能——初探AI

    一.游戏中的人工智能 让游戏具有挑战性: 让游戏好玩的关键因素是为之找到合适的难度等级: 人工智能在游戏中的作用是通过提供富有挑战性的竞争对象来让游戏更好玩,而在游戏中行动逼真的非玩家角色(NPC), ...

  5. 【腾讯GAD暑期训练营游戏程序开发】游戏中的动画系统作业

    游戏中的动画系统作业说明文档   一.实现一个动画状态机:至少包含3组大的状态节点

  6. [CareerCup] 12.3 Test Move Method in a Chess Game 测试象棋游戏中的移动方法

    12.3 We have the following method used in a chess game: boolean canMoveTo( int x, int y). This metho ...

  7. Unity3D 2D游戏中寻径算法的一些解决思路

    需求 unity3d的3d开发环境中,原生自带了Navigation的组件,可以很便捷快速的实现寻路功能.但是在原生的2d中并没有相同的功能. 现在国内很多手机游戏都有自动寻路的功能,或者游戏中存在一 ...

  8. Unity制作游戏中的场景

    Unity制作游戏中的场景 1.2.3  场景 在Unity中,场景(Scene)就是游戏开发者制作游戏时,所使用的游戏场景.它是一个三维空间,对应的三维坐标轴分别是X轴.Y轴和Z轴本文选自Unity ...

  9. lua学习:游戏中的Lua

    lua作为一种脚本语言,可以快速地开发游戏的原型.提高游戏的开发效率. 在游戏中,lua可以用来完成下面这些工作: ●编辑游戏的用户界面 ●定义.存储和管理基础游戏数据 ●管理实时游戏事件 ●创建和维 ...

随机推荐

  1. php session_id()函数介绍及代码实例

    session_id()功能: 获取设置当前回话ID. 函数说明: string session_id ([ string $id ] ) 参数: 如果指定了参数$id,那么函数会替换当前的回话id. ...

  2. Apache + Tomcat + mod_jk实现集群服务及session共享

    实现效果:用apache 分发请求到tomcat中的对应的项目 原理:

  3. 利用Highcharts制作web图表学习(二)

        最近中海油的项目需要用到图表展示数据,最近还是一直边学习边开发,今天做了一个展示,炼化厂加热炉效率展示的柱状图,把代码贴出来,大家指点一下互相学习,我是通过数组给Highcharts绑定的值, ...

  4. Object-C在Nil上调用方法

    在Object-C中,nil对象的作用等同于很多其它语言的NULL指针.不同的地方在于,在nil上调用方法不会导致程序崩溃或抛出异常. 这种技术被用在很多地方,但是对于我们来讲,最主要的就是我们不用在 ...

  5. WKWebView详解

    WKWebView是在Apple的WWDC 2014随iOS 8和OS X 10.10出来的,是为了解决UIWebView加载速度慢.占用内存大的问题.使用UIWebView加载网页的时候,我们会发现 ...

  6. 【BZOJ2793】【数学】[Poi2012]Vouchers

    Description 考虑正整数集合,现在有n组人依次来取数,假设第i组来了x人,他们每个取的数一定是x的倍数,并且是还剩下的最小的x个. 正整数中有m个数被标成了幸运数,问有哪些人取到了幸运数. ...

  7. 【ADO.NET】5、手机归属地查询( winfrom )

    using System.IO; 有一个数据库手机号码的txt文件,格式是 : 13500000000-13560000000-中国移动 查询结果: 湖南移动[邵阳]文件夹选择对话框 FolderBr ...

  8. 通过 ANE(Adobe Native Extension) 启动Andriod服务 推送消息(一)

    项目组用air来开发手游, 但有些在原生应用里很容易实现的功能没有办法在air中直接调用,比如说震动,服务等等.但Adobe 提供了一种方法让air间接调用本地代码(java,object-c...) ...

  9. mongodb 安装及,设置账户、主从

    我原来没用过mongodb ,在晚上查了查需要的命令,关于怎么mongodb怎么用,我就不知道了 官方网站: http://www.mongodb.org/ MongoDB 安裝,主从配置一 Mong ...

  10. 01_安装redhat 7.1时常出现的问题

    1. 笔记本安装时出现"dev/boot does not find ",进不去安装界面. 这是因为pci设备的问题,解决方法:在出现安装选项时,按Tab进入option模式,在末 ...