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

Project1

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

[已发主站] 【脚本应用类】RM外部档案变量操作系统 RMEV1.0

[复制链接]

Lv1.梦旅人

龙皇

梦石
0
星屑
50
在线时间
83 小时
注册时间
2007-8-8
帖子
2956
跳转到指定楼层
1
发表于 2012-5-3 22:32:28 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

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

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

x
本帖最后由 TERENCE 于 2012-5-3 22:35 编辑

◎前言
於是某诈尸龙来发布 RMXP 新的脚本作品了
"狠"久没来 66RPG 发现技术版变了好多,
而且好多人都不认识了,不知还会不会有故人捧个场 XXD
嘛,总之某诈尸龙始终是 RMXP 守旧派 wwwwa
此脚本如果有人已經實現,就54吧 = =
以上

◎概念与特性
RM外部档案变量操作系统『RM External Variable』,简称『RMEV
顾名思义,这些变量不是在游戏里存取,
而是藉由外部档案(.rmev)来存取一些变量数值,
该种变量特性不会因为下述几个情境,而造成变量数值消逝
  • 进入标题画面
  • 游戏关闭
  • 电脑关机

换句话说,这些变量数值一旦被修改,会长存於外部档案中
有点类似於永久标记 mark forever !!

◎用途
俺不敢说该系统用途很实用,
目前该系统使用与编辑制作的过程中有一定的繁琐,
以下是俺有可能想到的用途

  • (1) 破台後或多周目的 不同 标题 音乐
  • (2) 继承某些游戏中的数值,类似 不同代的游戏作品 RMEV 可以拿来在新作品中继承一些东西
  • (3) 多周目累加部份数值
  • (4) 游戏项目等设置
  • (5) 看过一遍的剧情能选择跳跃

P.S. (5)
很多时候我们会有以下事件类似情境设计
[ 很长很长很长的剧情对话 ] ==> [ BOSS战斗 ]

一般人设计不会在 [ BOSS战斗 ] 插入存档要求,会影响游戏流畅
但玩家却会面临 BOSS战斗 失败 GAME OVER 後,进入标题画面
读取上次存盘的地点,然後又得重看 [ 很长很长很长的剧情对话 ] = =
这是非常扰人且不符合人性的,尤其又面对 超难 [ BOSS战斗 ]

此时,如果利用 RMEV 来操作,可以做永久标记
然後设计出让 GAME OVER 後的玩家不必重复观看[ 很长很长很长的剧情对话 ]
这是一般很难在RM中实现的效果
而该(5)用途是俺开始起义设计 RMEV 的冲动

◎ RMEV 编辑器 (非随写随读)
顾名思义,用来编辑外部档案中变量群的操作软件
因为个人是用VC6.0繁体开发,又未使用utf-8或unicode模式开发,
为了避免乱码问题,大多采用英文,也没设计变量名称,抱歉 = =
RMEV编辑器 与 .rmev档案 放在同个目录下
.rmev档案名称也请务必使用英文



编辑器 下载 : (主要)
RM External Variable Editor.rar (374.5 KB, 下载次数: 106)
编辑器 source code 专案 下载 :
RMEV Editor source code.rar (34.12 KB, 下载次数: 71)

◎ RMEV 档案存取格式
为了有兴趣的人,能方便其他周边工具开发,与此介绍该档案格式
因为没有加密,长度固定,所以没有档头描述,排序也非常简单,如下
[ 4Bytes ][ 4Bytes ][ 4Bytes ][ 4Bytes ].....
共有5000组[ 4Bytes ]的变量值

