查看: 3902|回复: 8

[已经解决] 天资有限,系统脚本无法理解。

[复制链接]
梦石
0
星屑
208
在线时间
420 小时
注册时间
2020-1-11
回帖
175
发表于 2020-10-5 07:56:22 | 显示全部楼层 |阅读模式

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

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

×
本帖最后由 alianlord 于 2020-10-5 08:10 编辑

#==============================================================================
# ■ Game_Troop
#------------------------------------------------------------------------------
#  管理敌群和战斗相关资料的类,也可执行如战斗事件管理之类的功能。
#   本类的实例请参考 $game_troop 。
#===========================================
..............
..............
class Game_Troop < Game_Unit
#--------------------------------------------------------------------------
  # ● 同名的敌人附加字母后缀
  #--------------------------------------------------------------------------
  def make_unique_names
    members.each do |enemy|
      next unless enemy.alive?
      next unless enemy.letter.empty?
      n = @names_count[enemy.original_name] || 0
      enemy.letter = LETTER_TABLE[n % LETTER_TABLE.size]
      @names_count[enemy.original_name] = n + 1
    end
    members.each do |enemy|
      n = @names_count[enemy.original_name] || 0
      enemy.plural = true if n >= 2
    end
  end

不懂之处请看红字的一段。从上下文文析,这个 n 明显是个数字。
而 @names_count 是个散列,enemy.original_name enemy是实例  下 @original_name enemy 的内容。
怎么凑都不应该会出现数字啊? 这个功能到底怎么实现的。

而且就算 enemy.original_name enemy是实例  下 @original_name enemy 内容是空 返回的最多就是 0
这个 n 还要当成 字符表 LETTER_TABLE = [' A',' B',' C',' D',' E',' F',' G',' H',' I',' J',
                  ' K',' L',' M',' N',' O',' P',' Q',' R',' S',' T',
                  ' U',' V',' W',' X',' Y',' Z'] 的索引 ,0 不可能是唯一的结果
梦石
0
星屑
29901
在线时间
5734 小时
注册时间
2016-3-8
回帖
1653
发表于 2020-10-5 08:59:20 | 显示全部楼层
本帖最后由 alexncf125 于 2020-10-5 09:59 编辑

设有一名敌人甲和两名敌人乙

1.@names_count在class Game_Troop 第49行賦值了为{}, 所以p @names_count得{}
2.@names_count为{}, 不存在enemy.original_name, 所以p @names_count[enemy.original_name]得nil
3.n = @names_count[enemy.original_name] || 0, 即n = nil || 0
   nil || 0取0, 所以p n得0
4.p n % LETTER_TABLE.size, 即 0 % 26, 得0
   enemy.letter = LETTER_TABLE[n % LETTER_TABLE.size], 即enemy.letter = LETTER_TABLE[0], 所以p enemy.letter得" A"
5.@names_count[enemy.original_name] = n + 1, 即@names_count[enemy.original_name] = 1, 所以@names_count由{}成了{"甲"=>1}
6.@names_count的值最终会是{"甲"=>1, "乙"=>2}, 所以p @names_count[enemy.original_name] 输出1 2 2

[pre lang="ruby"]class Game_Troop < Game_Unit
  #--------------------------------------------------------------------------
  # ● 同名的敌人附加字母后缀
  #--------------------------------------------------------------------------
  def make_unique_names
    members.each do |enemy|
      next unless enemy.alive?
      next unless enemy.letter.empty?

      p @names_count #=>{} {"甲"=>1} {"甲"=>1, "乙"=>1}          #1.
      p @names_count[enemy.original_name] #=>nil nil 1          #2.
      n = @names_count[enemy.original_name] || 0                #3.
      p n #=>0 0 1                                              #3.

      p LETTER_TABLE #=>[" A", " B", " C", " D", " E", " F", " G", " H", " I", " J", " K", " L", " M", " N", " O", " P", " Q", " R", " S", " T", " U", " V", " W", " X", " Y", " Z"]
      p LETTER_TABLE.size #=>26
      p (n % LETTER_TABLE.size) #=>0 0 1                        #4.
      enemy.letter = LETTER_TABLE[n % LETTER_TABLE.size]        #4.
      p enemy.letter #=>" A" " A" " B"                          #4.

      @names_count[enemy.original_name] = n + 1                                     #5.
      p @names_count #=>{"甲"=>1} {"甲"=>1, "乙"=>1} {"甲"=>1, "乙"=>2}               #5.

    end
    members.each do |enemy|

      p @names_count[enemy.original_name] #=>1 2 2                      #6.
      n = @names_count[enemy.original_name] || 0
      enemy.plural = true if n >= 2   #当敌人"X"有两名或以上(例如{" 甲"=>1, " 乙"=>2}中, " 乙"的值>=2)时, 敌人"X"的名字附加后缀(enemy.letter)

    end
  end[/pre]输出的结果由上至下,左至右理解, 即:

