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

Project1

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

[已经解决] 这段脚本有没有对游戏速度影响最小的写法

 关闭 [复制链接]

Lv1.梦旅人

梦石
0
星屑
90
在线时间
216 小时
注册时间
2007-9-5
帖子
370
跳转到指定楼层
1
发表于 2009-12-2 15:04:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

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

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

x
本帖最后由 typhon_524 于 2009-12-2 15:12 编辑

下面这段脚本是加在 Scene_Map 里的,在地图上会用事件随时调用 $scene.defence ,但是写得很长,对游戏速度有一些影响,求教有没有提高游戏速度的脚本写法
  1.   def defence
  2.     $game_variables[41] = 0         # 抗火属性归零
  3.     $game_variables[42] = 0         # 抗冰属性归零
  4.     $game_variables[43] = 0         # 抗雷属性归零
  5.     $game_variables[44] = 0         # 抗水属性归零
  6.     $game_variables[45] = 0         # 抗土属性归零
  7.     $game_variables[46] = 0         # 抗风属性归零
  8.     $game_variables[47] = 0         # 抗光属性归零
  9.     $game_variables[48] = 0         # 抗暗属性归零

  10.     for i in [32,36,40]
  11.       $game_variables[41] += 4 if $game_party.actors[0].armor1_id != 0 and $data_armors[$game_party.actors[0].armor1_id].guard_element_set.include?(i)
  12.       $game_variables[41] += 4 if $game_party.actors[0].armor2_id != 0 and $data_armors[$game_party.actors[0].armor2_id].guard_element_set.include?(i)
  13.       $game_variables[41] += 4 if $game_party.actors[0].armor3_id != 0 and $data_armors[$game_party.actors[0].armor3_id].guard_element_set.include?(i)
  14.     end
  15.     for i in [33,37,41]
  16.       $game_variables[41] += 6 if $game_party.actors[0].armor1_id != 0 and $data_armors[$game_party.actors[0].armor1_id].guard_element_set.include?(i)
  17.       $game_variables[41] += 6 if $game_party.actors[0].armor2_id != 0 and $data_armors[$game_party.actors[0].armor2_id].guard_element_set.include?(i)
  18.       $game_variables[41] += 6 if $game_party.actors[0].armor3_id != 0 and $data_armors[$game_party.actors[0].armor3_id].guard_element_set.include?(i)
  19.     end
  20.     for i in [34,38,42]
  21.       $game_variables[41] += 8 if $game_party.actors[0].armor1_id != 0 and $data_armors[$game_party.actors[0].armor1_id].guard_element_set.include?(i)
  22.       $game_variables[41] += 8 if $game_party.actors[0].armor2_id != 0 and $data_armors[$game_party.actors[0].armor2_id].guard_element_set.include?(i)
  23.       $game_variables[41] += 8 if $game_party.actors[0].armor3_id != 0 and $data_armors[$game_party.actors[0].armor3_id].guard_element_set.include?(i)
  24.     end
  25.       $game_variables[42] += 10 if $game_party.actors[0].armor1_id != 0 and $data_armors[$game_party.actors[0].armor1_id].guard_element_set.include?(2)
  26.       $game_variables[42] += 10 if $game_party.actors[0].armor2_id != 0 and $data_armors[$game_party.actors[0].armor2_id].guard_element_set.include?(2)
  27.       $game_variables[42] += 10 if $game_party.actors[0].armor3_id != 0 and $data_armors[$game_party.actors[0].armor3_id].guard_element_set.include?(2)
  28.       $game_variables[42] += 10 if $game_party.actors[0].armor4_id != 0 and $data_armors[$game_party.actors[0].armor4_id].guard_element_set.include?(2)
  29.       $game_variables[42] += 10 if $game_party.actors[0].armor5_id != 0 and $data_armors[$game_party.actors[0].armor5_id].guard_element_set.include?(2)
  30.       $game_variables[42] += 10 if $game_party.actors[0].armor6_id != 0 and $data_armors[$game_party.actors[0].armor6_id].guard_element_set.include?(2)
  31.     for i in [43,47,51]
  32.       $game_variables[42] += 2 if $game_party.actors[0].armor1_id != 0 and $data_armors[$game_party.actors[0].armor1_id].guard_element_set.include?(i)
  33.       $game_variables[42] += 2 if $game_party.actors[0].armor2_id != 0 and $data_armors[$game_party.actors[0].armor2_id].guard_element_set.include?(i)
  34.       $game_variables[42] += 2 if $game_party.actors[0].armor3_id != 0 and $data_armors[$game_party.actors[0].armor3_id].guard_element_set.include?(i)
  35.     end
  36.     for i in [44,48,52]
  37.       $game_variables[42] += 4 if $game_party.actors[0].armor1_id != 0 and $data_armors[$game_party.actors[0].armor1_id].guard_element_set.include?(i)
  38.       $game_variables[42] += 4 if $game_party.actors[0].armor2_id != 0 and $data_armors[$game_party.actors[0].armor2_id].guard_element_set.include?(i)
  39.       $game_variables[42] += 4 if $game_party.actors[0].armor3_id != 0 and $data_armors[$game_party.actors[0].armor3_id].guard_element_set.include?(i)
  40. .............................
  41. ....................................
  42. .................
  43. ............................
  44. ............
  45. .............................
