查看: 8499|回复: 12

[推荐问答] 避免套娃!使用事件系统“条件分歧”指令的小技巧

[复制链接]

遠航の猫咪

梦石
3
星屑
26979
在线时间
2425 小时
注册时间
2005-10-15
回帖
989

开拓者

发表于 2020-6-13 17:15:34 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×
本帖最后由 SailCat 于 2020-6-13 17:30 编辑

其实一直想写一下这个FAQ,自己遇到过这样的问题,也被提问过这样的问题,昨天看R叔的考场7解说有感而发,就整理一下吧。

RM的“条件分歧”指令(Conditional branch)是所有RM通用的基础指令,也是非常重要的一个。因为只有有了这个指令,我们才可以在事件执行列表中避开顺序结构,实现分支结构。当然,自带分支结构的指令如“显示选择项”“战斗处理”就不多说了。
但是这个指令的局限性很大,主要原因是,除非使用条件分歧里的脚本,否则一个“条件分歧”指令只能判定一项内容,并且对于除了金钱、步数、计时器以外的其他游戏对象数值性的判断,没有直接接口,只有“变量”这一个选择。
这就要求在使用条件分歧时,不得不用临时变量代入要判断的数值,然后再去判断,本来这也没什么。
但是如果是两个游戏对象数值相比较呢?(用两个变量就是了)
但是如果是两组游戏对象数值相比较呢?比如角色的X、Y,事件的X、Y(用四个变量就是了)
但是如果有多个条件要同时满足呢?
但是如果有多个条件要满足一个呢?
但是如果有多个条件对应多个分支呢?
这些要求都是挺常见的吧,但是如果没有技巧,就很容易写出套娃指令。
套娃指令一个是逻辑不好管理,另一个是套的层数多了以后,缩进多了,在编辑器里显示不完整了,这非常要命。

诚然变量5K个是用不完的,但是变量太多不利用工程管理,而且一个变量用完就扔也很浪费。
因此在这里,介绍一个使用“条件分歧”指令的技巧。说是使用这个指令的技巧,但是其实大部分技巧性内容和“条件分歧”这条指令本身没有任何关系,是使用其他相关指令的技巧为“条件分歧”来服务。
用到的指令主要有:变量操作、标签、标签跳转、中断事件处理
我自己在R7考场中使用了下面技巧中的部分,逐一解说一下:

1. 利用“加法原理”实现多重判断
加法原理就是,当多个条件满足为非0,不满足为0时,把它们全加起来,只要有一个条件被满足,其结果就肯定不是0
例如:判断是否有至少一个NPC站歪了(脸没有朝向下):
我们知道,若用变量代入一个角色的朝向,下为2,左为4,右为6,上为8
于是我们可以通过代入朝向再减2的方法,来把这个变量值转换成“真为非0,假为0”的情况

传统套娃做法:
开关操作:[0001:立正] = OFF
条件分歧:[EV001]为 朝向下
    条件分歧:[EV002]为 朝向下
        条件分歧:[EV003]为 朝向下
            开关操作:[0001:立正] = ON
        分歧结束
    分歧结束
分歧结束
条件分歧:开关[0001:立正] 为 OFF
    ……(需要的处理)
分歧结束

加法原理做法:
变量操作:[0001:NPC朝向] = [EV001]的朝向
变量操作:[0001:NPC朝向] += [EV002]的朝向
变量操作:[0001:NPC朝向] += [EV003]的朝向
如果这些NPC都是脸朝下的,其最终的结果是你加了几次,就有几个2,这里我们加了3次,所以最后和6比较(就是减去6和0比较)
条件分歧:变量[0001:NPC朝向]为 6 以外
      ……
分歧结束


2. 利用“乘法原理”实现多重判断(多个满足所有)
乘法原理和加法原理恰好相反,当多个条件满足为非0,不满足为0时,把它们全乘起来,只要有一个条件没有被满足,其结果就肯定是0
例如:判断是不是所有箱子都在正确的位置上(R7考题,正确的位置地形标志不为0):

