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

Project1

 找回密码
 注册会员
搜索
12
返回列表 发新帖
楼主: YSC
打印 上一主题 下一主题

[已经解决] 更改敌人可获取的经验值

[复制链接]

Lv2.观梦者

梦石
0
星屑
275
在线时间
1373 小时
注册时间
2005-10-16
帖子
5113

贵宾

11
发表于 2016-10-28 09:40:15 | 只看该作者
本帖最后由 亿万星辰 于 2016-10-28 09:47 编辑
孤云黑月 发表于 2016-10-19 21:17
位置说错了
替换掉 Scene_Battle 2 的172行


这么改可以实现效果,但是不推荐,毕竟Scene_Battle涉及的脚本甚多,所以可以通过修改Game_Actor的
  1. class Game_Actor
  2.   #--------------------------------------------------------------------------
  3.   # ● 更改 EXP
  4.   #     exp : 新的 EXP
  5.   #--------------------------------------------------------------------------
  6.   def exp=(exp)
  7.     @exp = [[exp, 9999999].min, 0].max
  8.     # 升级
  9.     while @exp >= @exp_list[@level+1] and @exp_list[@level+1] > 0
  10.       @level += 1
  11.       # 学会特技
  12.       for j in $data_classes[@class_id].learnings
  13.         if j.level == @level
  14.           learn_skill(j.skill_id)
  15.         end
  16.       end
  17.     end
  18.     # 降级
  19.     while @exp < @exp_list[@level]
  20.       @level -= 1
  21.     end
  22.     # 修正当前的 HP 与 SP 超过最大值
  23.     @hp = [@hp, self.maxhp].min
  24.     @sp = [@sp, self.maxsp].min
  25.   end
  26. end
复制代码

这段脚本来实现,这个脚本的功能是处理角色获取经验值时的运算,延续状态法的思路,如果获得19号状态的话经验翻倍,想到这里去看看脚本吧。

def exp=(exp)
发现这个脚本定义的是“exp=”方法,也就是赋值号方法。就是说如果执行 someone.exp=99999时会调用。(PS:如果这么写的时候someone.exp+=100,那么其实是someone.exp=someone.exp+100,先计算出后面算式的值后再调用“=”方法,所以也是要调用这个方法的。)
someone:某个Game_Actor实例,或者叫对象。
exp=:调用了上面提到的赋值号方法 “exp=”。
someone.exp:这里调用的可不是这个方法,而是类开头写的“attr_reader   :exp”这个东西,也就是F1里提到的:
attr_reader(name ... )
等价于
def name
  @name
end
)# END PS

那么问题来了,如果(其实我们确实知道)在获取经验值的时候,使用的是actor.exp += value这种方式,如何获取这个“value”呢?

  def exp=(exp)
    gainExp = exp - @exp # <--  这就是那个“value”

但再考虑一下,如果是经验值减小了呢,是否需要排除这种情况呢?深思熟虑(2s 的时间)后决定,还是在减小时不进行翻倍的效果了,于是:

    exp += gainExp if gainExp>0 and self.state?(19)  # <--- 增加的经验值为正值且有19号状态时,经验值翻倍