复制代码

Lv1.梦旅人

梦石
0
星屑
61
在线时间
24 小时
注册时间
2008-8-5
帖子
1924
2
发表于 2009-12-2 18:49:19 | 只看该作者
本帖最后由 紫苏 于 2009-12-2 19:12 编辑

要 Ruby 最快的写法,可以从减少函数的调用上着手,命令式编程语言中,自然是函数调用越少效率越高~在你这段代码中,有很多“常量”,直到在这个函数结束前都不会改变,而每次你都调用一个函数去获取该“常量”,这个函数调用的步骤多次重复,效率就从中丢失了

比如:$game_party.actors[0]——每调用一次 $game_party.actors[0],实际上就是调用了一次 Game_Party#actors 方法获取了队员数组,并再通过这个数组调用了 Array#[] 方法去获取索引为 0 的数组元素。然而从这段代码中不难看出,变量的运算仅仅是针对队伍中的第一个队员,即 $game_party.actors[0],那完全可以用一个变量保存这个队员对象,这样之后仅仅是引用这个对象,而不会再次重复 $game_party.actors[0] 的调用了

总地来说,就是重复了很多次的相同代码,尽量把它返回的结果保存在另一个局部变量中,这样其实是用空间换取了时间~

以前两个循环为例,我们分别把优化后的代码和未经优化的代码放到两个函数中:
  1.   def defence1
  2.     $game_variables[41] = 0         # 抗火属性归零
  3.     $game_variables[42] = 0         # 抗冰属性归零
  4.     $game_variables[43] = 0         # 抗雷属性归零
  5.     $game_variables[44] = 0         # 抗水属性归零
  6.     $game_variables[45] = 0         # 抗土属性归零
  7.     $game_variables[46] = 0         # 抗风属性归零
  8.     $game_variables[47] = 0         # 抗光属性归零
  9.     $game_variables[48] = 0         # 抗暗属性归零

  10.     actor = $game_party.actors[0]
  11.     armor1_id = actor.armor1_id
  12.     armor2_id = actor.armor2_id
  13.     armor3_id = actor.armor3_id

  14.     armed1 = armor1_id != 0
  15.     armed2 = armor2_id != 0
  16.     armed3 = armor3_id != 0

  17.     armor1 = $data_armors[armor1_id]
  18.     armor2 = $data_armors[armor2_id]
  19.     armor3 = $data_armors[armor3_id]

  20.     ges1 = armor1.guard_element_set
  21.     ges2 = armor2.guard_element_set
  22.     ges3 = armor3.guard_element_set

  23.     for i in [32,36,40]
  24.       $game_variables[41] += 4 if armed1 and ges1.include?(i)
  25.       $game_variables[41] += 4 if armed2 and ges2.include?(i)
  26.       $game_variables[41] += 4 if armed3 and ges3.include?(i)
  27.     end

  28.     for i in [33,37,41]
  29.       $game_variables[41] += 6 if armed1 and ges1.include?(i)
  30.       $game_variables[41] += 6 if armed2 and ges2.include?(i)
  31.       $game_variables[41] += 6 if armed3 and ges3.include?(i)
  32.     end

  33.     # ...

  34.   end
  35.   
  36.   def defence2
  37.     $game_variables[41] = 0         # 抗火属性归零
  38.     $game_variables[42] = 0         # 抗冰属性归零
  39.     $game_variables[43] = 0         # 抗雷属性归零
  40.     $game_variables[44] = 0         # 抗水属性归零
  41.     $game_variables[45] = 0         # 抗土属性归零
  42.     $game_variables[46] = 0         # 抗风属性归零
  43.     $game_variables[47] = 0         # 抗光属性归零
  44.     $game_variables[48] = 0         # 抗暗属性归零
  45.     for i in [32,36,40]
  46.       $game_variables[41] += 4 if $game_party.actors[0].armor1_id != 0 and $data_armors[$game_party.actors[0].armor1_id].guard_element_set.include?(i)
  47.       $game_variables[41] += 4 if $game_party.actors[0].armor2_id != 0 and $data_armors[$game_party.actors[0].armor2_id].guard_element_set.include?(i)
  48.       $game_variables[41] += 4 if $game_party.actors[0].armor3_id != 0 and $data_armors[$game_party.actors[0].armor3_id].guard_element_set.include?(i)
  49.     end
  50.     for i in [33,37,41]
  51.       $game_variables[41] += 6 if $game_party.actors[0].armor1_id != 0 and $data_armors[$game_party.actors[0].armor1_id].guard_element_set.include?(i)
  52.       $game_variables[41] += 6 if $game_party.actors[0].armor2_id != 0 and $data_armors[$game_party.actors[0].armor2_id].guard_element_set.include?(i)
  53.       $game_variables[41] += 6 if $game_party.actors[0].armor3_id != 0 and $data_armors[$game_party.actors[0].armor3_id].guard_element_set.include?(i)
  54.     end
  55.   end