传统套娃做法:
变量操作:[0001:地形标志] = [EV006]的地形标志
条件分歧:[0001:地形标志]为 1 以上
    变量操作:[0001:地形标志] = [EV007]的地形标志
    条件分歧:[0001:地形标志]为 1 以上
        变量操作:[0001:地形标志] = [EV008]的地形标志
        条件分歧:[0001:地形标志]为 1 以上
            变量操作:[0001:地形标志] = [EV009]的地形标志
            条件分歧:[0001:地形标志]为 1 以上
                ……(R7有8个箱子,这个套娃要写8层)
            分歧结束
        分歧结束
    分歧结束
分歧结束

乘法原理做法:
变量操作:[0002:地形标志] = [EV006]的地形标志
变量操作:[0002:地形标志] *= [EV007]的地形标志
变量操作:[0002:地形标志] *= [EV008]的地形标志
变量操作:[0002:地形标志] *= [EV009]的地形标志
……(上述指令复制粘贴8次即可)
条件分歧:变量[0002:地形标志]为 0 以外
      ……(推箱子成功了)
分歧结束


3. 利用变量复用技巧减少变量的使用数目
常见例子,判断某人和某NPC是不是在一起

传统做法:
变量操作:[0003:角色X] = 角色 的 X坐标
变量操作:[0004:角色Y] = 角色 的 Y坐标
变量操作:[0005:事件X] = 本事件 的 X坐标
变量操作:[0006:事件Y] = 本事件 的 Y坐标
条件分歧:变量[0003:角色X] == 变量[0005:事件X]
    条件分歧:变量[0004:角色Y] == 变量[0006:角色Y]
        ……(在一起啊在一起)
    分歧结束
分歧结束

在这个判断中,我们一共用到了4个变量,全是用完就扔的临时变量,非常浪费也不利于管理

变量复用做法:
变量操作:[0003:角色坐标判断] = 角色 的 X坐标
变量操作:[0003:角色坐标判断] -= 本事件 的 X坐标
变量操作:[0003:角色坐标判断] *= 512 (注:地图最大500x500)
变量操作:[0003:角色坐标判断] += 角色 的 Y坐标
变量操作:[0003:角色坐标判断] -= 本事件 的 Y坐标
条件分歧:变量[0003:角色坐标判断] == 0
    ……(在一起啊在一起)
分歧结束

类似的,用这个方法,亦可判断角色和事件是不是在一条直线上,甚至是不是在一条对角线上
在一条直线上:
变量操作:[0003:角色坐标判断] = 角色 的 X坐标
变量操作:[0003:角色坐标判断] -= 本事件 的 X坐标
条件分歧:变量[0003:角色坐标判断] == 0
    ……(在一条纵线上)
除此以外的情况下
    变量操作:[0003:角色坐标判断] = 角色 的 Y坐标
    变量操作:[0003:角色坐标判断] -= 本事件 的 Y坐标
    条件分歧:变量[0003:角色坐标判断] == 0
        ……(在一条横线上)
    分歧结束
分歧结束
注意这里的套娃是无法避免的,防止将重合判定成在同一条直线上的情况

在一条对角线上:
对角线有两种,一种是[4,5][5,4][6,3][3,6]此时X+Y为定值,另一种是[3,6][4,7][2,5][0,3]此时X-Y为定值
变量操作:[0003:角色坐标判断] = 角色 的 X坐标
变量操作:[0003:角色坐标判断] += 角色 的 Y坐标
变量操作:[0003:角色坐标判断] -= 本事件 的 X坐标
变量操作:[0003:角色坐标判断] -= 本事件 的 Y坐标
条件分歧:变量[0003:角色坐标判断] == 0
    ……(在一条对角线上)
除此以外的情况下
    变量操作:[0003:角色坐标判断] = 角色 的 X坐标
    变量操作:[0003:角色坐标判断] -= 角色 的 Y坐标
    变量操作:[0003:角色坐标判断] -= 本事件 的 X坐标
    变量操作:[0003:角色坐标判断] += 本事件 的 Y坐标
    条件分歧:变量[0003:角色坐标判断] == 0
        ……(在另外一条对角线上)
    分歧结束
分歧结束


4. 卫语句处理,减少缩进
传送要判断魔法,住宿要判断金钱,怎么办
如果金钱在20以上,所有的分支全放在缩进里?否则放在另一个缩进里
你们被XP的默认脚本商店处理里面的难看写法带歪了
这种需求用卫语句解决就好了。

