Project1

标题: 看来脚本闭包做的太完善也有副作用啊 [打印本页]

作者: SailCat    时间: 2018-1-14 14:47
标题: 看来脚本闭包做的太完善也有副作用啊
一直喜欢VA的脚本闭包风格,什么配置都给你写成方法,而不是一堆@开头的属性。
自己做XP插件也是用这个风格。
然后刚才想把纯事件多箱子系统http://rpg.blue/thread-404988-1-1.html移植到VA。
在花了20分钟毫无压力的弄完钱箱以后。到了物品箱的处理部分。
初始化什么都没问题了。
然后发现,VA的Window_Selectable特么的就是一个空壳子。连数据变量都没有的壳子。
你说要是空壳子也好吧,我用instance_variable_set追加变量也活的下去的对吧……
结果item_max这个方法写死了返回0……估计VA的制作者从来不想你在事件脚本中开窗口这事儿。
没办法又用Window_ItemList折腾。折腾了5分钟发现col_max又给写死了2……我去!
在对VA脚本有进一步的解读以前,暂时放弃。
作者: RaidenInfinity    时间: 2018-1-14 15:09
本帖最后由 RaidenInfinity 于 2018-1-15 00:26 编辑

面向对象中,多态(polymorphism)的概念在这里的体现是同个名字的方法在不同的类里有不同的功能。
另外,大佬也需要参考下C#,Java等语言的Interface(接口),至少也要知道下概念,就知道为啥是个空壳子了。

Window_Selectable是所有用到选项光标(加上Window_BattleLog)的窗口类的底类
item_max, col_max等方法默认是返回一个固定的参数。是类似虚拟方法(virtual method)的存在。

在基于它的子类里面,这些方法会被正式地定义。
比如Window_Command的item_max,返回的是@list.size(列表的长度)。这不就是变量吗?
所以,基本上你需要做的,是创造新的类,设置Window_Selectable为父类,然后再定义新的initialize, item_max, refresh什么的方法。
item_max写死了返回0?没问题。你弄个新的类啊。
RUBY 代码复制
  1. class Window_CustomSelectable < Window_Selectable
  2.     def item_max
  3.         @item_max
  4.     end
  5.  
  6.     def item_max=(v)
  7.         @item_max = v
  8.         refresh #重绘以体现改动
  9.     end
  10. end

然后运用这个新的类,不就行了嘛?







在事件解释器中定义类的例子。最好用一些检查来避免重复定义影响效率,比如用一个全局变量来判断。
TOPLEVEL_BINDING将eval的运行环境设置到“上层”,所以基本上和在脚本编辑器里面写的一样。
作者: chd114    时间: 2018-1-14 15:20
不是写死了,而是默认工程里面就有错误···

我前面发了2个贴提到的那个bug找出来了

  1. #==============================================================================
  2. # ■ Window_HorzCommand
  3. #------------------------------------------------------------------------------
  4. #  横向选择的指令窗口
  5. #==============================================================================

  6. class Window_HorzCommand < Window_Command
  7.   #--------------------------------------------------------------------------
  8.   # ● 设置首列位置
  9.   #--------------------------------------------------------------------------
  10.   def top_col=(col)
  11.     col = 0 if col < 0
  12. #    col =  col_max + 1 if col>col_max-1
  13.     col = index - col_max + 1 if col > col_max - 1
  14.     self.ox = col * (item_width + spacing)
  15.   end
  16. end
复制代码

注释掉的是默认工程里有bug的那句
这类bug应该还有很多
但是修复脚本好像没有最新的或者说没人搬最新的··
搜了一下VA_SP结果出来的脚本基本是一样的

感觉光修掉默认工程脚本里的bug就要先花你几个月时间了(因为有些bug如果不是特定情况下并不能找出问题,比如我这里找到的这个,横向选择如果最大项目不超过显示项目数量2个以上并且不能循环就看不出有bug···还有上个月的帖子里的,如果短时间内附加移除同一个状态会无法再次附加(因为附加状态会判定移除的状态是否有某状态,如果有就不能附加,可是移除的状态组只在附加状态时有用到···))
作者: 不死鸟之翼    时间: 2018-1-14 15:22
其实这个……不是闭包……
编程语言的闭包指的是一个函数与它的执行环境的一种绑定。比如一个就地定义的函数可捕获函数外的局部变量,其作用域会被延长,然后我们把这个函数传出去并离开定义这个函数的语境,这些被捕获的变量对这个函数仍可访问。
拓扑学上的闭包是指子集S自身的点并上它的极限点。
作者: 芯☆淡茹水    时间: 2018-1-14 16:30
本帖最后由 芯☆淡茹水 于 2018-1-14 17:21 编辑

闭包?!
(function(){script}());
是这个?
作者: 喵呜喵5    时间: 2018-1-14 19:35
本帖最后由 喵呜喵5 于 2018-1-14 19:48 编辑
  1. class A
  2.   def item_max; 2; end
  3.   def get_item_max; p item_max; end
  4. end

  5. a = A.new
  6. a.get_item_max

  7. aa = A.new
  8. def aa.item_max; 3; end
  9. aa.get_item_max
复制代码

当然,以我自己的观点,在没有查找、没有快捷键、没有高亮的事件脚本中写业务层的东西实际上是挺后患无穷的一件事,自己写着玩玩还好,实际工程中我是反对这样用的

然后闭包指的是这个意思:

  1. def get_block
  2.   a = rand
  3.   ->{ p a }
  4. end

  5. a = get_block
  6. b = get_block
  7. a.call
  8. b.call
  9. a.call
复制代码

作者: summer92    时间: 2018-1-14 21:05
现随便学好一门语言,没什么写死了写不死的,突破思想很重要




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1