复制代码
然后再在事件中测试运行时间:
  1. t = Time.now
  2. for i in 0..100000
  3.   defence1
  4. end
  5. p Time.now - t

  6. t = Time.now
  7. for i in 0..100000
  8.   defence2
  9. end
  10. p Time.now - t
复制代码
未经优化的 defence2 执行的时间约略是优化后的 defence1 的两倍有余,所以在 defence 经常反复调用时,速度的差距也就明显了

另外一个着手点是 include? 方法——一般的 Array 是乱序线性数组,include? 自然也就只能是线性搜索,而这厮在数组很长时是一个骨灰级的效率杀手——在最坏的场合,include? 会一直从数组开头搜索到数组结尾。你的函数中,由于 guard_element_set 本身默认就是顺序数组(除非你用了什么脚本改变了从数据库中读取的防具属性防御)的这个特殊性,include? 完全可以被优化为一个一次性的遍历(即从头到尾检查整个 guard_element_set 数组一遍),每次枚举其中的一个元素,按照自然顺序检查元素(即属性的 ID)是否为某值,若是此值如何如何,如是彼值怎样怎样……也就是说,本来的这数个 for 循环,都会变成三个 for 循环(不管你有多少个属性需要判断),每个循环分别检查 armor1、armor2 和 armor3 的三个不同的 guard_element_set。这样下来,一共只会有三次数组的遍历,最坏的场合也不过是循环中的 if 或 case 语句判断到最后一个而已

另外,在循环外,你有很长一段代码重复调用 guard_element_set.include?(2),由于参数总是 2,且 guard_element_set 也并未改变,这些 include? 都会返回相同的结果。因此,将 include? 的结果保存在变量中引用也会提高效率~
回复 支持 1 反对 0

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
90
在线时间
216 小时
注册时间
2007-9-5
帖子
370
3
 楼主| 发表于 2009-12-3 09:07:38 | 只看该作者