传统做法:
条件分歧:金钱 >= 20
    显示选择项:你住吗?是,否
    [是] 的情况下
         文章:欢迎光临
         增减金钱:-20
         完全回复:全体
    [否] 的情况下
         文章:谢谢惠顾
    分歧结束
除此以外的情况下
    文章:没钱住什么店
分歧结束

这种需求在处理不长的情况下还好,一旦处理很长需要翻很多页,定位就很麻烦。我们可以把其中一个很快会结束的短处理做成卫语句,这样长的处理就不需要缩进,外部的逻辑是最不容易错的。

卫语句做法:
条件分歧:金钱 < 20 (注意条件变了)
    文章:没钱住什么店
    中断事件处理
分歧结束
显示选择项:你住吗?是,否
[是] 的情况下
     文章:欢迎光临
     增减金钱:-20
     完全回复:全体
[否] 的情况下
     文章:谢谢惠顾
分歧结束


5. 多标签实现switch-case型判断(多分支)
R7考场里面有一个选择后传送到哪个地方的事件。选择的显示本身就要分4种情况,选择后判断传送又有3种情况,如果不优化指令,那相同的传送代码就要复写12遍,非常容易整错。尤其是有剧情限定传送的情况下

尽管“显示选择项”指令自己就是个switch case结构,但如果它在套娃里面就很麻烦(如R7),另外还有些自制系统,需要根据变量的不同值实现不同的操作。脚本中,如果不想用case....when的情况下,我们可以用if....elsif来模拟。但问题就在于,事件系统里没有elsif,只有else……
只有if和else的情况,书写这种分支结构,出来的结果是这样的

传统做法:
条件分歧:变量[0005] == 1
    注释:吃鸡
除此以外的情况下
    条件分歧:变量[0005] == 2
        注释:喝汤
    除此以外的情况下
        条件分歧:变量[0005] == 3
            注释:恰烂分
        除此以外的情况下
            条件分歧:变量[0005] == 4
                注释:撒汤
            除此以外的情况下
                条件分歧:变量[0005] == 5
                    注释:酱油
                分歧结束
            分歧结束
        分歧结束
    分歧结束
分歧结束

如果有好多个选项,想想要套多少娃吧?

但是如果我们活用标签和标签跳转这两个指令,就可以把这个结构,不管可能有多少层,全部统统打散,做成顶层结构
条件分歧:变量[0005] == 1
    标签跳转:吃鸡
分歧结束
条件分歧:变量[0005] == 2
    标签跳转:喝汤
分歧结束
条件分歧:变量[0005] == 3
    标签跳转:恰烂分
分歧结束
条件分歧:变量[0005] == 4
    标签跳转:撒汤
分歧结束
条件分歧:变量[0005] == 5
    标签跳转:酱油
分歧结束
标签:吃鸡
……
标签跳转:结束
标签:喝汤
……
标签跳转:结束
标签:恰烂分
……
标签跳转:结束
标签:撒汤
……
标签跳转:结束
标签:酱油
……
标签:结束
……

事实上,我在06年开发“公共事件的技能特效”的时候,就使用了这个方法,可以将全游戏所有技能的特效写在一个公共事件里,而且不会引起多余的判断和执行效率问题。


好了,以上就是给大家分享的事件系统中使用“条件分歧”指令的小技巧,希望有用。

评分

参与人数 19星屑 +100 赞 +19 收起 理由
ghostboy + 1 我很赞同
鑫の尘埃 + 1 我很赞同
miantouchi + 1 精品文章
冥墨幽 + 1 塞糖
涅炎 + 1 实践出真知
zyf722 + 1 精品文章
enghao_lim + 1 塞糖
Six_Fish + 1 赞美猫姐
ssrwkx + 1 精品文章
89444640 + 1 塞糖

查看全部评分

SailCat (小猫子·要开心一点) 共上站 24 次,发表过 11 篇文章 上 次 在: [2006年01月28日11:41:18 星期六] 从 [162.105.120.91] 到本站一游。
梦石
1
星屑
15880
在线时间
5417 小时
注册时间
2017-2-18
回帖
413
发表于 2020-6-13 18:05:09 | 显示全部楼层
来学习了
回复

使用道具 举报

梦石
1
星屑
23281
在线时间
9566 小时
注册时间
2012-6-19
回帖
7020

开拓者短篇九导演组冠军

发表于 2020-6-13 23:44:44 | 显示全部楼层
Snipaste_2020-06-13_23-43-19.png

我直接写了个脚本来处理嵌套地狱……

https://rpg.blue/home.php?mod=sp ... o=blog&id=13466

点评

VA有command_108是吧……XP默认系统没有,这就很扯了……  发表于 2020-6-14 23:30
回复 2 0

使用道具 举报

梦石
0
星屑
35248
在线时间
4171 小时
注册时间
2007-12-15
回帖
9489
发表于 2020-6-14 08:51:12 | 显示全部楼层
1、2加朝向那个,现在是明白,撂爪就忘ORZ
3判断坐标我还真是4个一起ORZ,不过由于xp是先有坐标变化后有位移,模拟动作游戏的感觉极差,敌人没碰到就掉血,按照周围坐标来判断,敌人大小又不是矩形,无法做像素级别判断,所以放弃了。
4的住宿就是,分歧套很长,每次找都麻烦,以后换这个方法了,写好的就不折腾了。
5的那个根据变量去分歧,确实是好方法,菜刀给我的也是这个方法,把以前很多一两句话的公用事件,放在一起了。这样所有的道具调用公用事件全在这里,找起来方便多了
01.png
回复

使用道具 举报

梦石
0
星屑
4638
在线时间
488 小时
注册时间
2017-7-7
回帖
134

R考场第七期纪念奖

发表于 2020-6-14 11:31:37 | 显示全部楼层
使用条件分歧避免套娃是怎么回事?条件分歧相信大家都很熟悉了,但是使用条件分歧避免套娃是怎么回事?下面就让小编带大家了解一下吧。使用条件分歧避免套娃,其实就是利用“加法”“乘法”原理实现多重判断、变量复用减少变量数目、卫语句减少缩进、多标签实现switch-case型判断的技巧,大家可能很惊讶,小编也非常惊讶呢。这就是关于使用条件分歧避免套娃的事情了,大家有什么想法呢,欢迎和小编一起讨论哦!
-
咳咳,开个玩笑
其实现在一看到,发现技巧都是会的,在很多地方看过,甚至标签跳转大法还是自己无师自通的
然鹅一转头这些都给忘了,一看就会一做就废好像就是用来形容我的
果然基本功不行,用得多不至于忘的,是自己过于怠惰了
总之赞美猫姐,然后对自己说声加油吧…
回复

使用道具 举报

梦石
0
星屑
8003
在线时间
1184 小时
注册时间
2007-7-29
回帖
2014
发表于 2020-6-14 14:06:51 | 显示全部楼层
虽然自个儿用不上不过这个对很多新手中新手帮助很大,顶上去。
回复

使用道具 举报

梦石
2
星屑
6777
在线时间
501 小时
注册时间
2018-3-23
回帖
487

R考场第七期银奖

发表于 2020-6-14 15:16:16 | 显示全部楼层
是真大佬!
(虽然我坑麻烦的流程都丢给脚本了23333
祝好。
回复

使用道具 举报

梦石
24
星屑
14253
在线时间
8180 小时
注册时间
2011-7-2
回帖
449

超评测评委极短28评委极短27评委MZ评测员极短26评委极短25评委极短24评委极短23评委极短22评委R考场第七期纪念奖开拓者

发表于 2020-6-14 21:31:27 | 显示全部楼层
感谢分享!这是通过做工程的积累才能获得的可贵经验了。
【探索解谜游戏】《NULL》
-------------------------------------------------------------
回复

使用道具 举报

梦石
0
星屑
15061
在线时间
2231 小时
注册时间
2019-1-24
回帖
964

R考场第七期纪念奖

发表于 2020-6-14 22:44:58 | 显示全部楼层
哈哈,新手的想法是,眼睁睁看着大家套娃,看着也不得劲的样子,确无力反抗,只能用这套娃,因为不会别的!
这下好了,列出了这么多办法,如果以后遇到类似情况,应定要试试上面的方法!
回复

使用道具 举报

梦石
0
星屑
2876
在线时间
172 小时
注册时间
2020-8-9
回帖
100
发表于 2021-7-20 22:51:24 | 显示全部楼层
判断某人和npc是否在一起那里为啥要乘512呀,如果判断标准是x,y坐标都相同的话,那不乘不是也可以得到相同的结果嘛
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部