◎ RGSS 脚本
RUBY 代码复制
  1. #==============================================================================
  2. # ■ External_Variable (By TERENCE龙皇)
  3. #------------------------------------------------------------------------------
  4. #  RM 外部变量操作 V1.0。
  5. #     RMEV 1.0
  6. #==============================================================================
  7.  
  8. class External_Variable
  9.  
  10.   # 外部变量档案中,最大变量的数目
  11.   MAX_VAR = 5000
  12.   # 请勿随意更动该值,除非会操作VC6.0编译『外部变量编辑器』
  13.  
  14.   #------------------------------------------------------------------------------
  15.   #  修改 MAX_VAR 必要工具 : VC6.0 ( Microsoft Visual C++ 6.0 )
  16.   #  
  17.   #  (1) 下载 『外部变量编辑器』的 source code 专案
  18.   #  (2) 使用VC6.0或直接开启 RM External Variable Editor.dsw
  19.   #  (3) 在 FileView 中,点选 Header Files 文件夹後,再选择 RM External Variable EditorDlg.h
  20.   #  (4) 在程序编写页中,找到 define        MAX_VAR        5000
  21.   #  (5) 修改该 define        MAX_VAR 的值,并保证与此处 Ruby 脚本中 MAX_VAR 值相同
  22.   #  (6) 编译『外部变量编辑器』
  23.   #  (7) 在 source code 文件中,并在 Debug 文件夹下,找出编译完成的『外部变量编辑器』
  24.   #  (8) 旧的 .rmev 档,可能会不适用於新编译的『外部变量编辑器』,恐会造成出错
  25.   #------------------------------------------------------------------------------
  26.  
  27.   #--------------------------------------------------------------------------
  28.   # ● 定义实例变数
  29.   #--------------------------------------------------------------------------
  30.   attr_reader   :filename                # .rmev 档名
  31.   #--------------------------------------------------------------------------
  32.   # ● 初始化物件
  33.   #     fstr  : 外部变量档案名称
  34.   #--------------------------------------------------------------------------
  35.   def initialize(fstr = "ExternalVar")
  36.     if fstr.is_a?(String)
  37.       @filename = fstr+".rmev"
  38.     else
  39.       nfstr = "ExternalVar"
  40.       @filename = nfstr+".rmev"
  41.     end
  42.     # 档案不存在的情况下
  43.     unless File.exist?(@filename)
  44.       create_rmev(@filename[0, @filename.length-5], 0)
  45.     end
  46.   end
  47.   #--------------------------------------------------------------------------
  48.   # ● 读取「目前 RMEV 档案」外部变量
  49.   #     index : 变量 ID  (编号范围 : 0001 ~ 5000)
  50.   #--------------------------------------------------------------------------
  51.   def [](index)
  52.     # index 范围处理
  53.     index = index_limit(index)
  54.     # 主处理
  55.     data = File.read(@filename, 4, 4*(index-1))
  56.     k = data.unpack("i")
  57.     return k[0]
  58.   end
  59.   #--------------------------------------------------------------------------
  60.   # ● 读取「目前 RMEV 档案」外部变量   以开关访问
  61.   #     switch_id : 开关 ID  (编号范围 : 0001 ~ 5000)
  62.   #--------------------------------------------------------------------------
  63.   def get_bool(switch_id)
  64.     # index 范围处理
  65.    switch_id = index_limit(switch_id)
  66.     # 主处理
  67.     data = File.read(@filename, 4, 4*(switch_id-1))
  68.     k = data.unpack("i")
  69.     if k[0]==0
  70.       return false
  71.     end
  72.     return true
  73.   end
  74.   #--------------------------------------------------------------------------
  75.   # ● 更新「目前 RMEV 档案」外部变量
  76.   #     index : 变量 ID  (编号范围 : 0001 ~ 5000)
  77.   #     value : 变量数值 (数值范围 : -2147483648 ~ 2147483647)
  78.   #--------------------------------------------------------------------------
  79.   def []=(index, value)
  80.     # 变量数值布林转换
  81.     blvar = bool_to_i(value)
  82.     # int 范围处理
  83.     lvar = int_range(blvar)
  84.     # index 范围处理
  85.     index = index_limit(index)
  86.     # 主处理
  87.     File.open(@filename, "r+b") do |f|
  88.     f.pos=4*(index-1)
  89.     f.write([lvar].pack("i"))
  90.     end
  91.   end
  92.   #--------------------------------------------------------------------------
  93.   # ● 建立新的外部变量档案
  94.   #     newfstr   : 外部变量档案名称
  95.   #     initvalue : 初始值
  96.   #--------------------------------------------------------------------------
  97.   def create_rmev(fstr = "ExternalVar", initvalue = 0)
  98.     fstr += ".rmev"
  99.     # 变量数值布林转换
  100.     blvar = bool_to_i(initvalue)
  101.     # int 范围处理
  102.     lvar = int_range(blvar)
  103.     # 档案存在的情况下,不处理
  104.     if File.exist?(fstr)
  105.       return
  106.     end
  107.     # 档案不存在的情况下,建立新的外部变量档案
  108.     File.open(fstr, "wb") do |f|
  109.       for i in 1..MAX_VAR
  110.         f.write([lvar].pack("i"))
  111.       end
  112.     end
  113.   end
  114.   #--------------------------------------------------------------------------
  115.   # ● 初始「目前 RMEV 档案」 中所有变量
  116.   #     initvalue : 初始值
  117.   #--------------------------------------------------------------------------
  118.   def init_rmev(initvalue = 0)
  119.     # 变量数值布林转换
  120.     blvar = bool_to_i(initvalue)
  121.     # int 范围处理
  122.     lvar = int_range(blvar)
  123.     # 主处理
  124.     File.open(@filename, "wb") do |f|
  125.       for i in 1..MAX_VAR
  126.         f.write([lvar].pack("i"))
  127.       end
  128.     end
  129.   end
  130.   #--------------------------------------------------------------------------
  131.   # ● 选择「目前 RMEV 档案」
  132.   #     fstr  : 外部变量档案名称
  133.   #--------------------------------------------------------------------------
  134.   def select_rmev(fstr = "ExternalVar")
  135.     fstr += ".rmev"
  136.     # 档案不存在的情况下
  137.     unless File.exist?(fstr)
  138.       create_rmev(fstr, 0)
  139.     end
  140.     @filename = fstr
  141.   end
  142.   #--------------------------------------------------------------------------
  143.   # ● 获取「目前 RMEV 档案」 名称
  144.   #      (不含副档名)
  145.   #--------------------------------------------------------------------------
  146.   def current_rmev
  147.     return @filename[0, @filename.length-5]
  148.   end
  149.  
  150.   private # 私有方法
  151.   #--------------------------------------------------------------------------
  152.   # ● 布林值转换
  153.   #--------------------------------------------------------------------------
  154.   def bool_to_i(value)
  155.     if value.is_a?(FalseClass)
  156.       return 0
  157.     elsif value.is_a?(TrueClass)
  158.       return 1
  159.     end
  160.     return value
  161.   end
  162.   #--------------------------------------------------------------------------
  163.   # ● 系统有符号 int 范围调整
  164.   #--------------------------------------------------------------------------
  165.   def int_range(value)
  166.     if value < -2147483648
  167.       return int_renegative(value) # -2147483648
  168.     end
  169.     if value > 2147483647
  170.       return int_repositive(value) # 2147483647
  171.     end
  172.   end
  173.   #--------------------------------------------------------------------------
  174.   # ●  int 正数范围调整 大於 0x 7F FF FF FF 忽略进位
  175.   #--------------------------------------------------------------------------
  176.   def int_repositive(value)
  177.     if value > 2147483647
  178.       len = 2147483647*2+2
  179.       space = value - 2147483647
  180.       rem = (len + space)%len
  181.       return -2147483648+rem-1
  182.     end
  183.     return value
  184.   end
  185.   #--------------------------------------------------------------------------
  186.   # ●  int 负数范围调整 小於 0x 80 00 00 00 忽略借位
  187.   #--------------------------------------------------------------------------
  188.   def int_renegative(value)
  189.     if value < -2147483648
  190.       n = (-value)/2147483648
  191.       if n%2 == 0
  192.         return value+n*2147483648
  193.       else
  194.         rem = (-value)%2147483648
  195.         return 2147483647-rem+1
  196.       end
  197.     end
  198.     return value
  199.   end
  200.   #--------------------------------------------------------------------------
  201.   # ● index 范围处理
  202.   #--------------------------------------------------------------------------
  203.   def index_limit(index)
  204.     if index < 1   
  205.       return MAX_VAR-(-1*index)%MAX_VAR     
  206.     end
  207.     if index > MAX_VAR
  208.       return (index-1)%MAX_VAR+1  
  209.     end
  210.     return index
  211.   end
  212. end


