Tilemap 类是 RGSS1 为数不多不可被修改的一个类,我们无从得知它内部的实现究竟是怎样的。不过从测试的情况来看,数据库的“优先级”的确是起着一个高度的作用,也就是说,优先级为5的图快,它就盖不住从地面往上数的第六块的位置。需要注意的是,如果主角在地图上上下移动的话,坐标覆盖的情况应当有所调整(因为表示角色的图形是一个整体,具有统一的 z 坐标)。
最正规的办法当然是设置更高优先级的图快,但上面回帖已经说明不可行,更改为6以上会造成游戏的崩溃(可能库只考虑到5的情况)。
用 ULDS 直接画一层遮罩层应该说是一个不错的解决办法,但是 XP 的 ULDS,别说楼主了,作为作者的我都不怎么愿意用,因为,太难用。
不过,我们可以利用事件来把这个遮罩层铺出来(设置为“在最前面显示”即可),但是考虑到地图太大,一个个复制事件不是一个好主意,所以我们可以利用脚本来做这件事。
class Game_Map def create_mask_events @mask_event_count = 0 (0...width).each do |x| (0...height).each do |y| [2, 1, 0].each do |z| tile_id = data[x, y, z] if tile_id != nil && @terrain_tags[tile_id] == 7 ev = RPG::Event.new(x, y) ev.id = 1000 + @mask_event_count ev.pages[0].graphic.tile_id = tile_id ev.pages[0].always_on_top = true events[ev.id] = Game_Event.new(map_id, ev) @mask_event_count += 1 break end end end end end alias rb_setup_20170317 setup def setup(map_id) rb_setup_20170317(map_id) create_mask_events end end
class Game_Map
def create_mask_events
@mask_event_count = 0
(0...width).each do |x|
(0...height).each do |y|
[2, 1, 0].each do |z|
tile_id = data[x, y, z]
if tile_id != nil && @terrain_tags[tile_id] == 7
ev = RPG::Event.new(x, y)
ev.id = 1000 + @mask_event_count
ev.pages[0].graphic.tile_id = tile_id
ev.pages[0].always_on_top = true
events[ev.id] = Game_Event.new(map_id, ev)
@mask_event_count += 1
break
end
end
end
end
end
alias rb_setup_20170317 setup
def setup(map_id)
rb_setup_20170317(map_id)
create_mask_events
end
end
用法还是一样,地形标志设置为 7 的图快将会无条件出现在最上面。如果同一个位置有两个这样的图快,则只会考虑最高图层上地形标志为 7 的块。
当然,事件铺多了可能会造成掉帧,楼主给出的测试工程铺了 300 多个事件,帧率降低了 2 帧左右。不过这个可以通过修改 Game_Map#update 来防止卡机。在 Game_Map 的 392 行起可以加上一个防卡机判定。在我的代码中,用来铺遮罩层的事件的 ID 从 1000 开始算(因此不会和地图事件冲突)。
for event in @events.values event.update if event.id < 1000 end
for event in @events.values
event.update if event.id < 1000
end
楼主可以比较一下我和 guoxiaomi 的方案,选出一个适合自己的使用。 |