#=>a e i
#=>b f j
#=>c g k
#=>d h l
第26行#=>x y z

由a看到d,由e看到h,由 i 看到 l, 最后才算xyz
回复 1 0

使用道具 举报

梦石
0
星屑
208
在线时间
420 小时
注册时间
2020-1-11
回帖
175
 楼主| 发表于 2020-10-5 09:51:47 | 显示全部楼层
本帖最后由 alianlord 于 2020-10-5 09:54 编辑
alexncf125 发表于 2020-10-5 08:59
设有一名敌人甲和两名敌人乙

1.@names_count在class Game_Troop 第49行賦值了为{}, 所以p @names_count得{ ...


非常感谢,我明白这个n 的运算原理了。
我还有一个脚本的疑惑有提问过但没想明白。能给我提点一下吗?
class Game_Actor < Game_Battler
#--------------------------------------------------------------------------
  # ● 初始化装备
  #     equips : 初期装备的数组
  #--------------------------------------------------------------------------
  def init_equips(equips)
    @equips = Array.new(equip_slots.size) { Game_BaseItem.new }
    equips.each_with_index do |item_id, i|
      etype_id = index_to_etype_id(i)
      slot_id = empty_slot(etype_id)
      @equips[slot_id].set_equip(etype_id == 0, item_id) if slot_id
    end
    refresh
  end
  #--------------------------------------------------------------------------
  # ● 将索引变换为装备类型
  #--------------------------------------------------------------------------
  def index_to_etype_id(index)
    index == 1 && dual_wield? ? 0 : index
  end

红字的地方  etype_id  使用p 方法得出的是
0
1
2
3
4
这个结果 是否等价  etype_id = [0,1,2,3,4]
而下面这句编码的实现原理是什么?
#--------------------------------------------------------------------------
  # ● 将装备类型变换为装备栏 ID(优先返回空的装备栏)
  #--------------------------------------------------------------------------
  def empty_slot(etype_id)

    list = slot_list(etype_id)
    list.find {|i| @equips.is_nil? } || list[0]  <==  顺便问一下为什么标红字这行后面怎么变斜体了
  end
回复

使用道具 举报

梦石
0
星屑
29901
在线时间
5734 小时
注册时间
2016-3-8
回帖
1653
发表于 2020-10-5 10:20:58 | 显示全部楼层
本帖最后由 alexncf125 于 2020-10-5 12:59 编辑
alianlord 发表于 2020-10-5 09:51
非常感谢,我明白这个n 的运算原理了。
我还有一个脚本的疑惑有提问过但没想明白。能给我提点一 ...

红字的地方  etype_id  使用p 方法得出的是
0
1
2
3
4
这个结果 是否等价  etype_id = [0,1,2,3,4]
不是,p etype_id会出0=>1=>=2=>=3=>4只是因为 i 在0=>1=>=2=>=3=>4
  1.   #------------------------------------------------- -------------------------
  2.   # ● 将索引变换为装备类型
  3.   #------------------------------------------------- -------------------------
  4.   def index_to_etype_id(index)
  5.     index == 1 && dual_wield? ? 0 : index
  6.   end
复制代码
etype_id = index_to_etype_id(i), i 在0=>1=>=2=>=3=>4
index_to_etype_id(0) #index不为1         , etype_id返回0
index_to_etype_id(1) #index为1, 没双持, etype_id返回1
index_to_etype_id(2) #index不为1         , etype_id返回2
index_to_etype_id(3) #index不为1         , etype_id返回3
index_to_etype_id(4) #index不为1         , etype_id返回4

etype_id是一个局部变量, 用于判断正在设置(初始化)的装备是否武器
@equips[slot_id].set_equip(etype_id == 0, item_id) if slot_id
  1.   #------------------------------------------------- -------------------------
  2.   # ● 设置装备的 ID
  3.   # is_weapon : 是否武器
  4.   # item_id : 武器/防具 ID
  5.   #------------------------------------------------- -------------------------
  6.   def set_equip(is_weapon, item_id)
  7.     @class = is_weapon ? RPG::Weapon : RPG::Armor
  8.     @item_id = item_id
  9.   end
复制代码
所以etype_id不会有[0,1,2,3,4]这状态

第二部分的问题我得多花些时间研究研究
回复

使用道具 举报

梦石
0
星屑
208
在线时间
420 小时
注册时间
2020-1-11
回帖
175
 楼主| 发表于 2020-10-5 10:48:33 | 显示全部楼层
alexncf125 发表于 2020-10-5 10:20
不是,p etype_id会出0=>1=>=2=>=3=>4只是因为 i 在0=>1=>=2=>=3=>4etype_id = index_to_etype_id(i), i  ...

原来如此,我一只就搞不懂,原来p 出来的不是etype_id 本身 而是 i 啊。
我就奇怪怎么会有这种除了字符、数字、符号、数组、散列、实例外的怪对象
学 脚本好累啊。再次感谢大大
回复

使用道具 举报

梦石
0
星屑
29901
在线时间
5734 小时
注册时间
2016-3-8
回帖
1653
发表于 2020-10-5 12:09:45 | 显示全部楼层
本帖最后由 alexncf125 于 2021-2-15 16:54 编辑

点击展开/收起p出来的就是etype_id 本身, 只是因为第5行脚本而导致在默认脚本下都是与 i 相等。
例外的例子:当 i 是1且角色能双持武器时, etype_id就会是0而不是1(i)了

========================================================================================

1.Game_BaseItem第23行def is_nil?; @class == nil; end

2.[pre lang="ruby"]
  def slot_list(etype_id)
    result = []

    p equip_slots #=> [0,1,2,3,4]
    equip_slots.each_with_index {|e, i| result.push(i) if e == etype_id }
    result #=>依据etype_id的值, slot_list(etype_id)会返回[0]或[1]或[2]或[3]或[4]

  end[/pre]

3.[pre lang="ruby"]#--------------------------------------------------------------------------
  # ● 将装备类型变换为装备栏 ID(优先返回空的装备栏)
  #--------------------------------------------------------------------------
  def empty_slot(etype_id)
   
    p etype_id if self.id == $data_actors.size - 1
   
    list = slot_list(etype_id)
   
    if self.id == $data_actors.size - 1
      p list
      a = list.find {|i| p @equips; p @equips.is_nil?; @equips.is_nil? } || list[0]
      p a
      p "======================================================="
    end
  
    list.find {|i| @equips.is_nil? } || list[0]
  end[/pre]

#################################
p etype_id
p list
p @equips(i)<-这行和下一行我用了(i), 用[]i会使帖子的文字斜掉
p @equips(i).is_nil?
p a 「 empty_slot(etype_id)等同返回a」
#################################
0 #从4L的结论得出
[0] #2.
<Game_BaseItem:0x10030038 @class=nil, @item_id=0>
true #从1.和橙红色的部分得出
0 #这时候的@equips[0].is_nil?是true, 所以a返回0, 即empty_slot(etype_id)返回0
"======================================================="
1 #从4L的结论得出
[1] #2.
<Game_BaseItem:0x10030010 @class=nil, @item_id=0>
true #从1.和绿红色的部分得出
1 #这时候的@equips[0].is_nil?是false,而@equips[1].is_nil?是true, 所以a返回1, 即empty_slot(etype_id)返回1
"======================================================="
2 #从4L的结论得出
[2] #2.
<Game_BaseItem:0x1002fffc @class=nil, @item_id=0>
true #从1.和蓝红色的部分得出
2 #同上
"======================================================="
3 #从4L的结论得出
[3] #2.
<Game_BaseItem:0x1002ffd4 @class=nil, @item_id=0>
true #从1.和黄红色的部分得出
3 #同上
"======================================================="
4 #从4L的结论得出
[4] #2.
<Game_BaseItem:0x1002ffc0 @class=nil, @item_id=0>
true #从1.和紫红色的部分得出
4 #这时候的@equips[0].is_nil?是false, @equips[1].is_nil?是false, @equips[2].is_nil?是false, @equips[3].is_nil?是false
             #@equips[4].is_nil?是true, 所以a返回4, 即empty_slot(etype_id)返回4
"======================================================="



https://vimsky.com/examples/usag ... -find-function.html

Ruby Enumerable find()用法及代码示例

可枚举的find()是Ruby中的一种内置方法,它返回满足块中给定条件的第一个元素。如果没有块,则它返回枚举器本身。

用法: block.find { |obj| block }

参数:该函数采用一个块,根据该块将返回第一个满足条件的块。

返回值:它将返回满足该块或枚举数的第一个元素。

例子1:

# Ruby program for find method in Enumerable
  
# Initialize
enu = (1..50)
  
# returns first element
enu.find { |el| el % 2 == 0 && el % 9 == 0}

输出:

18

例子2:

# Ruby program for find method in Enumerable
  
# Initialize
enu = (1..50)
  
# returns enumerator
enu.find

输出:

Enumerator: 1..50:find
回复

使用道具 举报

梦石
0
星屑
29901
在线时间
5734 小时
注册时间
2016-3-8
回帖
1653
发表于 2020-10-5 12:37:13 | 显示全部楼层
本帖最后由 alexncf125 于 2020-10-5 13:03 编辑

其实我是不是错了?@喵呜喵5 @百里_飞柳
依我的说法, p @equips(i).is_nil?#[]i那里, 应该会像这样子才是吧?...
true
==========
false
true
==========
false
false
true
==========
false
false
false
true
==========
false
false
false
false
true
==========

可实际出来的结果却是
true
==========
true
==========
true
==========
true
==========
true
==========
回复 1 0

使用道具 举报

梦石
0
星屑
208
在线时间
420 小时
注册时间
2020-1-11
回帖
175
 楼主| 发表于 2020-10-5 13:30:30 | 显示全部楼层
alexncf125 发表于 2020-10-5 12:37
其实我是不是错了?@喵呜喵5 @百里_飞柳
依我的说法, p @equips(i).is_nil?#[]i那里, 应该会像这样子才是吧 ...

我也觉得很混乱,但没有能力把混乱在那里很有条理表达出来。alexncf125 真是高手啊。
回复

使用道具 举报

梦石
0
星屑
208
在线时间
420 小时
注册时间
2020-1-11
回帖
175
 楼主| 发表于 2020-10-5 15:01:16 | 显示全部楼层
7L的最后问题我找到答案了,在关键在红字
#==============================================================================
# ■ Game_BaseItem
#------------------------------------------------------------------------------
#  管理技能、物品、武器、护甲的统一类。会根据自己的所属类别而管理不同的数据。
#==============================================================================

class Game_BaseItem
  #--------------------------------------------------------------------------
  # ● 初始化对象
  #--------------------------------------------------------------------------
  def initialize
    @class = nil
    @item_id = 0
  end
  #--------------------------------------------------------------------------
  # ● 判定类
  #--------------------------------------------------------------------------
  def is_skill?;   @class == RPG::Skill;   end
  def is_item?;    @class == RPG::Item;    end
  def is_weapon?;  @class == RPG::Weapon;  end
  def is_armor?;   @class == RPG::Armor;   end
def is_nil?;     @class == nil;          end

当 #<Game_BaseItem:0x10030010 @class=nil, @item_id=0>
list.find {|i| @equips.is_nil? } 中 is_ni 判断的是传来的东西不属于 物品、武器、护具 时 返回 true
而返回的 0,1,2,3,4 或 0,0,2,3,4 都是索引 而不是  物品、武器、护具 的实例。所以全部返回  true


回复

使用道具 举报

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

本版积分规则

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

在本版发帖返回顶部