◎ 使用说明
(1) initialize
# 初始化物件,档案默认指向 ExternalVar.rmev
External_Variable.new
# 初始化物件,自指定.rmev文件,参数无须填上副档名
External_Variable.new(".rmev档案名")
当档案不存在时,会自动生成.rmev档,所有变量值等於 0
example:
  1. aa = External_Variable.new
  2. p aa.filename
  3. # => "ExternalVar.rmev"
  4. aa = External_Variable.new("MyVar.rmev")
  5. p aa.filename
  6. # => "MyVar.rmev"
复制代码
(2) 基本变量操作方法
与 $game_variables[id] 操作相似,
[](变量ID)                 # 读取「目前 RMEV 档案」外部变量
[]=(变量ID, 变量值) # 写入「目前 RMEV 档案」外部变量

但由於.rmev是由系统有符号的int(4Bytes大小)来纪录,所以
数值范围 : -2147483648 ~ 2147483647

该系统变量也能接受布林(开关)值
输入 布林的true(开关的ON)        会被转置成 1
输入 布林的false(开关的OFF)        会被转置成 0
example:
  1. aa = External_Variable.new
  2. aa[100] = 1234
  3. aa[100] += 1000
  4. p aa[100]
  5. # => 5234
  6. aa[100] = true
  7. p aa[100]
  8. # => 1
  9. aa[100] = false
  10. p aa[100]
  11. # => 0
