本文转至:http://bbs.chinaunix.net/thread-1692302-8-1.html
(只作转载, 不代表本站和博主同意文中观点或证实文中信息) 再比如,传说中的面向对象本该大显神威的游戏领域——就说流行的WOW吧。 这个游戏有10个职业,10个种族,每个种族都有自己的几个特有种族天赋(这个种族天赋还可能根据职业有所不同,比如血精灵);每个职业有几十甚至上百种不同的技能/法术,这些技能有近战技能,有远程技能;有的技能会对敌方造成伤害或不良状态,有的技能能给己方队友加上好的状态或治疗队友;而且很多这类技能还会根据目标的状态切换不同的效果;有些技能是单体效果,有些技能是光环效果(又分为对地方造成光环效果还是对己方两种,也可能两者兼备),而另一些技能是地图范围效果(如烈焰风暴是一个圆形区域;冰锥术是一个锥形区域;特别的,顺劈斩是在当前攻击目标旁边不超过5码的另一个敌对目标——某个boss的顺劈斩更强,它会从第一个目标传递几十个目标,总传递距离可以达到夸张的几百码;并且这个伤害也是各有特色的:战士的顺劈斩是每个目标伤害固定,有些boss的则是同时挨打的人越多伤害越低,但还有个变态boss却是被打的人越多伤害越高……);大多数技能还可以通过天赋雕文强化/改变的面目全非(比如插一个雕文,法师的火球就不会造成持续伤害但施法速度增加;点一个天赋,法师的冰冷减速效果就会降低对方受到的治疗效果;点某个天赋,盗贼的某些技能攻击就会延长自身提升攻击速度这个状态的持续时间,等等);还有很多技能是因为学习了某个专业或装备/持有某个物品而得到(比如,学了采药,就可以得到生命之血这个技能,每3分钟可用,能够在若干秒内回复你若干生命值——这个技能和采药技能等级挂钩,但很可能接下来的某个版本,就会再和玩家的生命上限值挂钩,以避免它像现在一样,被玩家斥为废柴技能);另外,不同等级的技能可能有施法时间甚至额外特效方面的差别;此外,每个技能会造成不同属性的伤害/效果(神圣、暗影、元素、物理等等),甚至一个技能同时造成多种类型伤害效果,更有冰火球这样根据目标抵抗力而智能选择更大杀伤效果类型的变态魔法…… 最后,最最重要的是,这所有职业上千个技能(或许加上NPC特有的一些技能,数目会达到几千种)并不稳定,常常会因为某个技能或某些技能的组合过于强大/弱小而加以修改(比如加一个额外的负面状态如无敌/圣疗;甚至全面修改“抗性”“破甲”概念的定义)——玩过wow的都知道,这事几乎每个月都有发生。 好吧,你打算怎么设计这数千个技能/效果? 或者,你就这样把这些概念用class这个筐一装,然后到处开特例、特例都解决不了就搞23个模式使劲往一块粘,管他整体结构如何,淌哪算哪? 扯淡。 有个故事说的好:
有人送几个瞎子一条鱼,瞎子们高兴坏了,决定熬鱼汤喝。鱼汤熬好了,瞎子甲尝了一口,真鲜啊;瞎子乙赶紧也喝一口,太鲜了,太好喝了。几个瞎子一边喝一边赞美——忽然瞎子丙叫了起来:鱼跳我脚上了,它不在锅里!
众瞎子大惊:这鱼都没放到锅里,汤就鲜成这样了;要是放进锅里,还不得把我们都鲜死啊! 众面向对象原教旨主义者把事情搅得一团糟,同样也会大惊:天哪,用了面向对象都复杂成这样,这要不用面向对象,这软件就不能写了吧!
   这个问题是不可回避的

暴雪在Diablo 2时代已经解决了: 法术/技能数据库化

所谓数据库化,其实等同于表格化,例如我的简化方案:

法术ID 动画效果 作用范围 作用类型 属性 特殊限制 强化类型 特殊设定

