下载 App
《有点不一样的自走棋》开发日志2
修改于10/2016 浏览综合
上一篇减的是系统,这一篇减的是代码结构。行为系统原来是一个机制一个类,现在拆成动词、词条、行为、棋子四层。下面记的是这次怎么拆的,以及有序行为列表、Buff 即行为、连击独立判定、涌现式组合、行为预演这几件事是怎么保下来的。
- 删掉的和换掉的 端游那套行为是用类继承堆起来的:一个攻击基类,派生出普攻、突进、横扫,特殊棋子再各挂一套脚本。机制一多就出问题——每加一个"攻击之后再做点什么",就得新开一个类;数值写死在代码里;每枚棋子还要一套自己的选敌脚本;Buff 又是另一套并行系统。跑到最后,谁也说不清一个增益归谁管、什么时候消失。
手游的棋盘只剩 3×6,机制只增不减,活动期还卡着。照继承那套写法,一定做不完。于是有了下面这些删改:
类继承 → 四层职责:动词管能力,写在代码里;词条管数值,就是一串整数;行为管卡面,是一份配方;棋子管顺序,是一张有序列表。
复杂权重索敌 → 默认射程内随机:小棋盘上大家都挤在一起,站位本身就是最直接的决策,权重系统只剩工作量。
Nearest 这条目标规则 → 删掉:老配置统一迁成 Random,不留静默兜底。移动行为里的"走向最近的敌人"是另一条寻路逻辑,不属于索敌,不跟着删。
控制优先区 → 删掉:冻结不再是什么特殊状态机,它只是被 ApplyControl 塞到主动列表最前面的一个"等一轮"。好处很直接——别的行为也能手动插到冻结前面,于是有了"不解除冻结的临时解控"。
独立 Buff 系统 → Buff 即行为:持续的正面效果、负面效果、周期状态、限时的攻击偏好,全用 Buff 行为实例来装。它有类型、有名字、有图标,知道绑在谁身上、当前是多少、谁给的、能不能叠、几轮后消失。
每枚棋子一套脚本 → 公共索敌:先按阵营、存活、射程筛出合法目标,再按规则挑一个。动词只管接住挑好的结果,不再为每种棋子写选敌代码。
2. 四层职责,和一条不能越的线 层 管什么 例子 动词 通用执行能力,一共 23 个 造成伤害、移动、插入行为、修改数值 词条 整数数值,一共 25 个 伤害 3、射程 1、持续 2 轮 行为 一份配方:哪几步、什么数值、什么条件、打谁、叫什么、长什么样 抓:射程 1、伤害 3、随机挑一个敌人 棋子 属性,外加两条有序列表 顺序即性格 有一条线写进了契约:改数值不加动词。火球伤害从 3 调到 5,改词条就行;"打完把目标拽过来"这种新组合,也只是把现有动词重新排一遍。
顺手记一个坑:有伤害步骤不等于就是攻击。中毒也掉血,但它没有攻击标签。所以判断一个行为算不算攻击,看标签,不看它有没有伤害步骤。
23 个动词、25 个词条,撑起 80 个主动加 69 个被动共 149 份配方,够 第一版90 枚棋子用。配方不绑棋子——同一个"抓",装在慢盾身上是补刀,装在快刺客身上是收割。行为 ID 固定,展示名单独维护,改文案不用动存档。
- 有序行为列表:棋子的"程序" 排第一的说了算:每次只执行第一个条件成立的行为。顺序即性格。 连击每次重新判:击杀后插进来的额外行动,轮到它时还是从列表开头匹配——可能还是攻击,也可能已经变成移动。 匹配不上不花机会:筛不到合法目标就接着看下一项。但行为一旦正式开始,后面的步骤失败也不返还机会、不退回重选。 被动按实例记进度:不用会变的数组下标,改记"这个阶段处理到哪个实例"。已经走过的地方往前面插进来的不补跑,后面还没走到的能赶上。百家之学那种复制被动的配方,靠"下一轮才生效"这条明规则避开"同一阶段里自己复制自己"的死循环,而不是偷偷加一句"每轮只能触发一次"。 预演和实际是同一套:随机结果在动手前就定好,预演不改状态、不重新随机。玩家在界面上看到的步骤和数值,就是真正会发生的。一次执行里的多个步骤只算一次触发,靠执行 ID 区分。
- Buff 即行为,以及后来补上的"结果 Buff"一层 第一版把 Buff 并进行为体系时,还留着老习惯的影子:技能负责发数值,系统在背后默默记账。跑几轮就出事——修饰散落在各个执行器里,说不清该归谁清理、能不能被净化、界面上该显示成什么。
后来收了一次口:谁发的修饰@###,就归哪个 Buff 实例管。普通技能在该出手的时机授予或更新一个"结果 Buff",提交时只登记数值本身;这个结果不参加被动结算,也不会重复加一遍。纯伤害、治疗、位移、队列操作,以及只算这一次的攻击公式,当场结清,不留结果——"看法宝"每发都重新读遗物数,不会把数量写成永久成长。
这一层顺手解决了"攻击力"这个老问题:棋子没有独立攻击力,所有增减都挂在具体的行为实例上。所以加成打哪儿必须写明——第一个攻击、严格第一个、本次全部攻击、主动加被动的全部攻击、全部抓、本行为、棋子属性,各是各的规则,不能混着用。"淬火"绑的是严格第一个,第一个换人了,也要等下次结算才清掉旧的、绑上新的,不会悄悄把加成搬到新首攻上。
结果 Buff 没有"默认全部攻击"这种好事:目标规则、锁哪个实例、改哪个字段、数值多少、维持还是累计、活几轮,少填一项就不让配。界面文字也跟着改,写"第一个攻击主动伤害+1",不写成棋子攻击力上升。
- 涌现式组合:以"抓"为例 单个抓朴素得不能再朴素:射程 1,伤害 3,随机挑一个敌人。放端游里,这种技能大概就是一行配置。
但把它做成一族(BehaviorFamily=Claw)之后,事情开始起变化:
锋利爪牙:场上友方的抓伤害+1,3 变 4; 班门弄斧:身边两格内有三个不同的抓使用者,自己的抓全部翻倍,4 变 8(先加后乘,所以是 8 不是 7); 疯狂乱抓:只要手里有抓,本场连击+1。效果一轮后来源没了,增益还在,第二轮才多一次行动; 抓到你了:自己的抓射程+1,长胳膊换出来的远射程抓也吃得到; 猫抓板:之后三个不同棋子第一次用抓,各自伤害前 +2,本场有效; 长胳膊:把自己的主动原位换成抓,射程取替换那一刻到最近敌人的距离——没有新动词、没有新伤害代码,同一个抓换了个射程; 接骨术:治疗 2,目标手上有抓就计划治 3——认的是同一族,不是同一行配置。 接力是另一个样子:A、B、C 都有接力,按顺序第一次行动,A 让 B、C 的首攻各翻一倍,B 又让还没行动的 C 再翻一倍,C 最后拿到 4 倍。倍率相乘、同一来源不重复翻倍,规则一句话说得完,可这个结果不在任何单个个体身上。
这些配方没有一条写在"棋子"身上。90 枚棋子只负责按顺序装配,组合空间是配置层白送的。猫抓板还顺手推着引擎开了一条口子:要在"第一次抓打出伤害之前"发增益,才有了执行前那个只准改数值、不准改结构的窗口。
- 一个时钟:全局轮末统一扣时 删掉的东西里最省心的是计时。现在只有一种时钟:这轮所有行动都结束后,有限期的东西统一减一轮。
单次主动做完、行动点用完、被冻结占着、机会被抢走,都不提前扣; 这轮中途插进去的效果,从这轮开始算,不顺延到目标下次行动; 一轮里 3 个正常行动加 2 个额外行动,等于 5 段被动和最多 5 次主动,有限期效果只在轮末扣 1。 有个能直接验证的例子:一个 3 个行动点的棋子,行动前被冻一轮,三次主动全被"等一轮"占掉,轮末冻结自然到期。不用为"冻结到底算几回合"写任何特例。