复制代码
(3) 以开关方法访问变量方法
.get_bool(变量ID)
变量数值中,除了 0 以外,全部视为回传 true
example:
  1. aa = External_Variable.new
  2. aa[200] = 0
  3. p aa.get_bool(200)
  4. # => false
  5. aa[200] = 1
  6. p aa.get_bool(200)
  7. # => true
  8. aa[200] = 123
  9. p aa.get_bool(200)
  10. # => true
  11. aa[200] = -123
  12. p aa.get_bool(200)
  13. # => true
复制代码
(4) 建立新的 RMEV 档案
# 默认产生ExternalVar.rmev,所有变量的默认初值为 0
.create_rmev
# 产生自指定.rmev文件(参数无须填上副档名),所有变量的默认初值为 0
.create_rmev(".rmev档案名")
# 产生自指定.rmev文件(参数无须填上副档名),自指定所有变量初值
.create_rmev(".rmev档案名", 所有变量的初始值)

上述档案存在的情况下,不处理该方法
而且必须注意,物件指向档案,不会指向新的建立新的 RMEV 档
example:
  1. aa = External_Variable.new
  2. p aa.filename
  3. # => "ExternalVar.rmev"
  4. aa.create_rmev("MyVar", 123)
  5. p aa.filename
  6. # => "ExternalVar.rmev"
复制代码
(5) 统一目前 RMEV 档案中所有变量数值
# 设置所有变量的默认初值为 0
.init_rmev
# 设置自指定所有变量值
.init_rmev(所有变量的值)

参数一样能接受布林(开关)值
自转换 1 或 0
example:
  1. aa = External_Variable.new
  2. aa.init_rmev
  3. p aa[10] + aa[20]
  4. # => 0
  5. aa.init_rmev(15)
  6. p aa[10] + aa[20]
  7. # => 30
  8. aa.init_rmev(true)
  9. p aa[10] + aa[20]
  10. # => 2
复制代码
(6) 改变目前指向(选择) RMEV 档案
# 默认选择ExternalVar.rmev
.select_rmev
# 选择自指定.rmev文件(参数无须填上副档名)
.select_rmev(".rmev档案名")

上述选择的档案不存在时,
会自动生成档案,且所有变量的默认初值为 0
example:
  1. aa = External_Variable.new
  2. p aa.filename
  3. # => "ExternalVar.rmev"
  4. aa.select_rmev("MyVar")
  5. p aa.filename
  6. # => "MyVar.rmev"
  7. aa.select_rmev
  8. p aa.filename
  9. # => "ExternalVar.rmev"