特殊设定可以是一段LUA代码,比如可以在其中搜索、设置伤害类型,查询顺劈斩/治疗链等技能的传递目标等等。

特殊限制,如驱散限定为只能作用于魔法性buf/debuf(根据职业不同,可能有进攻性驱散和防守性驱散之一,也可能同时具备——这就体现在可否驱散敌方/友方目标的debuf)

在这个方案下,释放一个法术/技能,就成为一种查表运算——找到此法术ID,找到它的作用类型和伤害属性,计算特殊设定(包括但不限于顺劈斩模式的判断、天赋加成和天赋效果、雕文加成和雕文效果等等)。

于是,到最后,整个法术体系被分为一组组的魔法buf/debuf、物理buf/debuf,这些buf/debuf会影响伤害公式中的某个因子或者造成伤害效果;而伤害效果又分为立即伤害/立即治疗和持续伤害/持续治疗;最后则是一套影响范围判定机制。

举例来说,骑士开圣盾,他同时得到一个buf和一个debuf。
buf是“无敌”,效果相当于设置伤害公式 a*(....) 前面的a因子为0(没有无敌时此因子为1),于是所有伤害无效。
debuf则是“自律”,因为他的圣盾、圣疗技能判断条件里都有“有自律debuf,则不允许使用”的设定,于是禁止他在短时间内再次使用这些无赖技能。 敌方法师对他释放寒冰箭,系统受理,但查询骑士状态,发现他处于无敌状态,返回大大的两个字“免疫”。 然后,有一个敌方牧师对他使用驱散,查询牧师的驱散术发现,在驱散术的可驱散列表里没有圣盾术,于是提示无法驱散或驱散了另外的可驱散(魔法)效果。
敌方牧师迅速反应过来,再次对他使用强力驱散;查询牧师强力驱散术,发现该牧师在不久前使用过强力驱散,提示无法施法。
等待3秒后,敌方牧师发现自己的强力驱散冷却(cool down),再次使用强力驱散,查询发现强力驱散可驱散圣盾术,于是成功移除骑士的无敌状态。 现在,敌方法师再次对他释放寒冰箭,骑士切换冰抗光环,系统查询骑士状态,发现冰抗光环,又查询法师穿透等级,和暴击等级,根据公式计算能否命中、能否造成全额伤害以及能否暴击;然后提取法师和骑士双方装备、天赋数据代入公式计算伤害加成、减免数据,最后给出骑士受到的伤害数字(包括部分抵抗了多少)。 在暴雪设计师的整理之下,如上种种最终构成了几个表格;只要查询并代入相应的数据,即可计算出伤害/治疗数值以及类型;特殊效果可以用存储在数据库中的LUA代码补充完成。 最终的设计效果就好像内嵌了一个解释器,这个解释器会根据法术ID解释执行数据库内部的相关内容。 至此,暴雪就完成了整个游戏中各种技能的数据库化,以至于给一个角色/物品添加/删除一个/一些技能都易如反掌。 想想看,假如让那些面向对象原教旨主义者来设计,会出现什么情况: 定义一个基类叫技能;然后一个继承类叫法术技能,另一个叫物理技能;然后神圣法术从法术技能继承,疾病法术也从法术技能继承;由于圣骑士一个技能同时具备物理和法术两种效果,于是必须多重继承神圣法术和物理技能;多重继承太危险,于是不得不把神圣法术搞成接口类,引入接口继承甚至带实现的纯虚函数等等高端概念;然后,活该枪毙的暴雪设计师又想出了让某个技能同时对目标加上神圣持续伤害效果——于是不得不再加个继承层次,使得神圣法术是神圣持续伤害法术的子集:仅立刻造成一次持续伤害的DOT(damage of time)技能…… 那么,点一个天赋,一个技能就会有dot,否则就没有怎么办? 设计模式是灵丹妙药,不是吗 ^_^ 等到把这所有几千个技能全部搞定,起码也是一个数万个类、几十层的恐怖继承树,并且会用完23个设计模式(甚至再发明几个新模式出来,我也不会感到奇怪),精巧复杂到没有任何人愿意去碰它。 但,请注意,天杀的暴雪设计师,在最开始的设计方案里规定DOT不能暴击;后来又添加约定说某某某职业的某个dot可以暴击;另一个职业的某个dot在点天赋后可暴击;至于死亡骑士,在他穿了T9套装中的其中四件装备时,他的某个瘟疫类型的dot可以暴击——但另一个瘟疫dot永远不能暴击。 嗯嗯嗯,太好解决了——这不就是策略模式吗? 好吧,你再填几十几百个类体系,然后把旧的几十层继承树中的数万个类一个个都策略化吧。反正不是我在维护…… 哎呀不好,那个枪毙了几百次都还没死的暴雪设计师又出馊主意了,他要求:当死亡骑士点了邪恶系的某个天赋时,不光给他增加一个新的dot、并且在这个新dot的存在期间,还要保护他的两个dot性疾病和1个debuf性疾病不被驱散! 继续补充:在WLK里面,那个脑袋都被子弹打成筛子了的暴雪设计师又跳出来了,用他满是漏洞的脑子出了个该杀的主意:他要求添加载具概念,当玩家坐上载具时,临时删除他的所有技能,替换为载具的技能;或者当他坐在特定载具的特定位置时,防止他受到任何伤害、并且允许他释放自己的所有技能!
更该死的是,他要求,一些技能本来不允许在移动中施放;但现在,当玩家坐在载具上某个位置时,要临时允许他移动施法! 还有,为了平衡某个野外战场,他还要求,在某方人数较少时,临时根据提高他们的生命值和所有技能的攻击力和治疗能力——这个改变必须根据进入战场的人数实时进行;在一方连续在某个战场失败时,同样要给他们一定补偿! 嗯嗯,看看这些刁钻需求吧,如果没有面向对象,没有以策略模式为首的28个设计模式(我有理由相信你们需要至少28个设计模式而不是23个)的英明领导,我们这些没接触过大项目、不懂面向对象的傻B们,就是哭的拿眼泪把长城溶解掉都没办法吧?——我当然知道搭建长城的材料极难溶与水。 可怜的瞎子,你们的鱼汤很鲜吧?

