TA的每日心情 | 开心 4 天前 |
---|
签到天数: 33 天 连续签到: 1 天 [LV.5]常住居民I
管理员
- 积分
- 7144
|
好像看到有人写过,但是为了给地图截个图自写一个Tilemap,是不是有点太小题大做了……想过渲染Tilemap有多麻烦吗?
于是写了下面这个。Tilemap是什么能吃吗……
500X500的地图亲测可用。
单框脚本,俺就不发测试工程了,免得积分清零了导致各位下载不能。
更新:
v1.3
再加速PNG处理(加速约6倍,果然优化无上限)
支持M(纯地图)、U(ULDS)、T(攻略)、A(航拍)四种截图模式
全脚本加注释(详细程度可比默认系统,700行脚本有1/3是注释……)
v1.2
优化缓存,现支持RM理论上限(500X500)的导出;优化进度显示功能
v1.1
加速PNG处理
执行效率(在M模式下):
90X90以下的地图秒过,250X250大约需要6秒,500X500大约需要25秒(Surface Book i7-6600M CPU测试数据)
我的204张地图的大坑,M模式下47秒全部输出完,其他模式1分多一点点。
RUBY 代码 - #==============================================================================
- # ■ Map_Snapshot 1.3 (Build 171106)
- #------------------------------------------------------------------------------
- # 地图截图工具 by SailCat @ Project1
- # 该程序能将地图转换为PNG图片格式,包括三层图块和用图块ID绘制的事件,遮挡正确。
- # 使用方法:
- # 1. 插入本脚本到Game_Temp(不是Main)之前。
- # 2. 在插入脚本的下方,输入代码:
- # ms = Map_Snapshot.new
- # ms.set_scale(8) # 将地图缩小8倍,可以设定的值有1、2、4、8,默认为1
- # ms.set_mode("U") # 设置输出模式为 ULDS分层模式
- # 支持的模式有"M"普通地图、"U"ULDS分层模式、"T"攻略模式、"A"航拍模式
- # M模式:默认的模式、渲染F5、F6、F7层的全部和F8层的地图元件事件
- # U模式:内容同M模式,但将一张地图渲染成主角上层和主角下层的两张截图
- # T模式:在M模式的基础上,再加上不移动的事件,事件取第1页、初始位置
- # A模式:在M模式的基础上,再加上所有的非空事件,事件取第1页、初始位置
- # 注:使用U模式会将地图放大率强制设为1:1
- # ms.snap(6) # 转换Map006到图片
- # ms.snaps(1..19) # 转换Map001到Map019到图片
- # ms.snaps([1, 3, 7, 15]) # 转换Map001, Map003, Map007, Map015到图片
- # ms.snap_all # 转换工程中所有地图到图片
- # exit # 转换工程后退出
- # 3. 注释掉700行以下的内容可以屏蔽此工具,正常测试游戏。
- # 4. 该工具不修改工程内含文件,故执行完后不需要退出重新打开工程。
- #==============================================================================
- #==============================================================================
- # ■ Scene_Reporter
- #------------------------------------------------------------------------------
- # 通用工具处理进度显示模块。
- #==============================================================================
- module Scene_Reporter
- @sprite = nil
- @message = ""
- @value = ""
- #--------------------------------------------------------------------------
- # ● 更新显示
- # message: 主要信息(滚屏)
- # value: 次要信息(不滚屏)
- #--------------------------------------------------------------------------
- defself.update(message = "", value = "")
- # 初期化精灵
- if@sprite == nil
- @sprite = Sprite.new
- @sprite.bitmap = Bitmap.new(640, 480)
- @sprite.bitmap.font.name = "楷体"
- @sprite.bitmap.font.size = 20
- @start = Time.now
- @elapse = -1
- end
- # 信息和所显信息完全相同的情况下,直接返回
- returnif(message == ""or@message == message)and@value == value
- # 主信息不相同的情况下,滚屏
- if message != ""and@message != message
- @sprite.bitmap.blt(0, 0, @sprite.bitmap, Rect.new(0, 32, 640, 448))
- @message = message
- @elapse = 0
- end
- # 显示已用时间
- elapse = Integer(Time.now - @start)
- if@elapse < elapse
- @elapse = elapse
- min = @elapse / 60
- sec = @elapse % 60
- @sprite.bitmap.fill_rect(580, 0, 60, 32, Color.new(0, 0, 0))
- @sprite.bitmap.draw_text(580, 0, 60, 32, sprintf("%2d:%02d", min, sec))
- end
- # 显示信息
- @sprite.bitmap.fill_rect(0, 448, 640, 32, Color.new(0, 0, 0))
- @sprite.bitmap.draw_text(0, 448, 640, 32, @message + value)
- @value = value
- # 更新画面
- Graphics.update
- end
- #--------------------------------------------------------------------------
- # ● 结束处理
- # message: 最后的信息
- #--------------------------------------------------------------------------
- defself.close(message)
- # 更新最后的信息
- Scene_Reporter.update(message)
- # 等待按键结束
- loopdo
- Graphics.update
- Input.update
- # 按下 C 键或 B 键的情况下
- if Input.trigger?(Input::C)or Input.trigger?(Input::B)
- break
- end
- end
- # 释放精灵
- if@sprite != nil
- @sprite.bitmap.dispose
- @sprite.dispose
- end
- end
- end
- #==============================================================================
- # ■ PNG
- #------------------------------------------------------------------------------
- # PNG文件输出模块 by SailCat
- # 鸣谢:SixRC(取内存地址相关代码)
- # 用法:bitmap.output_png(filename)
- # filename: 输出的文件名,可含路径
- #==============================================================================
- module PNG
- #--------------------------------------------------------------------------
- # ● API 声明
- #--------------------------------------------------------------------------
- CopyMemory_pi = Win32API.new('kernel32', 'RtlMoveMemory', 'pii', 'i')
- CopyMemory_ii = Win32API.new('kernel32', 'RtlMoveMemory', 'iii', 'i')
- CopyMemory_ip = Win32API.new('kernel32', 'RtlMoveMemory', 'ipi', 'i')
- CallWindowProc_p = Win32API.new('user32.dll','CallWindowProc','pppii','i')
- CallWindowProc_i = Win32API.new('user32.dll','CallWindowProc','ppiii','i')
- #--------------------------------------------------------------------------
- # ● API 调用代码
- #--------------------------------------------------------------------------
- RGBAConvert = [
- 0x55, 0x8B, 0xEC, 0x8B, 0x45, 0x08, 0x33, 0xC9,
- 0xEB, 0x0D, 0x8B, 0x10, 0x0F, 0xCA, 0xC1, 0xCA,
- 0x08, 0x89, 0x10, 0x41, 0x83, 0xC0, 0x04, 0x3B,
- 0x4D, 0x0C, 0x72, 0xEE, 0xC9, 0xC2, 0x10, 0x00].pack('C*')
- GetAddress = [
- 0x8B, 0x74, 0x24, 0x08, 0x8B, 0x36, 0x8B, 0x76,
- 0x08, 0x8B, 0x76, 0x10, 0x8B, 0x7C, 0x24, 0x04,
- 0x89, 0x37, 0xC2, 0x10, 0x00].pack("C*")
- #--------------------------------------------------------------------------
- # ● PNG 常量
- #--------------------------------------------------------------------------
- PNG_HEADER = "\211\120\116\107\015\012\032\012\000\000\000\015"
- PNG_IHDR_HEAD = "\111\110\104\122"
- PNG_IHDR_TAIL = "\010\006\000\000\000"
- PNG_IEND_CHUNK = "\000\000\000\000\111\105\116\104\256\102\140\202"
- #--------------------------------------------------------------------------
- # ● 生成 PNG 文件情报头数据块(IHDR)
- #--------------------------------------------------------------------------
- def make_png_ihdr
- data = PNG_IHDR_HEAD + [width, height].pack("N*") + PNG_IHDR_TAIL
- return data + [Zlib.crc32(data)].pack("N")
- end
- #--------------------------------------------------------------------------
- # ● 保存 PNG 文件
- # filename: 保存的文件名
- #--------------------------------------------------------------------------
- def output_png(filename)
- # 检查并建立路径
- dir = filename.split("/")
- for i in0...dir.size - 1
- unless dir == "."
- add_dir = dir[0..i].join("/")
- Dir.mkdir(add_dir)rescuenil
- end
- end
- # 依次写入 PNG 文件内容
- file = File.open(filename,"wb")
- file.write(PNG_HEADER)
- file.write(make_png_ihdr)
- file.write(make_png_idat)
- file.write(PNG_IEND_CHUNK)
- file.close
- Scene_Reporter.update("", "完成")
- end
- #--------------------------------------------------------------------------
- # ● 使用临时文件生成 PNG 图像数据(IDAT)
- #--------------------------------------------------------------------------
- def make_png_idat
- # 数据头
- header = "IDAT"
- # 输出图像信息为临时文件并获得校验码
- adler = [make_data_file].pack("N")
- # 读取临时文件
- data = "\170\332"
- fsize = File.size("temp.gz")
- File.open("temp.gz", "rb")do |f|
- f.pos = 10
- data.concat(f.read(fsize - 18))
- data.concat(adler)
- end
- # 删除临时文件
- File.delete("temp.gz")
- # 附加校验码
- crc = [Zlib.crc32(header + data)].pack("N")
- size = [data.length].pack("N")
- # 返回数据
- return size + header + data + crc
- end
- #--------------------------------------------------------------------------
- # ● 将内存数据转储为文件,并返回adler32校验值
- #--------------------------------------------------------------------------
- def make_data_file
- # 建立缓存
- cache = "\000" * 1
- # 保存缓存原有结构信息
- cache_info = [cache.size].pack("L")+ [cache].pack("p")
- cache_len = cache.id * 2 + 8; cache_addr = cache_len + 4
- # 将缓存的指针覆盖使之指向 Bitmap 的图像数据
- byte_size = 4 * width * height
- bitmap_info = [byte_size].pack("L") + [address].pack("L")
- CopyMemory_ip.call(cache_len, bitmap_info, 8)
- # 进度汇报线程
- t = Thread.newdo
- loopdo; sleep(0.5); Scene_Reporter.update("", "转换格式..."); end
- end
- # BGRA 转 RGBA
- CallWindowProc_p.call(RGBAConvert, cache, width * height, 0, 0)
- # 结束进度汇报
- Thread.kill(t)
- # 准备写入文件
- x = 4 * width; y = [address + byte_size]; null = "\000"
- # adler32 校验码初期化
- adler = Zlib.adler32
- # 将缓存的大小改为单行位图
- CopyMemory_ip.call(cache_len, [x].pack("L"), 4)
- # 打开临时文件
- Zlib::GzipWriter.open("temp.gz", 8)do |gz|
- # 进度汇报线程
- t = Thread.newdo
- loopdo
- sleep(0.5)
- Scene_Reporter.update("", sprintf("压缩图片...%d%%",
- (byte_size - y[0] + @address) * 100 / byte_size))
- end
- end
- # 逐行上移
- while y[0] > @address
- y[0] -= x
- # 更改缓存指针
- CopyMemory_ip.call(cache_addr, y.pack("L"), 4)
- # 写入文件数据
- gz.write(null)
- adler = Zlib.adler32(null, adler)
- gz.write(cache)
- adler = Zlib.adler32(cache, adler)
- end
- # 结束进度汇报
- Thread.kill(t)
- # 关闭临时文件
- gz.close
- end
- # 恢复指针原始结构信息以便释放
- CopyMemory_ip.call(cache_len, cache_info, 8)
- # 返回校验码
- return adler
- end
- #--------------------------------------------------------------------------
- # ● 位图的数据内存地址
- #--------------------------------------------------------------------------
- def address
- if@address == nil
- buffer = "xxxx"
- CallWindowProc_i.call(GetAddress, buffer, object_id * 2 + 16, 0, 0)
- @address = buffer.unpack("L")[0]
- end
- return@address
- end
- end
- #==============================================================================
- # ■ Bitmap
- #------------------------------------------------------------------------------
- # 内部位图类
- #==============================================================================
- class Bitmap
- #--------------------------------------------------------------------------
- # ● 导入 PNG 模块
- #--------------------------------------------------------------------------
- include PNG
- #--------------------------------------------------------------------------
- # ● 合成
- # rect: 合成的矩形
- # src_bitmap: 合成的位图
- # src_rect: 合成位图的传送元矩形
- # opacity: 不透明度
- # blend_type: 合成方式(1: 加法、2: 减法)
- #--------------------------------------------------------------------------
- def blend_blt(rect, src_bitmap, src_rect, opacity, blend_type)
- # 纯透明的情况下 不合成
- returnif opacity == 0
- # 建立临时位图
- temp_bitmap = Bitmap.new(rect.width, rect.height)
- # 将源位图合成到临时位图,考虑缩放
- if rect.width != src_rect.widthor rect.height != src_rect.height
- temp_bitmap.stretch_blt(temp_bitmap.rect, src_bitmap, src_rect, opacity)
- else
- temp_bitmap.blt(0, 0, src_bitmap, src_rect, opacity)
- end
- # 逐点合成
- for i in0...rect.width
- for j in0...rect.height
- # 取色
- c1 = self.get_pixel(rect.x + i, rect.y + j)
- c2 = temp_bitmap.get_pixel(i, j)
- # 源位图此点无色的情况下,继续
- nextif c2.alpha == 0
- # 加法
- if blend_type == 1
- c1.red += c2.red * c2.alpha / 255 * opacity / 255
- c1.green += c2.green * c2.alpha / 255 * opacity / 255
- c1.blue += c2.blue * c2.alpha / 255 * opacity / 255
- # 减法
- else
- c1.red = [0, c1.red - c2.red * c2.alpha / 255 * opacity / 255].max
- c1.green = [0, c1.green - c2.green * c2.alpha / 255 * opacity / 255].max
- c1.blue = [0, c1.blue - c2.blue * c2.alpha / 255 * opacity / 255].max
- end
- # 设色
- self.set_pixel(rect.x + i, rect.y + j, c1)
- end
- end
- # 释放临时位图
- temp_bitmap.dispose
- end
- end
- #==============================================================================
- # ■ Map_Snapshot
- #------------------------------------------------------------------------------
- # 地图截图渲染引擎
- #==============================================================================
- class Map_Snapshot
- #--------------------------------------------------------------------------
- # ● 常量
- #--------------------------------------------------------------------------
- AUTOTILE_EXPAND = [
- 555752218, 555752196, 555746586, 555746564, 186653466, 186653444,
- 186647834, 186647812, 554310426, 554310404, 554304794, 554304772,
- 185211674, 185211652, 185206042, 185206020, 522066200, 522061080,
- 186521880, 186516760, 353636110, 185863950, 352980750, 185208590,
- 589438236, 587865372, 589438212, 587865348, 757868326, 757868292,
- 757859622, 757859588, 589176088, 757862158, 319950092, 185732364,
- 387322128, 386535696, 791554344, 791554308, 724182308, 724174116,
- 387059980, 724176140, 791292196, 791548176, 791286028, 117833984
- ]# 自动元件的展开方式
- #--------------------------------------------------------------------------
- # ● 初期化
- #--------------------------------------------------------------------------
- def initialize
- @tilesets = load_data("Data/Tilesets.rxdata")
- @mapnames = load_data("Data/MapInfos.rxdata")
- @mapnames.each{|k, v| @mapnames[k] = v.name.gsub(/[\\\/:*?|]/,"_")}
- @map_data = nil
- @output_bitmap = nil
- @tile_bitmap = nil
- @autotiles = [nil, nil, nil, nil, nil, nil, nil]
- @width = 0
- @height = 0
- @map_id = 0
- @scale = 1
- @mode = "M"
- end
- #--------------------------------------------------------------------------
- # ● 设置缩放
- # scale: 缩放比(1/1、1/2、1/4或1/8)
- #--------------------------------------------------------------------------
- def set_scale(scale)
- @scale = scale if[1, 2, 4, 8].include?(scale)
- end
- #--------------------------------------------------------------------------
- # ● 设置渲染模式
- # mode: 渲染模式(M、U、A、T)
- #--------------------------------------------------------------------------
- def set_mode(mode)
- @mode = mode if["M", "U", "A", "T"].include?(mode)
- end
- #--------------------------------------------------------------------------
- # ● 地图截图
- # map_id: 地图ID
- #--------------------------------------------------------------------------
- def snap(map_id)
- # 如果是ULDS模式,放大率强制为1
- set_scale(1)if@mode == "U"
- # 加载地图数据
- map_name = sprintf("Data/Map%03d.rxdata", map_id)
- ifFileTest.exist?(map_name)
- @map_id = map_id
- @map_data = load_data(map_name)
- @width = @map_data.width
- @height = @map_data.height
- @tileset = @tilesets[@map_data.tileset_id]
- @tile_bitmap = RPG::Cache.tileset(@tileset.tileset_name)
- @tile_rect = Rect.new(0, 0, 32, 32)
- # 用于输出的位图
- @output_bitmap = Bitmap.new(@width * 32 / @scale, @height * 32 / @scale)
- for i in0..6
- @autotiles[i] = RPG::Cache.autotile(@tileset.autotile_names[i])
- end
- @auto_stretch = {}
- # 渲染
- snapshot
- # 输出截图
- filename = sprintf("MapSnapshots/%03d-%s.png", map_id, @mapnames[map_id])
- @output_bitmap.output_png(filename)
- # 如果是ULDS模式,渲染第二张图
- if@mode == "U"
- @output_bitmap.clear
- snapshot(true)
- f2 = sprintf("MapSnapshots/%03d-%s[U].png", map_id, @mapnames[map_id])
- @output_bitmap.output_png(f2)
- end
- # 释放位图
- @output_bitmap.dispose
- @auto_stretch.each_value{|v| v.dispose}
- for i in0..6
- @autotiles[i].dispose
- end
- @autotiles = [nil, nil, nil, nil, nil, nil, nil]
- @tile_bitmap.dispose
- @tile_bitmap = nil
- end
- end
- #--------------------------------------------------------------------------
- # ● 渲染地图
- # ulds: ULDS第二层渲染专用
- #--------------------------------------------------------------------------
- def snapshot(ulds = false)
- # 筛选需要渲染的事件集
- @effect_events = @map_data.events.selectdo |k, v|
- # 事件的地图元件有效的情况下,总是渲染
- effective = (v.pages[0].graphic.tile_id > 0)
- # 分层模式的情况下
- if@mode == "U"
- # 事件还需要满足优先级条件才渲染
- effective &= (v.pages[0].always_on_top == ulds)
- # 攻略模式的情况下
- elsif@mode == "T"
- # 事件不移动且朝向固定也需渲染
- effective |= (v.pages[0].graphic.character_name != ""and
- v.pages[0].move_type == 0)
- # 航拍模式的情况下
- elsif@mode == "A"
- # 所有非空事件一律渲染
- effective |= (v.pages[0].graphic.character_name != "")
- end
- # 筛选
- effective
- end
- # 纯地图模式的情况下,直接按格快速渲染
- return direct_paint if@mode == "M"
- # 分层渲染底图
- unless ulds
- # 渲染没有优先级的图块
- for k in0...3
- for j in0...@height
- for i in0...@width
- # 取得图块
- tile_id = @map_data.data[i, j, k]
- # 优先级为0的情况下
- if tile_id > 0and@tileset.priorities[tile_id] == 0
- paint(i, j, tile_id)
- end
- end
- end
- # 每层汇报进度
- Scene_Reporter.update(sprintf("正在生成截图Map%03d.png...", @map_id),
- sprintf("渲染下层...%d%%", (k + 1) * 33))
- end
- # 渲染不在最前显示的图块事件
- @effect_events.eachdo |f|
- e = f[1]; g = e.pages[0].graphic
- if g.tile_id > 0andnot e.pages[0].always_on_top
- paint(e.x, e.y, g.tile_id, g.character_hue, g.opacity, g.blend_type)
- end
- end
- # 分层模式的情况下,渲染结束
- returnif@mode == "U"
- end
- # 分层渲染顶图
- # 计算剩余所有图块的 Z 坐标
- z_indexes = {}
- for k in0...3
- for j in0...@height
- for i in0...@width
- # 取得图块
- tile_id = @map_data.data[i, j, k]
- # 优先级不为0的情况下
- if tile_id > 0and@tileset.priorities[tile_id] > 0
- z = (@tileset.priorities[tile_id] + j) * 32 + 32
- z_indexes[z] = (z_indexes[z] || []).push([i, j, tile_id])
- end
- end
- end
- end
- # 计算所有需要渲染的事件的 Z 坐标
- @effect_events.eachdo |f|
- e = f[1]; g = e.pages[0].graphic
- # 事件的 Z 坐标
- z = e.pages[0].always_on_top ? 32768 : e.y * 32 + 32
- # 是普通事件的情况下
- if g.tile_id == 0or e.pages[0].always_on_top
- z_indexes[z] = (z_indexes[z] || []).push([e.x, e.y, g])
- end
- end
- # 按 Z 坐标开始绘制
- l = n = z_indexes.keys.size
- z_indexes.keys.sort.eachdo |k|
- v = z_indexes[k]
- whilenot v.empty?
- tile = v.shift
- x = tile[0]; y = tile[1]; g = tile[2]
- # 如果此处是图块
- if g.is_a?(Numeric)
- paint(x, y, g)
- # 如果此处是事件
- elsif g.tile_id > 0
- paint(x, y, g.tile_id, g.character_hue, g.opacity, g.blend_type)
- else
- paint_character(x, y, g)
- end
- end
- n -= 1
- # 已绘制20层的情况下,汇报进度
- if n % 20 == 0
- Scene_Reporter.update("", sprintf("渲染上层...%d%%",(l - n) * 100 / l))
- end
- end
- end
- #--------------------------------------------------------------------------
- # ● 快速逐格渲染(M模式用)
- #--------------------------------------------------------------------------
- def direct_paint
- # 变换有效事件列表
- events = @effect_events.inject({})do |s, f|
- e = f[1]
- s[[e.x, e.y]] = [e.pages[0].graphic, e.pages[0].always_on_top]
- s
- end
- # 逐格绘制
- for j in0...@height
- for i in0...@width
- # 获得此处的三层图块
- tiles = [@map_data.data[i, j, 0],
- @map_data.data[i, j, 1], @map_data.data[i, j, 2]]
- # 获得此处三层图块的 Z 坐标
- z_indexes = [@tileset.priorities[tiles[0]] * 32,
- @tileset.priorities[tiles[1]] * 32 + 1,
- @tileset.priorities[tiles[2]] * 32 + 2]
- # 如果此处有事件,压入图块数据
- if events.has_key?([i, j])
- tiles.push(events[[i, j]][0].tile_id)
- z_indexes.push(events[[i, j]][1] ? 999 : 3)
- end
- # 从最小值 Z 坐标开始绘制
- while tiles.size > 0
- z_index = z_indexes.min
- index = z_indexes.index(z_index)
- tile_id = tiles[index]
- # 图块是事件的情况下,按事件图块的合成方式绘成
- if z_index == 3or z_index == 999
- opacity = events[[i, j]][0].opacity
- hue = events[[i, j]][0].character_hue
- blend_type = events[[i, j]][0].blend_type
- else
- # 基本绘成
- hue = blend_type = 0
- opacity = 255
- end
- paint(i, j, tile_id, hue, opacity, blend_type)if tile_id > 0
- tiles.delete_at(index)
- z_indexes.delete_at(index)
- end
- end
- # 每绘制 20 行汇报一次进度
- if j % 20 == 0or j == @height - 1
- Scene_Reporter.update(sprintf("正在生成截图Map%03d.png...", @map_id),
- sprintf("渲染地图...%d%%", (j + 1) * 100 / @height))
- end
- end
- end
- #--------------------------------------------------------------------------
- # ● 绘制格子
- # x, y: 地图的坐标
- # tile_id: 元件 ID
- # hue_change: 色相
- # opacity: 不透明度
- # blend_type: 合成方式 (0: 普通、1: 加法、2: 减法)
- #--------------------------------------------------------------------------
- def paint(x, y, tile_id, hue_change = 0, opacity = 255, blend_type = 0)
- # 透明的图块不需要绘制
- returnif opacity == 0
- # 绘制的原点
- ox = x * 32 / @scale
- oy = y * 32 / @scale
- # 是普通元件的情况下
- if tile_id >= 384
- # 取得源位图
- if hue_change != 0
- (src = @tile_bitmap.clone).hue_change(hue)
- else
- src = @tile_bitmap
- end
- # 传送矩形
- tile_id -= 384
- src_rect = Rect.new((tile_id % 8) * 32, (tile_id / 8) * 32, 32, 32)
- # 绘制合成
- if blend_type == 0
- if@scale == 1
- @output_bitmap.blt(ox, oy, src, src_rect, opacity)
- else
- @output_bitmap.stretch_blt(Rect.new(ox, oy,
- 32 / @scale, 32 / @scale), src, rect, opacity)
- end
- else
- @output_bitmap.blend_blt(Rect.new(ox, oy,
- 32 / @scale, 32 / @scale), src, rect, opacity, blend_type)
- end
- # 色相有差异的情况下要释放
- src.disposeif hue_change != 0
- # 不是普通元件的情况下(即自动元件)
- else
- # 获得自动元件的展开样式
- autotile = @autotiles[tile_id / 48 - 1]
- tile_form = AUTOTILE_EXPAND[tile_id % 48]
- tile_lu = tile_form & 0xff
- tile_ru = (tile_form & 0xff00) >> 8
- tile_ld = (tile_form & 0xff0000) >> 16
- tile_rd = (tile_form & 0xff000000) >> 24
- # 缩放比为1的情况下,直接拷贝原件
- if@scale == 1
- @output_bitmap.blt(ox, oy, autotile, auto_rect(tile_lu), 255)
- @output_bitmap.blt(ox + 16, oy, autotile, auto_rect(tile_ru), 255)
- @output_bitmap.blt(ox, oy + 16, autotile, auto_rect(tile_ld), 255)
- @output_bitmap.blt(ox + 16, oy + 16, autotile, auto_rect(tile_rd), 255)
- # 缩放比不为1的情况下
- else
- s = 32 / @scale
- temp_bitmap = Bitmap.new(32, 32)
- temp_bitmap.blt(0, 0, autotile, auto_rect(tile_lu), 255)
- temp_bitmap.blt(16, 0, autotile, auto_rect(tile_ru), 255)
- temp_bitmap.blt(0, 16, autotile, auto_rect(tile_ld), 255)
- temp_bitmap.blt(16, 16, autotile, auto_rect(tile_rd), 255)
- @output_bitmap.stretch_blt(Rect.new(ox, oy, s, s),
- temp_bitmap, @tile_rect, 255)
- temp_bitmap.dispose
- end
- end
- end
- #--------------------------------------------------------------------------
- # ● 绘制事件
- # x, y: 地图的坐标
- # g: 事件的图像(RPG::Event::Graphic)
- #--------------------------------------------------------------------------
- def paint_character(x, y, g)
- # 透明的角色不需要绘制
- returnif g.opacity == 0
- # 绘制的原点
- bitmap = RPG::Cache.character(g.character_name, g.character_hue)
- rect = char_rect(bitmap.width, bitmap.height, g.direction, g.pattern)
- ox = (x * 32 - rect.width / 2 + 16) / @scale
- oy = (y * 32 - rect.height + 32) / @scale
- w = rect.width / @scale
- h = rect.height / @scale
- # 普通叠加的情况下,传送位图
- if g.blend_type == 0
- if@scale == 1
- @output_bitmap.blt(ox, oy, bitmap, rect, g.opacity)
- else
- @output_bitmap.stretch_blt(Rect.new(ox, oy, w, h), bitmap, rect,
- g.opacity)
- end
- else
- @output_bitmap.blend_blt(Rect.new(ox, oy, w, h), bitmap, rect,
- g.opacity, g.blend_type)
- end
- end
- #--------------------------------------------------------------------------
- # ● 事件的传送矩形
- # width, height: 事件的位图宽高
- # direction: 事件的朝向
- # pattern: 事件的模式
- #--------------------------------------------------------------------------
- def char_rect(width, height, direction, pattern)
- Rect.new(pattern * width / 4, (direction - 2) * height / 8,
- width / 4, height / 4)
- end
- #--------------------------------------------------------------------------
- # ● 自动元件的传送矩形
- # region: 自动元件的展开方式(0-47)
- #--------------------------------------------------------------------------
- def auto_rect(region)
- Rect.new((region % 6) * 16, (region / 6) * 16, 16, 16)
- end
- #--------------------------------------------------------------------------
- # ● 连续截图
- # range: 截图的地图ID列表
- #--------------------------------------------------------------------------
- def snaps(range)
- Scene_Reporter.update("准备就绪")
- if range.is_a?(Range)or range.is_a?(Array)
- range.eachdo |i|
- snap(i)
- end
- end
- Scene_Reporter.close("完成,按B或C键继续")
- end
- #--------------------------------------------------------------------------
- # ● 全部截图
- #--------------------------------------------------------------------------
- def snap_all
- snaps(1..999)
- end
- end
- ms = Map_Snapshot.new
- ms.set_scale(1)
- ms.set_mode("T")
- ms.snap_all
- exit
复制代码
运行时截图:
截图样例:
本帖来自P1论坛作者89444640,因Project1站服务器在国外有时候访问缓慢不方便作者交流学习,经联系P1站长fux2同意署名转载一起分享游戏制作经验,共同为国内独立游戏作者共同创造良好交流环境,原文地址: https://rpg.blue/forum.php?mod=viewthread&tid=403282 若有侵权,发帖作者可联系底部站长QQ在线咨询功能删除,谢谢。 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|