Project1

标题: 让RGSS3记住事件移动后的位置 [打印本页]

作者: DeathKing    时间: 2014-7-26 18:53
标题: 让RGSS3记住事件移动后的位置
本帖最后由 DeathKing 于 2014-7-26 18:54 编辑
TL;DR
使用此脚本前,您应该阅读:自由脚本协议(Free Script License)
您也可以在GitHub上查看此脚本的最新版:1.1.0726版本
这里是参考范例工程: [FSL][1.1.0726]RememberWorld.rar (1.42 MB, 下载次数: 205)


RGSS3中存在什么问题?


RM系列一直存在这个问题。每次切换到新地图时,RGSS会重新从Map***.r*data文件中加载数据,重新设置地图(见Game_Map#setup_events),这样,有些执行过“设置事件位置”或者随机移动路线的事件就会再切换回地图时重新回到在编辑器中设定的位置。

这其实是很诡异的。我们希望RGSS3记住事件移动后的位置。

RememberWorld是如何解决这个问题的?

简而言之,给Scene_Map的pre_transfer加个钩子,添加我们的处理代码。基本思想是让RGSS3将当前地图中的事件的坐标存放在Game_System的一个实例变量中。然后再给Game_Map的setup_events加钩子,使得地图重新加载时,会从Game_System的那个实例变量中读取事件位置。这样就实现了事件位置的记录。

现在比较纠结的问题。


为什么有这个脚本?

正在做一个非常有趣的脚本,就需要这个功能的支撑。仓促之作,应该还会有许多没有考虑到的地方,希望大家多多提交BUG。









脚本


作者: 冰之滄月    时间: 2014-7-26 19:17
LZ做的很棒!就是Bgm有点问题哈
作者: 喵kano    时间: 2014-7-26 20:24
之前看过一个保存事件位置的脚本,内部切换黑/白名单
https://rpg.blue/thread-230430-1-1.html
作者: DeathKing    时间: 2014-7-26 22:02
喵kano 发表于 2014-7-26 20:24
之前看过一个保存事件位置的脚本,内部切换黑/白名单
https://rpg.blue/thread-230430-1-1.html ...

看了一下脚本 @feizhaodan 的是直接HOOK Game_Map#setup,在实际执行地图切换前记录事件位置,并直接让Game_Map来记录这些内容,某种程度上来说比我的脚本来得巧妙。

美中不足的是,需要将68行处,由:

RUBY 代码复制
  1. e.direction( @event_pos[@map_id][i][2])


修改为:

RUBY 代码复制
  1. e.set_direction( @event_pos[@map_id][i][2])


这样就能正确处理事件朝向的问题了。

其实我还要实现一个核功能,就是让这个地图的事件移动到另一个地图,并保持有效,这个比较棘手,也是我最想解决的。

作者: 菜鸟飞呀飞    时间: 2014-7-26 22:38
提示: 作者被禁止或删除 内容自动屏蔽
作者: lanyaolove    时间: 2014-7-28 02:11
希望能有xp版本
作者: taroxd    时间: 2014-7-28 07:40
本帖最后由 taroxd 于 2014-7-28 07:44 编辑
DeathKing 发表于 2014-7-26 22:02
看了一下脚本 @feizhaodan 的是直接HOOK Game_Map#setup,在实际执行地图切换前记录事件位置,并直接让Ga ...


RUBY 代码复制
  1. class Game_Map
  2.  
  3.   alias init_20140728 initialize
  4.   def initialize
  5.     init_20140728
  6.     @moved_events   = {}
  7.     @removed_events = {}
  8.   end
  9.  
  10.   # default_proc 不能存档简直忧伤……
  11.   def get_moved_events(map_id)
  12.     @moved_events[map_id] ||= {}
  13.   end
  14.  
  15.   def get_removed_events(map_id)
  16.     @removed_events[map_id] ||= {}
  17.   end
  18.  
  19.   def setup_events
  20.     @events = {}
  21.     @map.events.each do |i, event|
  22.       unless get_removed_events(@map_id)[i]
  23.         @events[i] = Game_Event.new(@map_id, event)
  24.       end
  25.     end
  26.     get_moved_events(@map_id).each do |i, (x, y, direction, event)|
  27.       @events[i] = event = Game_Event.new(@map_id, event)
  28.       event.moveto(x, y)
  29.       event.set_direction(direction)
  30.     end
  31.     @common_events = parallel_common_events.collect do |common_event|
  32.       Game_CommonEvent.new(common_event.id)
  33.     end
  34.     refresh_tile_events
  35.   end
  36. end
  37.  
  38. class Game_Event
  39.   def moveto_new_map(map_id, x, y, direction = nil)
  40.     if map_id == @map_id
  41.       moveto(x, y)
  42.       set_direction(direction) if direction
  43.       return
  44.     end
  45.     $game_map.get_moved_events(@map_id).delete(@id)
  46.     $game_map.get_removed_events(@map_id)[@id] = true
  47.     new_map = load_data(sprintf("Data/Map%03d.rvdata2", map_id))
  48.     size = new_map.width * new_map.height
  49.     begin
  50.       @event.id = @id = size + rand(0xffff) + @id # just a random number big enough
  51.     end while $game_map.get_moved_events(map_id).key?(@id)
  52.     $game_map.get_moved_events(map_id)[@id] =
  53.       [x, y, (direction || @direction), @event]
  54.     $game_map.get_removed_events(map_id).delete(@id)
  55.   end
  56. end


一个不太完善的版本,仅仅提供一个思路。
有很多问题没有考虑到,比如从当前地图移动走的时候,事件仍然会停留在地图上。
比如独立开关的问题没有处理。

反正我也不需要这个功能,所以也没有太在意美观和可读性什么的。总之就是提供一个思路吧。这些小问题应该都不难解决的。






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