[转] 评 WOW技能天赋设计的更多相关文章

  1. 游戏设计艺术 第2版 (Jesse Schell 著)

    第1章 太初之时,有设计师 (已看) 第2章 设计师创造体验 第3章 体验发生于场景 第4章 体验从游戏中诞生 第5章 游戏由元素构成 第6章 元素支撑起主题 第7章 游戏始于一个创意 第8章 游戏通 ...

  2. app开发版面设计原则

    (1) 单纯:形象和色彩必须简单明了(也就是简洁性). (2) 统一:造型与色彩必须和谐,要具有统一的协调效果. (3) 均衡:整个画面须要具有魄力感与均衡效果. (4) 展现重点:构成要素必须化繁为 ...

  3. UI设计初学者必看,这款设计神器教你快速入门

    网络时代,网页和手机App已经深入到人们生活的方方面面.这也使得App界面设计越来越受青年求职者们的青睐,并纷纷投入这个行业.但是,作为UI设计初学者,究竟如何才能快速的入门?当今市场上,是否有那么一 ...

  4. UI设计是青春饭?今天告诉你真相!

    最近有学员来问,“我想转行学习UI设计,但是听很多人说,UI设计是吃青春饭的,互联网公司是不是只选择年轻的血液而淘汰年纪大的?”今天,我来统一回答一下. UI设计是不是青春饭? 我们先来思考一个问题: ...

  5. 【开源】使用Angular9和TypeScript开发RPG游戏(补充了Buffer技能)

    RPG系统构造 通过对于斗罗大陆小说的游戏化过程,熟悉Angular的结构以及使用TypeScript的面向对象开发方法. Github项目源代码地址 RPG系统构造 ver0.02 2020/03/ ...

  6. The Life out of coding_Employment_01

    1.工作与个人价值 软技能读书笔记第一篇:--From 安晓辉 内生涯与外生涯 内生涯包括知识.技能.工作经验.心理素质.内心情感.行为习惯.视野.观念.职业心态.职业成熟度.心灵成长. 外生涯包括职 ...

  7. 敏捷软件开发VS传统软件工程

    敏捷软件开发:又称敏捷开发,是一种从1990年代开始逐渐引起广泛关注的一些新兴软件开发方法,是一种应对快速变化的需求的一种软件开发能力. 与传统软件工程相比,它们的具体名称.理念.过程.术语都不尽相同 ...

  8. PHP程序员的技术成长规划

    按照了解的很多PHP/LNMP程序员的发展轨迹,结合个人经验体会,抽象出很多程序员对未来的迷漫,特别对技术学习的盲目和慌乱,简单梳理了这个每个阶段PHP程序员的技术要求,来帮助很多PHP程序做对照设定 ...

  9. php技术之路

    按照了解的很多PHP/LNMP程序员的发展轨迹,结合个人经验体会,抽象出很多程序员对未来的迷漫,特别对技术学习的盲目和慌乱,简单梳理了这个每个阶段PHP程序员的技术要求,来帮助很多PHP程序做对照设定 ...