复制代码
(7) 获取目前指向 RMEV 档案名称
.current_rmev # (不含副档名)
.filename # (含副档名)
example:
  1. aa = External_Variable.new("MyVar")
  2. p aa.filename
  3. # => "MyVar.rmev"
  4. p aa.current_rmev
  5. # => "MyVar"
  6. aa.select_rmev
  7. p aa.current_rmev
  8. # => "ExternalVarv"
复制代码
(8) 其他注意事项
当参数变量ID超出范围(1至5000)时,会自动调整至标准范围,如下
10001
10002
...
14999
15000
5001
5002
...
9999
10000
1
2
...
4999
5000
-4999
-4998
...
-1
0
-9999
-9998
...
-5001
-5000

当给予变量数值int(有符号的4Bytes大小)超过 -2147483648 ~ 2147483647 范围时,
会以循环值处理,与电脑超出4Bytes有限空间时的表现相同
example:
  1. 超越2147483647(0x7FFFFFFF),会从-2147483648(0x80000000)开始往上
  2. 当递增至-1(0xFFFFFFFF),从0(0x00000000)继续开始往上
  3. 低於-2147483648(0x80000000),则会从2147483647(0x7FFFFFFF)开始递减
  4. 当递减至0(0x00000000),从-1(0xFFFFFFFF)继续开始递减
复制代码


◎范例工程
Project1.rar (185.16 KB, 下载次数: 107)
本人使用繁体环境开发,若有乱码困扰,请使用APP

◎後记
由於RMEV,在诸多DEBUG之际,会影响前後因果
所以DEBUG过程,都要开启RMEV编辑器,而且软件不是随写随读,要反覆开启软件和修改,
过程很反锁,而且很有可能漏修,

