【加工】PNG Map Extractor for XP-地图PNG图片导出器Ver 1.3:深夜忙到很晚搞出来这个东西,这个脚本的功能就是导出游戏地图,把它制作成一个PNG文件。
类似的脚本在论坛上已经出现过,不过时间过于久远,而且不能直接在XP上使用。昨天在提问区看到一个提问帖,就拿来做了。用的是之前论坛上的脚本。
做的很仓促,所以有瑕疵的地方我会尽力改正。主要修复的问题就是自动元件描绘的问题,大家都知道只有XP才有自动元件,而且由于自动元件是程序自动生成,我们看不到源码,所以画起来十分麻烦,代码中大家也可以看到写得不是很简洁,不过我已经尽力了。
还有一个问题,就是地图导出会比较慢,所以尽量不要使用太大的地图。
感觉这玩意还可以配合ULDS系统进行截图。
使用前请下载这个DLL,并把它复制到工程的根目录下:
[code]#==============================================================================# PNG Map Extractor Ver 1.3#------------------------------------------------------------------------------# Modified By :RyanBern# 注:此脚本为部分原创,增加了一个描绘自动元件的功能(原版本无法描绘自动元件)# 引用的DLL: MGC_PNG(By MGC),使用前请将MGC_PNG.dll复制到根目录下。#------------------------------------------------------------------------------# 功能:可以将地图导出成 PNG 文件格式(不含主角和事件)# 也有直接将 Bitmap 对象输出为图片的功能#------------------------------------------------------------------------------# 使用方法:# 对 Bitmap 对象使用 save_as_png(filename) 即可在指定目标文件夹中生成 PNG 文件。# 直接调用 Picture_Map.make_all 即可生成全部地图的 PNG 文件# 如果想单独生成某一ID的地图可以调用 Picture_Map.make_one(id[, layers])# 后面的layers为指定图层,默认为整个地图,如果只需要生成1号地图第1层和第2层# 的PNG,可以用 Picture_Map.make_one(1, [0, 1]),注意图层的顺序不要反了。# 有关设置请改 module Picture_Map下的常量#------------------------------------------------------------------------------# 友情提示:# 当地图很大时,处理会比较慢,建议不要放置过大的地图。否则程序会因长时间没有# 响应而终止。# 输出的文件名统一为Map+3位地图ID的形式。#------------------------------------------------------------------------------# 更新记录:# Ver 1.1 :采用外接DLL,生成PNG更迅速# Ver 1.2 :增加分层描绘功能# Ver 1.3 :修复BUG(感谢pjy612的测试)#==============================================================================module Picture_Map # 是否自动缩放,如果设置为 true ,则输出的png不会超过以下的宽和高 AUTO_CHANGE = false # 自动缩放的宽度 AUTO_WIDTH = 800 # 自动缩放的高度 AUTO_HEIGHT = 1024 # 输出的文件夹(英文名称) DIR_OUT = "OutMaps/" def self.make_all mapinfos = load_data("Data/MapInfos.rxdata") for id in 1...mapinfos.size+1 next if mapinfos[id] == nil out_filename = sprintf("Map%03d.png", id) bitmap = make_map_bitmap(id) if bitmap != nil bitmap.save_as_png(DIR_OUT + out_filename) bitmap.dispose end end end def self.make_one(id, layers = [0, 1, 2]) mapinfos = load_data("Data/MapInfos.rxdata") return if mapinfos[id] == nil out_filename = sprintf("Map%03d.png", id) bitmap = make_map_bitmap(id, layers) if bitmap != nil bitmap.save_as_png(DIR_OUT + out_filename) bitmap.dispose end end def self.make_map_bitmap(id, layers = [0, 1, 2]) if FileTest.exist?(sprintf("#{DIR_OUT}Map%03d.png", id)) return nil end filename = sprintf("Data/Map%03d.rxdata", id) return nil unless FileTest.exist?(filename) map = load_data(filename) map_data = map.data tilesets = $data_tilesets[map.tileset_id] tileset_name = tilesets.tileset_name tileset = RPG::Cache.tileset(tileset_name) autotiles = [] for i in 0..6 autotile_name = tilesets.autotile_names autotiles = RPG::Cache.autotile(autotile_name) end map_bitmap = Bitmap.new(map.width * 32, map.height * 32) for y in 0...map.height for x in 0...map.width new_orders = [] layers.each do |z| new_orders = 0 if tilesets.priorities[new_orders[k]] > tilesets.priorities[temp] new_orders[k+1] = new_orders[k] k -= 1 else break end end new_orders[k+1] = temp if k != j - 1 end new_orders.each do |tile_num| begin next if tile_num == nil if tile_num < 384 if tile_num >= 48 #48 self.make_autotile(x * 32, y * 32, map_bitmap, autotiles[tile_num / 48 - 1], tile_num % 48) end else tile_num -= 384 src_rect = Rect.new(tile_num % 8 * 32, tile_num / 8 * 32, 32, 32) map_bitmap.blt(x * 32, y * 32, tileset, src_rect) end rescue Hangup p 1 end end end end if AUTO_CHANGE and (map_bitmap.width > AUTO_WIDTH or map_bitmap.height > AUTO_HEIGHT) zoom1 = map_bitmap.width.to_f / AUTO_WIDTH.to_f zoom2 = map_bitmap.height.to_f / AUTO_HEIGHT.to_f zoom = zoom1 > zoom2 ? zoom1 : zoom2 w = map_bitmap.width / zoom h = map_bitmap.height / zoom ret_bitmap = Bitmap.new(w, h) src_rect = Rect.new(0, 0, map_bitmap.width, map_bitmap.height) dest_rect = Rect.new(0, 0, w, h) ret_bitmap.stretch_blt(dest_rect, map_bitmap, src_rect) map_bitmap = ret_bitmap end return map_bitmap end def self.make_autotile(x, y, target_bitmap, tile_bitmap, tile_num) if tile_bitmap == nil return end case tile_num when 0...16 target_bitmap.blt(x, y, tile_bitmap, Rect.new(32, 64, 32, 32)) target_bitmap.blt(x, y, tile_bitmap, Rect.new(64, 0, 16, 16)) if tile_num & 0x01 != 0 target_bitmap.blt(x+16, y, tile_bitmap, Rect.new(80, 0, 16, 16)) if tile_num & 0x02 != 0 target_bitmap.blt(x+16, y+16, tile_bitmap, Rect.new(80, 16, 16, 16)) if tile_num & 0x04 != 0 target_bitmap.blt(x, y+16, tile_bitmap, Rect.new(64, 16, 16, 16)) if tile_num & 0x08 != 0 when 16...20 bit = tile_num - 16 target_bitmap.blt(x, y, tile_bitmap, Rect.new(0, 64, 32, 32)) target_bitmap.blt(x+16, y, tile_bitmap, Rect.new(80, 0, 16, 16)) if bit & 0x01 != 0 target_bitmap.blt(x+16, y+16, tile_bitmap, Rect.new(80, 16, 16, 16)) if bit & 0x02 != 0 when 20...24 bit = tile_num - 20 target_bitmap.blt(x, y, tile_bitmap, Rect.new(32, 32, 32, 32)) target_bitmap.blt(x+16, y+16, tile_bitmap, Rect.new(80, 16, 16, 16)) if bit & 0x01 != 0 target_bitmap.blt(x, y+16, tile_bitmap, Rect.new(64, 16, 16, 16)) if bit & 0x02 != 0 when 24...28 bit = tile_num - 24 target_bitmap.blt(x, y, tile_bitmap, Rect.new(64, 64, 32, 32)) target_bitmap.blt(x, y+16, tile_bitmap, Rect.new(64, 16, 16, 16)) if bit & 0x01 != 0 target_bitmap.blt(x, y, tile_bitmap, Rect.new(64, 0, 16, 16)) if bit & 0x02 != 0 when 28...32 bit = tile_num - 28 target_bitmap.blt(x, y, tile_bitmap, Rect.new(32, 96, 32, 32)) target_bitmap.blt(x, y, tile_bitmap, Rect.new(64, 0, 16, 16)) if bit & 0x01 != 0 target_bitmap.blt(x+16, y, tile_bitmap, Rect.new(80, 0, 16, 16)) if bit & 0x02 != 0 when 32 target_bitmap.blt(x, y, tile_bitmap, Rect.new(0, 64, 16, 32)) target_bitmap.blt(x+16, y, tile_bitmap, Rect.new(80, 64, 16, 32)) when 33 target_bitmap.blt(x, y, tile_bitmap, Rect.new(32, 32, 32, 16)) target_bitmap.blt(x, y+16, tile_bitmap, Rect.new(32, 112, 32, 16)) when 34...36 bit = tile_num - 34 target_bitmap.blt(x, y, tile_bitmap, Rect.new(0, 32, 32, 32)) target_bitmap.blt(x+16, y+16, tile_bitmap, Rect.new(80, 16, 16, 16)) if tile_num & 0x01 != 0 when 36...38 bit = tile_num - 36 target_bitmap.blt(x, y, tile_bitmap, Rect.new(64, 32, 32, 32)) target_bitmap.blt(x, y+16, tile_bitmap, Rect.new(64, 16, 16, 16)) if tile_num & 0x01 != 0 when 38...40 bit = tile_num - 38 target_bitmap.blt(x, y, tile_bitmap, Rect.new(64, 96, 32, 32)) target_bitmap.blt(x, y, tile_bitmap, Rect.new(64, 0, 16, 16)) if tile_num & 0x01 != 0 when 40...42 bit = tile_num - 40 target_bitmap.blt(x, y, tile_bitmap, Rect.new(0, 96, 32, 32)) target_bitmap.blt(x+16, y, tile_bitmap, Rect.new(80, 0, 16, 16)) if tile_num & 0x01 != 0 when 42 target_bitmap.blt(x, y, tile_bitmap, Rect.new(0, 32, 16, 32)) target_bitmap.blt(x+16, y, tile_bitmap, Rect.new(80, 32, 16, 32)) when 43 target_bitmap.blt(x, y, tile_bitmap, Rect.new(0, 32, 32, 16)) target_bitmap.blt(x, y+16, tile_bitmap, Rect.new(0, 112, 32, 16)) when 44 target_bitmap.blt(x, y, tile_bitmap, Rect.new(0, 96, 16, 32)) target_bitmap.blt(x+16, y, tile_bitmap, Rect.new(80, 96, 16, 32)) when 45 target_bitmap.blt(x, y, tile_bitmap, Rect.new(64, 32, 32, 16)) target_bitmap.blt(x, y+16, tile_bitmap, Rect.new(64, 112, 32, 16)) when 46 target_bitmap.blt(x, y, tile_bitmap, Rect.new(0, 0, 32, 32)) end endend#==============================================================================# ■ Bitmap#------------------------------------------------------------------------------# 关联到Bitmap。#==============================================================================class Bitmap #-------------------------------------------------------------------------- # * Constantes #-------------------------------------------------------------------------- CREATE_PNG = Win32API.new("MGC_PNG", "createPNG", "ll", "l") #-------------------------------------------------------------------------- # * Méthode d'appel pour créer un fichier PNG # chemin : chemin + nom du fichier à créer #-------------------------------------------------------------------------- def save_as_png(chemin) unless chemin[/\//] then chemin = './'