好了,功能实现了,那能否更加人性化一些呢?如果不是翻倍而是变成3倍,或者是1.5倍的经验该怎么实现?如果不是19号状态而是20号状态呢?如果我想要在经验值减少的时候依然保持这个增益的效果呢?
最终又经过2s的深思熟虑后,上面这一样变成了这样
    exp += gainExp*($game_variables[EXPRATE_VID) if $game_switches[EXPRATEALWAYS_SID] and self.state?($game_variables[EXPSTATEID_VID])

通过变量和开关实现制作过程中的控制,这步当然不是必须的,不做也无妨,所以最后的脚本变成了这样:
  1. class Game_Actor
  2.   # 【经验增益比例控制变量ID】
  3.   # 变量ID:对应变量的值为经验提升的比例,如该值为4,且【变量4】为150的话代表
  4.   #         各种途径(战斗、事件操作)下获取的经验值为正常状态下的150%;【变量
  5.   #         4】为0时代表不获得经验值;为负数代表经验值亏损,-100表示亏损100%,
  6.   #         不过估计没人这么用吧……;
  7.   EXPRATE_VID = 4
  8.   
  9.   # 【享受经验增益时的状态】
  10.   # 变量ID:对应变量的值为享受经验增益的前提状态,如该值为5,且【变量5】为19的
  11.   #         的话,代表角色在获得状态19的情况下才享受经验增益效果;
  12.   EXPSTATEID_VID = 5
  13.   
  14.   # 【始终享受经验增益】
  15.   # 开关ID:对应开关打开时代表无论在经验增加还是减少时均享受经验增益效果,
  16.   #         如该值为1,代表【开关1】在打开时(当然状态还是要满足),无论是经验
  17.   #         增加还是减少,都会具有增益效果;如果【开关1】为关闭时,只有在经验值
  18.   #         增加时才会有增益效果。
  19.   EXPRATEALWAYS_SID = 1
  20.   
  21.   #--------------------------------------------------------------------------
  22.   # ● 更改 EXP
  23.   #     exp : 新的 EXP
  24.   #--------------------------------------------------------------------------
  25.   def exp=(exp)
  26.     gainExp = exp - @exp # <--  这就是那个“value”
  27.     exp += gainExp * ($game_variables[EXPRATE_VID] - 100) / 100 if ($game_switches[EXPRATEALWAYS_SID] or gainExp > 0) and self.state?($game_variables[EXPSTATEID_VID])
  28.     @exp = [[exp, 9999999].min, 0].max
  29.     # 升级
  30.     while @exp >= @exp_list[@level+1] and @exp_list[@level+1] > 0
  31.       @level += 1
  32.       # 学会特技
  33.       for j in $data_classes[@class_id].learnings
  34.         if j.level == @level
  35.           learn_skill(j.skill_id)
  36.         end
  37.       end
  38.     end
  39.     # 降级
  40.     while @exp < @exp_list[@level]
  41.       @level -= 1
  42.     end
  43.     # 修正当前的 HP 与 SP 超过最大值
  44.     @hp = [@hp, self.maxhp].min
  45.     @sp = [@sp, self.maxsp].min
  46.   end
  47. end
复制代码
我只个搬答案的
叔叔我已经当爹了~
婚后闪人了……
回复 支持 反对

使用道具 举报

Lv4.逐梦者 (版主)

梦石
0
星屑
9532
在线时间
5073 小时
注册时间
2013-6-21
帖子
3580

开拓者贵宾剧作品鉴家

12
发表于 2016-10-28 14:53:18 | 只看该作者
亿万星辰 发表于 2016-10-28 09:40
这么改可以实现效果,但是不推荐,毕竟Scene_Battle涉及的脚本甚多,所以可以通过修改Game_Actor的
这段 ...

与前辈的观点恰恰相反,我本人是不推荐前辈的这种改法的(或者说是要尽量避免),倒是比较赞同直接改 Scene_Battle 的办法。原因很简单,这样改破坏了原有的代码语意。

假设 EXP 收益增益(2倍)的条件被满足,那么执行下面的脚本
RUBY 代码复制
  1. # suppose self.exp is 15 right now
  2. self.exp = 20
  3. p self.exp # => 25

这样弄是不是有一些奇怪呢?因为从自然语意上来讲,我们更希望'='表达的意思尽量和原意相同。虽然在增减 EXP 的时候,也会有上下界这样的东西改变'='的含义,但是,如果这种2倍增益的效果也隐藏在exp=这个方法当中,那会使得代码的结构更加混乱了。毕竟,exp=的并不是仅仅为了 self.exp += val 这种语意设计的(如果是这样我更倾向于定义类似于 gain_exp 这样的方法,而并非在 exp= 上做手脚)。

另外,这样的改法并不是什么问题都没有的。
RUBY 代码复制
  1. class Game_Actor
  2.   def level=(level)
  3.     # 检查上下限
  4.     level = [[level, $data_actors[@actor_id].final_level].min, 1].max
  5.     # 更改 EXP
  6.     self.exp = @exp_list[level]
  7.   end
  8. end

这是 Game_Actor 增减等级的代码,请注意看定义的最后一句,就是
RUBY 代码复制
  1. self.exp = @exp_list[level]

如果exp=这个方法被黑过,那么这个增减等级的代码就会出问题。当然,你可以通过更改绑定的开关EXPRATEALWAYS_SID(这名字读起来也怪怪的)来暂时使得这个效果失效,但是问题是,谁会注意到这个冲突?只有在用的时候发现不对劲的时候才会发现,黑掉 exp = 这个方法后,level = 这个方法也会受到牵连。这并不是我们想看到的。

前辈不推荐改 Scene_Battle 仅仅是因为“涉及 Scene_Battle 的脚本甚多”。这里的“脚本”应该是所谓“插件脚本”,在我看来,插件脚本本身就是一个很坑的东西,使用这些脚本几乎都会破坏已有脚本的兼容性,所以无需迎合这些脚本的需求。反之,既然你都学会了改脚本,那么为何不将整合的工作也一并做了?毕竟插件脚本是给小白使用的,而并非有一定经验的人士。
回复 支持 反对

使用道具 举报

Lv2.观梦者

梦石
0
星屑
275
在线时间
1373 小时
注册时间
2005-10-16
帖子
5113

贵宾

13
发表于 2016-10-28 15:45:03 | 只看该作者
RyanBern 发表于 2016-10-28 14:53
与前辈的观点恰恰相反,我本人是不推荐前辈的这种改法的(或者说是要尽量避免),倒是比较赞同直接改 Sce ...

确实,更改原有语义这块我还真在写这个的时候没想到,因为语义中也没有提到经验增益的字面含义,再仔细一看题主问的确实是敌人可获取的经验值(这里我其实有点懵,后面说),这么说来还真的就是在Scene_Battle里修改更为合适。

好了,说下原因吧,早上其实是在看
https://rpg.blue/forum.php?mod=v ... amp;_dsign=a7c00fff
这个帖子,然后默默跟着里面的链接点到了现在这个帖子,然后默默的回复在了这个帖子里……
好吧,怪不得看问题觉得和早上好像不太一样了……
我只个搬答案的
叔叔我已经当爹了~
婚后闪人了……
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-11-11 14:36

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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