#============================================================================== # ■ 隐藏房间黑块遮罩 # by:VIPArcher [email: VIPArcher@sina.com] # -- 本脚本来自 https://rpg.blue 使用或转载请保留以上信息。 #============================================================================== =begin 使用说明: · 在地图上建一个事件,事件名为 "Black_Room_Config" 并且在该事件里注释上 path: BlackRoomFiles color: Color.new(33,33,33) x: 3 y: 0 z: 250 edge_width: 20 draw: [3,9,9,13][7,0,9,9] check: [2,8,10,14][8,0,10,10] min_opacity: 75 max_opacity: 200 switch_id: 5 · 以上的配置都有默认值,可以不配置,注释框可能不够写,可以使用滚动文字、脚本框、 显示对话来填,用来设置黑块的事件不会被执行,推荐使用滚动文字配置,不会被换行。 · 各字段作用释义: path:使用的素材所在路径,不使用素材绘制则没有意义 color:绘制黑块时使用的颜色,使用素材绘制黑块时无效 x: 遮罩区域的 x 坐标 y:遮罩区域的 y 坐标 z: 遮罩块的 z 值(在人物上方:200 同层:100 下方:0,可以做个参考) edge_width:绘制黑块时边缘的留白宽度,使用素材绘制黑块时无效 draw:要绘制黑块的范围,[左上角x,左上角y,右下角x,右下角y] 写多个会进行拼接 check:检查玩家踏入的范围,在范围内时,黑块将隐藏,设置规则同上 min_opacity:隐藏时不透明度最低值 默认0 max_opacity:显示时不透明度最大值 默认255 switch_id:关联的开关,设置的开关打开时,视为玩家在范围内,将隐藏黑块 标签内的文件名是在使用素材做遮罩时读取的文件名 · 注意: 使用素材绘制遮罩时:必须指定 x、y、check 不用素材绘制遮罩时:x、y会自动计算,无需设置,check 如果未设置则与 draw 一致 多个矩形之间允许重叠范围,注意不要换行,看地图编辑器右下角坐标就可以轻松取值 Black_Room_Config 的事件可以有多个,一个事件里也可以写多个遮罩 =end #============================================================================== $VIPArcherScript ||= {};$VIPArcherScript[:black_room] = 20220520 #------------------------------------------------------------------------------- module VIPArcher end #============================================================================== # ★ 设定部分 ★ #============================================================================== module VIPArcher::BlackRoom SW = 1 # 该开关开启时遮罩块不可见 RE_OUTER = /(.*?)<\/mask>/mi # 读取备注用的正则表达式 RE_INNER = /(\w+) *: *(.*)/ # 读取设置用的正则表达式 DEFAULT_Z = 300 # 遮罩块的Z值 EDGE_WIDTH = 16 # 遮罩块边距留空的距离 EVENT_NAME = 'Black_Room_Config' # 设置遮罩块的事件名 DEFAULT_COLOR = Color.new(0,0,0) # 默认遮罩块填充的颜色 DEFAULT_PATH = 'Parallaxes' # 素材存放默认文件夹 Graphics 下 OPACITY_SPEED = 17 # 透明度变化的速度 end #============================================================================== # ☆ 设定结束 ☆ #============================================================================== class Sprite_BlackRoom < Sprite include VIPArcher::BlackRoom #-------------------------------------------------------------------------- # ● 初始化对象 #-------------------------------------------------------------------------- def initialize(settings, viewport) super(viewport) @settings = settings @check_rects = [] basename = extract(nil) self.z = extract('z', DEFAULT_Z).to_i @switch_id = extract('switch_id', SW).to_i @min_opacity = extract('min_opacity', 0).to_i @max_opacity = extract('max_opacity', 255).to_i @opacity_speed = extract('opacity_speed', OPACITY_SPEED).to_i if basename.empty? return unless extract('draw') draw_rects = make_rects(extract('draw','')) make_bitmap(draw_rects) @check_rects = extract('check') ? make_rects(extract('check','')) : draw_rects else folder_name = "Graphics/#{extract('path', DEFAULT_PATH).chomp}" self.bitmap = Bitmap.new("#{folder_name}/#{basename}") if RUBY_VERSION == '1.9.2' p "#{basename}遮罩未设置踏入区域" unless extract('check') end @check_rects = make_rects(extract('check','')) self.x = extract('x', 0).to_i * 32 self.y = extract('y', 0).to_i * 32 end self.opacity = character_pos? ? @min_opacity : @max_opacity end #-------------------------------------------------------------------------- # ● 通过备注的设置的矩形绘制 Bitmap #-------------------------------------------------------------------------- def make_bitmap(draw_rects) bitmap_x = draw_rects.min_by { |rect| rect.x }.x bitmap_y = draw_rects.min_by { |rect| rect.y }.y bitmap_width = draw_rects.max_by { |rect| rect.width }.width bitmap_height = draw_rects.max_by { |rect| rect.height }.height self.x = bitmap_x * 32 self.y = bitmap_y * 32 self.bitmap = Bitmap.new(bitmap_width * 32, bitmap_height * 32) color = extract('color', DEFAULT_COLOR) edge_width = extract('edge_width', EDGE_WIDTH).to_i draw_rects.each do |rect| fill_rect = Rect.new( edge_width + (rect.x - bitmap_x) * 32, edge_width + (rect.y - bitmap_y) * 32, (rect.width - rect.x + 1) * 32 - edge_width * 2, (rect.height - rect.y + 1) * 32 - edge_width * 2 ) self.bitmap.fill_rect(fill_rect, color) end end #-------------------------------------------------------------------------- # ● 备注字符串转矩形数组 #-------------------------------------------------------------------------- def make_rects(str) str.scan(/\[[\d, ]+?\]/mi).collect do |rect| eval("Rect.new(#{$1})") if rect =~ /\[(\d+.*?)\]/ end end #-------------------------------------------------------------------------- # ● 提取备注中的设定值 #-------------------------------------------------------------------------- def extract(key, default = nil) return eval(@settings[key]) if key == 'color' && @settings[key] @settings[key] || default end #-------------------------------------------------------------------------- # ● 检查位置是否在设定的范围内 #-------------------------------------------------------------------------- def character_pos? @check_rects.any? do |rect| $game_player.x <= rect.width && $game_player.x >= rect.x && $game_player.y <= rect.height && $game_player.y >= rect.y end || $game_switches[@switch_id] end #-------------------------------------------------------------------------- # ● 更新透明度 #-------------------------------------------------------------------------- def update_opacity self.opacity = character_pos? ? [self.opacity - @opacity_speed, @min_opacity].max : [self.opacity + @opacity_speed, @max_opacity].min self.visible = !$game_switches[SW] end #-------------------------------------------------------------------------- # ● 更新地图卷动位置 #-------------------------------------------------------------------------- def update_position self.ox = $game_map.display_x * (RUBY_VERSION == '1.9.2' ? 32 : 0.125) self.oy = $game_map.display_y * (RUBY_VERSION == '1.9.2' ? 32 : 0.125) end #-------------------------------------------------------------------------- # ● 更新画面 #-------------------------------------------------------------------------- def update super update_opacity update_position end #-------------------------------------------------------------------------- # ● 释放 #-------------------------------------------------------------------------- def dispose self.bitmap.dispose super end end #------------------------------------------------------------------------------- class Spriteset_Map include VIPArcher::BlackRoom # 显示文字:(401) 滚动文本:(405) 注释:(108, 408) 脚本:(355, 655) EVENT_CODE = [108, 408, 405, 355, 655, 401] # 可以进行填写配置的事件类型编号 #-------------------------------------------------------------------------- # ● 生成人物精灵 #-------------------------------------------------------------------------- alias black_room_create_characters create_characters def create_characters black_room_create_characters room_sprite_dispose if @black_room_sprites create_black_rooms end #-------------------------------------------------------------------------- # ● 生成黑色遮罩块 #-------------------------------------------------------------------------- def create_black_rooms @black_room_sprites = [] $game_map.events.values.each do |event| if event.instance_variable_get(:@event).name =~ /#{EVENT_NAME}/i return if event.list.nil? event.list.unshift( RPG::EventCommand.new(115) ) if event.list.first.code != 115 event.list.inject('') do |result, command| next result unless EVENT_CODE.include?(command.code) "#{result}#{command.parameters.join()}\n" end.scan(RE_OUTER).map do |name, contents| settings = {nil => name} contents.scan(RE_INNER) do |key, value| (settings[key] ||= '') << value end sprite = Sprite_BlackRoom.new(settings, @viewport1) @black_room_sprites.push(sprite) end end end end #-------------------------------------------------------------------------- # ● 释放 #-------------------------------------------------------------------------- alias black_room_dispose dispose def dispose black_room_dispose room_sprite_dispose end #-------------------------------------------------------------------------- # ● 释放遮罩块 #-------------------------------------------------------------------------- def room_sprite_dispose @black_room_sprites.each {|sprite| sprite.dispose } end #-------------------------------------------------------------------------- # ● 更新画面 #-------------------------------------------------------------------------- alias black_room_update update def update black_room_update @black_room_sprites.each {|sprite| sprite.update } end end