以後可能还需要,在游戏中新增给RMEV系统的DEBUG菜单(类似F9 那样的界面
方便游戏DEBUG过程,可以不必开启RMEV编辑器,
不过俺有限时间,研究生的生活繁忙,
若有心人,帮忙设计吧 XD

点评

覆盖文件的话不是 overwrite 么?  发表于 2012-5-4 18:29

评分

参与人数 1+6 收起 理由
Shy07 + 6 主站收录

查看全部评分


                签名图来自:無限のファンタジア
                 我的RMXP专题空间--龙使传说

Lv1.梦旅人

梦石
0
星屑
50
在线时间
90 小时
注册时间
2012-4-29
帖子
133
2
发表于 2012-5-3 22:43:37 | 只看该作者
抢个沙发 再慢慢看


‘‘──哦他妈的耶于2012-5-3 22:47补充以下内容

我承认,我没看懂。。。唉。。
’’

我的优点:勇于认错;缺点:坚决不改。
回复 支持 反对

使用道具 举报

Lv1.梦旅人

龙皇

梦石
0
星屑
50
在线时间
83 小时
注册时间
2007-8-8
帖子
2956
3
 楼主| 发表于 2012-5-3 23:00:06 | 只看该作者
哦他妈的耶 发表于 2012-5-3 22:43
抢个沙发 再慢慢看


                签名图来自:無限のファンタジア
                 我的RMXP专题空间--龙使传说
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
115 小时
注册时间
2011-8-25
帖子
36
4
发表于 2012-5-3 23:01:51 | 只看该作者
是让变量很多么?不过已经够用了。
回复 支持 反对

使用道具 举报

Lv1.梦旅人

龙皇

梦石
0
星屑
50
在线时间
83 小时
注册时间
2007-8-8
帖子
2956
5
 楼主| 发表于 2012-5-3 23:02:37 | 只看该作者
102045301 发表于 2012-5-3 23:01
是让变量很多么?不过已经够用了。

不是
性質不同

                签名图来自:無限のファンタジア
                 我的RMXP专题空间--龙使传说
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
49
在线时间
152 小时
注册时间
2012-1-12
帖子
456
6
发表于 2012-5-3 23:38:42 | 只看该作者
不懂脚本就是不好,但我又没耐心去学……
回复 支持 反对

使用道具 举报

Lv2.观梦者

梦石
0
星屑
681
在线时间
791 小时
注册时间
2011-10-20
帖子
2394

开拓者

7
发表于 2012-5-4 18:12:09 | 只看该作者
不知道干嘛用的,不过看了下脚本,好像是把变量变成数组然后File保存文件,其实直接用save_data(obj, filename)
更方便
欢迎点此进入我的egames.wink.ws,有RMQQ堂等

[url=http://rpg.blue/thread-317273-1-1.html]短篇八-赶选

http://yun.baidu.com/share/link?shareid=2158225779&uk=169642147&third=0


历险ARPG赢回你的疆域新的战斗模式?…………点击这里:[宋乱贼狂 for QQ堂]
http://rpg.blue/group-368-1.html
programing ....?
[url=http://rpg.blue/thrd-234658-1-1.html]
回复 支持 反对

使用道具 举报

Lv6.析梦学徒

Fuzzy Ginkgo
Taciturn Knight

梦石
0
星屑
60475
在线时间
1933 小时
注册时间
2010-6-26
帖子
1605

烫烫烫开拓者

8
发表于 2012-5-4 18:26:30 | 只看该作者
end55rpg 发表于 2012-5-4 18:12
不知道干嘛用的,不过看了下脚本,好像是把变量变成数组然后File保存文件,其实直接用save_data(obj, filen ...

这样的话每次写入都要保存整个文件。19 kb 呢,不停的写入总不太好吧。

另外觉得楼主的说明太过复杂了反而搞得新手看起来不太懂。

点评

哦  发表于 2012-5-4 18:27
我的言论只代表我个人的观点,不代表雇主及/或任何第三方的立场。
Opinions expressed are solely my own and do not express the views or opinions of my employer and/or any third parties.
捐赠 | GitHub
回复 支持 反对

使用道具 举报

Lv3.寻梦者

孤独守望

梦石
0
星屑
3121
在线时间
1534 小时
注册时间
2006-10-16
帖子
4321

开拓者贵宾

9
发表于 2012-5-4 18:59:12 手机端发表。 | 只看该作者
Mark。目前 RUBY 的文件格式已经判明,可以不用自己新定义文件格式。此外,说明写太复杂了……我们嫌繁可是新手看不懂……
菩提本非树,明镜本非台。回头自望路漫漫。不求姻缘,但求再见。
本来无一物,何处惹尘埃。风打浪吹雨不来。荒庭遍野,扶摇难接。
不知道多久更新一次的博客
回复 支持 反对

使用道具 举报

Lv1.梦旅人

龙皇

梦石
0
星屑
50
在线时间
83 小时
注册时间
2007-8-8
帖子
2956
10
 楼主| 发表于 2012-5-4 19:26:30 | 只看该作者
本帖最后由 TERENCE 于 2012-5-4 19:52 编辑
orzfly 发表于 2012-5-4 18:26
这样的话每次写入都要保存整个文件。19 kb 呢,不停的写入总不太好吧。

另外觉得楼主的说明太过复杂了反 ...


嗯~俺RM中
写入 是采 r+b
即是 io 对文件 直接 写入要 想写的地方
不是整份档案读入ruby的变量,然後再写

嗯~太过复杂,我也是这麽认为
俺不太擅长 写 这种 比较抽象和看不见 的 东西 XD
写出来 连俺都 看得 有点头疼 ( 看起来像是 写论文啥的 = ="< 研究生泛职业病


‘‘──TERENCE于2012-5-4 19:33补充以下内容
@IamI

原来可以不用自己新定义文件格式 XD
俺没注意到的说

嘛~说明写太复杂~ 确实
我也承认这帖,也不适合给新手看
就像 10 楼 俺说的一样
不擅长 写 这种 比较抽象和看不见 的 东西 XD

含请多多见谅了~ ^^::a
如果有比较 好的说法 和 解释,欢迎请大大们 懂俺这鬼玩意儿 补充说明 ><
’’

                签名图来自:無限のファンタジア
                 我的RMXP专题空间--龙使传说
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-4-25 07:42

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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