卡牌游戏的后端代码是如何设计的?

2023-05-26 08:59:21 +08:00
 franklinre
像炉石传说这种游戏,各种战哄类,光环类卡牌,种类很多,组合很多,感觉有无限种组合。
例如:打出一张卡牌可以给全员+2 攻击力。
有些卡牌可以让这个效果触发两次,有些卡牌可以让这个效果*2 ,有些卡牌攻击力增长时会加血。。等等。随着游戏更新,还可以出现其他更多效果。
应该不是用 if else 写出来的吧。是怎么实现的呢?
4830 次点击
所在节点    问与答
34 条回复
fordoo
2023-05-26 09:08:21 +08:00
=各种角色属性+技能公式+配置表
clecho
2023-05-26 09:21:06 +08:00
op 想自己实现一个炉石吗? cool
InkStone
2023-05-26 09:23:05 +08:00
我自己设想的话,大概是把整个回合精确划分为多个阶段,每个动作(比如攻击)也划分为多个子阶段,然后各种修改效果都通过在这些阶段上插入回调链来实现
clecho
2023-05-26 09:24:44 +08:00
我的想法是,每张卡牌的血量费用等作为类的基础属性,战吼、亡语等作为 interface 分别给每一类效果做方法,这样一个对象就能有多个复合效果了,但是结算顺序我还没想过
andyskaura
2023-05-26 09:27:21 +08:00
你举得例子都是数值策划的工作,由他们维护角色特性,技能数值,使用效果。
wxw752
2023-05-26 09:30:59 +08:00
那些 buff 的属性肯定是分了很多种类型,然后就像配置优惠券一样,各种叠加就可以了。

不同品类的优惠券能不能叠加、谁先谁后需要看配置。感觉和优惠券唯一的区别是优惠券是减,计算 buff 加成是加减都有。
gam2046
2023-05-26 09:32:06 +08:00
以前玩三国杀的时候,考虑过。要是我的话,基本思路和#3 差不多。

先将整个游戏拆分成若干个独立的阶段,例如
洗牌、发牌、(发牌前)判定、准备、行动、结束、(结束后)判定、行动外回合等等

在每个阶段可以只完成自己的事情,比如某些 dot 的持续回合数增减,人员状态的设置等等,可能会相对简单一些。

同时为了扩展日后可能存在新的机制,采用调用链的方式,向各个独立阶段中插入自己的业务逻辑。
LandCruiser
2023-05-26 09:35:02 +08:00
我猜是这样的,特定的卡牌是对象,分别隶属于增减益类,攻击类,召唤类等等。 回合内的行为是个队列。增减溢类方法执行,攻击方法执行等等。每个类都有哪些卡牌,这个是策划定的,有个工具,可以让策划制作卡牌导入游戏进行测试
cxtrinityy
2023-05-26 09:38:36 +08:00
我觉得最具有参考意义的是万智牌,因为万智牌本身的阶段区分,各阶段允许操作,结算顺序都很清晰,这样实体和客户端就可以互相借鉴。
sunny352787
2023-05-26 09:38:39 +08:00
你是要策划的设计还是程序的实现?

策划部分就是设计很多基础效果然后想办法组合
程序就是读 Excel+有限状态机
WashFreshFresh
2023-05-26 09:43:08 +08:00
确实,有限状态机非常合适,就是会越来越复杂。
polo3584
2023-05-26 09:43:56 +08:00
数值配表,每个属性还有各种逻辑优先度,最后一个公式算出来
timelessland
2023-05-26 09:46:50 +08:00
@gam2046 我几年前做的卡牌(战棋)类游戏确实是这样设计的,回合制情况下,每一回合分为若干阶段。
每一张战场上的牌是一个单位,单位挂着各类技能,技能的构成:触发阶段,触发条件,效果;阶段内,条件满足,则触发效果;
人机对战,对面是 AI 的话,会有额外的计算方式,左右触发条件。
franklinre
2023-05-26 09:50:27 +08:00
@clecho 不是想自己实现一个炉石。就是感觉有无限种可能,想在 java 开发时借鉴一下。
akiyamamio
2023-05-26 09:54:29 +08:00
我更好奇的是,这种卡牌客户端和服务器怎么同步的?
之前看过几个录像,感觉炉石酒馆战旗是不同步的,各算各的,有时候你看到是自己赢了,结束后看战绩发现是自己输了
guoyongqiang
2023-05-26 09:54:56 +08:00
可以反编译下杀戮尖塔看看
lifeintools
2023-05-26 09:59:37 +08:00
在像炉石传说这样的卡牌游戏中,实现各种不同效果和组合通常需要更复杂的逻辑和数据结构。使用大量的 if-else 语句可能不是最好的解决方案,因为这样的代码会变得冗长、难以维护和扩展。

在实现卡牌效果和组合的过程中,常用的方法是使用面向对象编程( Object-Oriented Programming )的概念。游戏中的每个卡牌可以看作是一个对象,具有属性和方法。这样可以通过定义卡牌类( Card Class )和效果类( Effect Class )来管理不同的卡牌和它们的效果。
xianyv
2023-05-26 10:11:35 +08:00
都是效果类支撑的, 将相同效果抽取成效果类, 使用的时候,调用不同效果类就可以了, 具体的数据都做成可配置的, 通过配置,将不同卡牌进行数值上的区分.
xianyv
2023-05-26 10:13:44 +08:00
@akiyamamio 感觉是本地计算,然后谁先算的快谁上传服务器
sunny352787
2023-05-26 10:15:40 +08:00
@franklinre 所谓无限可能也只是各种基础效果的组合而已,比如做一个禁止行动的效果,那你客户端配合不同特效就有了冰冻、眩晕、僵直等一系列效果;再做个速度变化,100%就是标准速度,50%就是减速 200%就是加速,这就又是好多种冰水火等的增益和减益。每种效果再加个目标,是给敌人加还是给自己加,加一个人还是范围,那就区分出了治疗辅助还是伤害,还有光环等不同效果。

卡牌本质上也都是这些东西的组合,甚至比这些更简单,ARPG 类的比较好举例而已。

最终的代码逻辑实现基本都是状态机+读表,复杂点的行为树+读表,SB 点的 ifelse+读表,反正都是花式读表。结构上就最简单的父子继承树,最近也开始流行结构化 ECS 什么的,看个人喜好了。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/943060

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX