设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 2409|回复: 0
打印 上一主题 下一主题

[交流讨论] 基础脚本:通用备注扩展(及此脚本制作简单状态切换被动

[复制链接]

Lv2.观梦者

梦石
0
星屑
777
在线时间
70 小时
注册时间
2017-12-2
帖子
14
跳转到指定楼层
1
发表于 2021-3-15 00:24:08 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

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

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

x
本帖最后由 KurozawaRuby 于 2021-3-15 00:31 编辑

很久之前就想写的一个东西,最近找到了历史遗留的老代码,看了十几秒后删了重写了一份,发上来给大家玩。
因为也没实现什么实际功能,也需要使用者有一定的脚本能力,就发个讨论吧。

我们经常会碰到需要为游戏系统中的角色,技能,物品等新增一些额外属性的时候,之前挺多脚本的做法是在备注区(note)走正则匹配,这样做每加一个属性就需要新增一个正则和一个读取属性的方法,比较麻烦。也有大大使用元编程等手段自动生成了这些代码,但作为一个稍懂一点ruby的码农,怎么能不造个自己的轮子呢?

于是就有了这个备注扩展脚本,它可以在备注栏定义值类型、函数类型和ruby原始代码等的变量,通过变量名的Symbol获取,帮助我们走出正则解析等的迷宫,专注于游戏系统内的逻辑实现。

备注扩展脚本会在加载数据库(DataManager.load_databas)完成后初始化备注扩展的属性,扩展的属性被追加到RPG::BaseItem, RPG::Map, RPG::Tileset这三个类中,你可以通过 ext(:name) 的方式去获取。

我们可以在备注中添加 '---' 分隔符来兼容其它的脚本,如果备注中包含以三个英文减号'---'开头的行,则会将其作为分隔行。默认情况下,脚本不会解析没有分隔行的备注。有分隔行时,脚本默认会解析第一个分隔行之前的部分,而将该分隔行之后的部分作为原始备注设置回去,因此其它脚本在运行时进行正则匹配,就无法感知到备注扩展的内容。当然,我们也可以通过修改脚本内设置的常量来改变这样(需要有分隔行才解析,解析分隔行之前的部分)的策略。

变量定义规则:
首先,以'#'号开头的,且不在多行解析范围内的行为注释行。

以赋值符号 '='  '=>'  '=$'  '=@' 为界,左边的作为变量名(不允许带空格),或函数定义解析。右边作为值解析,如果右边不为空,则视为单行定义。如果右边为空,则为视为多行定义,直到下一个空行(或分隔行)为止。

比如备注区备注
  1. name1 = test

  2. name2 =
  3. t
  4. e
  5. s
  6. t
  7. ---
  8. 原始注释
复制代码

上面的代码定义了name1和name2,值都是'test'(默认设定是删除多行文本间的换行符的,这个也可以修改常量配置),对应的data对象使用 ext(:name1) 就可以拿到它的值了,而其它脚本在运行时读取的注释,只有下面的“原始注释”了


脚本支持 值类型,函数类型,模板类型,原始ruby代码 四种定义,分别对应 '='  '=>'  '=$'  '=@' 四种符号。

值类型(=):
最简单的类型,直接写就行了,单行定义时会自适应数字(整数和浮点数)和字符串,不需要你自己转换了。字符串还可以支持"#{}"的表达式,不过表达式的值是通过eval在解析时直接确定的,所以不能通过ext方法访问krubynote的值或是游戏开关变量等全局变量的值了。如果你需要那样的功能,你可以使用模板(或者函数或者原始ruby,都是一样的,只是模板最简单)。
  1. 简介 = 这个物品的名字是#{name}
  2. 最大数量 = 100
  3. 百分比 = 20.0
  4. 整数部分为0的小数 = .2

  5. ---
  6. 原始注释
复制代码


函数类型(=>)
函数类型写法比较特殊,我是按照我自己写的比较偷懒的习惯,函数名+空格+参数列表空格分隔放在赋值符号"=>"的左边,右边放ruby代码,特殊情况是单行有参数的函数可以直接写等号,看起来更好看(多行或没有参数就只能写=>了,不然解析成值类型了)
  1. add a b = a + b

  2. fun => puts self

  3. condition user =>
  4.   user.hp_rate > 20

  5. ---
  6. 原始注释
复制代码

函数类型定义拿到的是lambda,需要你传参调用(使用.call或[]调用)
比如上例调用时
  1. # 只做演示,真正使用时别忘了判空
  2. ext(:add).call(1, 2)
  3. ext(:fun)[]
  4. ext(:condition)[user]
复制代码



模板类型(=$):
运行时确定"#{}"表达式的值的字符串类型,最开始设计就是为了写复杂的简介,以下是例子:

  1. 简介 =$
  2. #{name}是比较强力的技能,冷却时间为#{ext(:cd)}回合,伤害公式为#{damage.formula}

  3. cd = 5
  4. ---
  5. 原始注释
复制代码

这样只要照着下面重写一下description方法,这个简介就生效了,你也可以就着F1文档补充一点代码,把其它的属性写全(当然,底下实现技能冷却时间还需要你自己再写写代码才行,而且默认简介框的大小。。。):
  1. class RPG::BaseItem
  2.   def description
  3.     ext(:简介) || @description
  4.   end
  5. end
复制代码



原始ruby代码(=@):
最简单粗暴强力的功能,上面所有的功能都可以写ruby代码解决,但万一没注意漏个逗号什么的调起来报错信息会很蛋疼(函数类型也有类似问题)。
  1. list =@ [1,2,3]
  2. fun =@ -> { puts self }
  3. dict =@
  4. {
  5.     a: "1",
  6.     b: 2
  7. }

  8. ---
  9. 原始注释
复制代码

代码:



赠品:




顺便:
模板类型和带#{}符号的值类型会使用HEREDOC的模板代码进行eval,使用的标志为 'hIRJi5_FOSy___' 所有多行文本内出现内容为 'hIRJi5_FOSy___' 的行时解析会出问题(我感觉是不可能出现,但是还是说一声吧)。

评分

参与人数 3+3 收起 理由
wc3215410 + 1 塞糖
负有尽 + 1 塞糖
WLian + 1

查看全部评分

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

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-4-29 15:31

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表