本帖最后由 typhon_524 于 2009-12-3 09:08 编辑

非常感谢,如果我还有一个$game_party.actors[1]要添加,最好的办法是不是就直接加在后面了?这游戏最多就两个角色
  1.   def defence1
  2.     $game_variables[41] = 0         # 抗火属性归零
  3.     $game_variables[42] = 0         # 抗冰属性归零
  4.     $game_variables[43] = 0         # 抗雷属性归零
  5.     $game_variables[44] = 0         # 抗水属性归零
  6.     $game_variables[45] = 0         # 抗土属性归零
  7.     $game_variables[46] = 0         # 抗风属性归零
  8.     $game_variables[47] = 0         # 抗光属性归零
  9.     $game_variables[48] = 0         # 抗暗属性归零

  10.     actor = $game_party.actors[0]
  11.     armor1_id = actor.armor1_id
  12.     armor2_id = actor.armor2_id
  13.     armor3_id = actor.armor3_id

  14.     armed1 = armor1_id != 0
  15.     armed2 = armor2_id != 0
  16.     armed3 = armor3_id != 0

  17.     armor1 = $data_armors[armor1_id]
  18.     armor2 = $data_armors[armor2_id]
  19.     armor3 = $data_armors[armor3_id]

  20.     ges1 = armor1.guard_element_set
  21.     ges2 = armor2.guard_element_set
  22.     ges3 = armor3.guard_element_set

  23.     for i in [32,36,40]
  24.       $game_variables[41] += 4 if armed1 and ges1.include?(i)
  25.       $game_variables[41] += 4 if armed2 and ges2.include?(i)
  26.       $game_variables[41] += 4 if armed3 and ges3.include?(i)
  27.     end

  28.     for i in [33,37,41]
  29.       $game_variables[41] += 6 if armed1 and ges1.include?(i)
  30.       $game_variables[41] += 6 if armed2 and ges2.include?(i)
  31.       $game_variables[41] += 6 if armed3 and ges3.include?(i)
  32.     end

  33.     # ...

  34.   end
  35.   
  36.   def petdefence
  37.     $game_variables[41] = 0         # 抗火属性归零
  38.     $game_variables[42] = 0         # 抗冰属性归零
  39.     $game_variables[43] = 0         # 抗雷属性归零
  40.     $game_variables[44] = 0         # 抗水属性归零
  41.     $game_variables[45] = 0         # 抗土属性归零
  42.     $game_variables[46] = 0         # 抗风属性归零
  43.     $game_variables[47] = 0         # 抗光属性归零
  44.     $game_variables[48] = 0         # 抗暗属性归零
  45.     actor = $game_party.actors[1]
  46.     armor1_id = actor.armor1_id
  47.     armor2_id = actor.armor2_id
  48.     armor3_id = actor.armor3_id

  49.     armed1 = armor1_id != 0
  50.     armed2 = armor2_id != 0
  51.     armed3 = armor3_id != 0

  52.     armor1 = $data_armors[armor1_id]
  53.     armor2 = $data_armors[armor2_id]
  54.     armor3 = $data_armors[armor3_id]

  55.     ges1 = armor1.guard_element_set
  56.     ges2 = armor2.guard_element_set
  57.     ges3 = armor3.guard_element_set

  58.     for i in [32,36,40]
  59.       $game_variables[41] += 4 if armed1 and ges1.include?(i)
  60.       $game_variables[41] += 4 if armed2 and ges2.include?(i)
  61.       $game_variables[41] += 4 if armed3 and ges3.include?(i)
  62.     end

  63.     for i in [33,37,41]
  64.       $game_variables[41] += 6 if armed1 and ges1.include?(i)
  65.       $game_variables[41] += 6 if armed2 and ges2.include?(i)
  66.       $game_variables[41] += 6 if armed3 and ges3.include?(i)
  67.     end

  68.     # ...

  69.   end
复制代码
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-12-26 21:32

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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