随机推荐

  1. myrocks复制中断问题排查

    背景 mysql可以支持多种不同的存储引擎,innodb由于其高效的读写性能,并且支持事务特性,使得它成为mysql存储引擎的代名词,使用非常广泛.随着SSD逐渐普及,硬件存储成本越来越高,面向写优化 ...

  2. (转载) Linux IO模式及 select、poll、epoll详解

    注:本文是对众多博客的学习和总结,可能存在理解错误.请带着怀疑的眼光,同时如果有错误希望能指出. 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案 ...

  3. Python处理Excel表格

    同事小王今天说他有一个Excel表格,表格如下,一列是姓名,一列是电话号码,总共有大概2000行数据. 有的姓名占了一行,有的占了两行,还有一些占了三行的.如下图: 他问我可不可以全部统一成一行,而且 ...

  4. 如玫瑰一般的PHP与C#混合编程

    故事背景是这样的,有一套项目,服务器端是用C#写的,为了完成某种事情,它需要使用到一个组件,这个组件很小但很重要,很不巧的是,这个这个组件是用PHP语言写的,如果为了使用这个组件而专门搭建一个PHP的 ...

  5. 基于Netty打造RPC服务器设计经验谈

    自从在园子里,发表了两篇如何基于Netty构建RPC服务器的文章:谈谈如何使用Netty开发实现高性能的RPC服务器.Netty实现高性能RPC服务器优化篇之消息序列化 之后,收到了很多同行.园友们热 ...

  6. Nodejs之MEAN栈开发(五)---- Angular入门与页面改造

    这个系列一共会涉及两个JavaScript框架的讲解,一个是Express用做后端,一个是Angular用于前端.和Express一样,Angular分离内容,处理视图.数据和逻辑.和MVC模式很相似 ...

  7. Struts2拦截器的执行过程浅析

    在学习Struts2的过程中对拦截器和动作类的执行过程一度陷入误区,特别读了一下Struts2的源码,将自己的收获分享给正在困惑的童鞋... 开始先上图: 从Struts2的图可以看出当浏览器发出请求 ...

  8. ASP.net 使用ConfigurationManager获取连接字符串

    在解决方案资源管理器里右键单击解决方案选择“添加引用”,并且从 .net 中找到 System.Configuration 引用它 在项目的web.config文件中添加 <connection ...

  9. Hibernate 命名查询

    1.定义 Hibernate允许在映射配置文件中定义字符串形式的查询语句,这种查询方式被称为命名查询. 2.创建表结构并添加测试数据 create table `student` ( `id` dou ...

  10. ASP.NET MVC5+EF6+EasyUI 后台管理系统(54)-工作流设计-所有流程监控

    系列目录 先补充一个平面化登陆页面代码,自己更换喜欢的颜色背景 @using Apps.Common; @{ Layout = null; } <!DOCTYPE html> <ht ...