查看: 3076|回复: 2

[已经解决] 地图导出成png

[复制链接]
梦石
0
星屑
9818
在线时间
1648 小时
注册时间
2012-6-6
回帖
306
发表于 2017-5-2 14:45:15 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×
不知道大家有没有用过,就是把地图导出成PNG的一个屏幕截图脚本,有个外站的脚本,我这不能翻墙,不知道哪位能发下,或者有办法能把画的地图导出成png文件

点评

【警告】版规A-8 提问后不管  发表于 2017-5-15 11:34

职业の水客

梦石
2
星屑
16989
在线时间
7497 小时
注册时间
2010-6-16
回帖
3464

极短27评委MZ评测员极短26评委开拓者

发表于 2017-5-2 17:29:37 | 显示全部楼层
F7输出
  1. =begin
  2. #===============================================================================
  3. Title: Map Screenshot
  4. Author: Hime
  5. Date: Sep 25, 2015
  6. --------------------------------------------------------------------------------
  7. ** Change log
  8. Sep 25, 2015
  9.    - fixed placement issue with large sprites
  10. Dec 7, 2014
  11.    - added option to draw certain events
  12. Apr 15, 2013
  13.    - updated script to use GDI+ interface
  14.    - added support for region map overlay and passage map overlay
  15. Apr 6, 2013
  16.    - fixed bug where drawing events crashed the game
  17. Apr 2, 2013
  18.    - map data is now setup by an instance of Game_Map, to account for custom
  19.      map scripts adding to the map
  20. Jul 27
  21.    - Export dirNames are now optional
  22. May 28
  23.    - updated overlay mapping compatibility to draw the overlays
  24.      based on the player's current position
  25.    - fixed issue where import hash was commented out
  26.    - Added support for Yami's overlay mapping
  27. May 24, 2012
  28.    - fixed large characters
  29.    - some optimizations for calculating bounds and dimensions
  30. May 5, 2012
  31.    - fixed waterfall autotile
  32.    - added screenshot feature
  33. May 4, 2012
  34.    - fixed tiles with alpha channel
  35.    - fixed shadows
  36.    - fixed wall autotiles
  37. May 1, 2012
  38.    - fixed wall autotile, although there is still an issue with some tiles
  39. Apr 29, 2012
  40.    - fixed shadow map drawing
  41.    - added region highlighting
  42.    - added damage tile highlighting
  43. Apr 28, 2012
  44.    - Initial Release
  45. ------------------------------------------------------------------------------
  46. ** Description

  47. This script allows you to take a full image of any of your game's maps
  48. and export. An image of the map is referred to as a "mapshot" (as opposed to
  49. screenshot).

  50. The script provides various configuration options to control what kinds of
  51. things you want to see on your map, such as events, vehicles, region ID's, or
  52. specific tile properties.

  53. ------------------------------------------------------------------------------
  54. ** Usage

  55. The default key for taking a mapshot is F7. This can be changed in the
  56. configuration section.

  57. To take a mapshot, first start the game, and then hit F7.
  58. A message will appear informing you that a mapshot was successfully taken.

  59. Alternatively, you can use script calls to take mapshots.

  60.     Map_Saver.new(map_id).export
  61.    
  62. Aside from exporting images, you are able to use the image that the
  63. map saver captures.

  64.    ms = Map_Saver.new(map_id)
  65.    bmp = ms.map_image
  66.    
  67. This gives you a reference to a Bitmap object that contains an image of
  68. your map.
  69. --------------------------------------------------------------------------------
  70.   ** Credits

  71.   Cremno
  72.     -GDI+ interface code
  73.   Cidiomar
  74.     -for drawing autotiles and shadows,
  75.     -providing efficient bmp and png exporters
  76.   Moon
  77.     -auto-tile related info
  78.   Mephistox
  79.     -testing and suggestions
  80. ================================================================================
  81. =end
  82. $imported = {} if $imported.nil?
  83. $imported["TH_MapSaver"] = true
  84. #===============================================================================
  85. # ** Configuration
  86. #===============================================================================
  87. module TH
  88.   module Map_Saver
  89.    
  90.     #Mapshot options. This takes an image of the entire map
  91.     Mapshot_Button = Input::F7
  92.     Mapshot_Scale = 1
  93.    
  94.     #Screenshot options. This takes an image of the visible map
  95.     Screenshot_Button = Input::F6
  96.     Screenshot_Scale = 1
  97.    
  98.     #Folder that the map will be exported to
  99.     Mapshot_Directory = "Mapshots"
  100.     Screenshot_Directory = "Screenshots"
  101.    
  102.     # format you want to export to. You should stick with png.
  103.     # Options: [bmp, png]
  104.     Export_Format = "png"
  105.    
  106.     # Sprite draw options
  107.     Draw_Events = true
  108.     Draw_Player = false
  109.     Draw_Followers = true
  110.     Draw_Vehicles = true
  111.    
  112.     #Should shadows be drawn? What color?
  113.     Draw_Shadow = true
  114.     Shadow_Color = Color.new(0, 0, 0, 128)
  115.    
  116.     # Should regions be drawn? Requires "Region Overlay Map" script
  117.     Draw_Regions = false
  118.    
  119.     # Should passage settings be drawn? Requires "Passage Overlay Map" script
  120.     Draw_Passages = false
  121.    
  122.     #Should damage tiles be highlighted? What color?
  123.     Highlight_Damage = true
  124.     Damage_Color = Color.new(128, 0, 0, 128)
  125.   end
  126. end

  127. #==============================================================================
  128. # ** Module: Map_Tiles
  129. # Contains data and methods useful for working with maps and tiles
  130. #==============================================================================

  131. module Map_Tiles
  132.   AUTOTILE_PARTS = [[18,17,14,13], [ 2,14,17,18], [13, 3,17,18], [ 2, 3,17,18],
  133.                     [13,14,17, 7], [ 2,14,17, 7], [13, 3,17, 7], [ 2, 3,17, 7],
  134.                     [13,14, 6,18], [ 2,14, 6,18], [13, 3, 6,18], [ 2, 3, 6,18],
  135.                     [13,14, 6, 7], [ 2,14, 6, 7], [13, 3, 6, 7], [ 2, 3, 6, 7],
  136.                     [16,17,12,13], [16, 3,12,13], [16,17,12, 7], [12, 3,16, 7],
  137.                     [10, 9,14,13], [10, 9,14, 7], [10, 9, 6,13], [10, 9, 6, 7],
  138.                     [18,19,14,15], [18,19, 6,15], [ 2,19,14,15], [ 2,19, 6,15],
  139.                     [18,17,22,21], [ 2,17,22,21], [18, 3,22,21], [ 2, 3,21,22],
  140.                     [16,19,12,15], [10, 9,22,21], [ 8, 9,12,13], [ 8, 9,12, 7],
  141.                     [10,11,14,15], [10,11, 6,15], [18,19,22,23], [ 2,19,22,23],
  142.                     [16,17,20,21], [16, 3,20,21], [ 8,11,12,15], [ 8, 9,20,21],
  143.                     [16,19,20,23], [10,11,22,23], [ 8,11,20,23], [ 0, 1, 4, 5]]
  144.   WATERFALL_PIECES = [[ 2, 1, 6, 5], [ 0, 1, 4, 5], [ 2, 3, 6, 7], [0, 3, 4, 7]]
  145.   WALL_PIECES =  [[10, 9, 6, 5], [ 8, 9, 4, 5], [ 2, 1, 6, 5], [ 0, 1, 4, 5],
  146.                   [10,11, 6, 7], [ 8,11, 4, 7], [ 2, 3, 6, 7], [ 0, 3, 4, 7],
  147.                   [10, 9,14,13], [ 8, 9,12,13], [ 2, 1,14,13], [ 0, 1,12,13],
  148.                   [10,11,14,15], [8, 11,12,15], [ 2, 3,14,15], [ 0, 3,12,15]]

  149.   A1_TILES = [[0, 0], [0, 96], [192, 0], [192, 96],
  150.                [256, 0], [448, 0], [256, 96], [448, 96],
  151.                [0, 192], [192, 192], [0, 288], [192, 288],
  152.                [256, 192], [448, 192], [256, 288], [448, 288]]
  153.    
  154.   
  155.   #--------------------------------------------------------------------------
  156.   # * Checks if a tile is a wall
  157.   #--------------------------------------------------------------------------
  158.   def is_wall?(data)
  159.     return true if data.between?(2288, 2335)
  160.     return true if data.between?(2384, 2431)
  161.     return true if data.between?(2480, 2527)
  162.     return true if data.between?(2576, 2623)
  163.     return true if data.between?(2672, 2719)
  164.     return true if data.between?(2768, 2815)
  165.     return true if data.between?(4736, 5119)
  166.     return true if data.between?(5504, 5887)
  167.     return true if data.between?(6272, 6655)
  168.     return true if data.between?(7040, 7423)
  169.     return true if data > 7807
  170.     false
  171.   end
  172.   #--------------------------------------------------------------------------
  173.   # * Checks if a tile is roof
  174.   #--------------------------------------------------------------------------
  175.   def is_roof?(data)
  176.     return true if data.between?(4352, 4735)
  177.     return true if data.between?(5120, 5503)
  178.     return true if data.between?(5888, 6271)
  179.     return true if data.between?(6656, 7039)
  180.     return true if data.between?(7424, 7807)
  181.     false
  182.   end  
  183.   #--------------------------------------------------------------------------
  184.   # * Checks if a tile is soil
  185.   #--------------------------------------------------------------------------
  186.   def is_soil?(data)
  187.     return true if data.between?(2816, 4351) && !is_table?(data)
  188.     return true if data > 1663 && !is_stair?(data)
  189.     false
  190.   end   
  191.   #--------------------------------------------------------------------------
  192.   # * Checks if a tile is a stair
  193.   #--------------------------------------------------------------------------
  194.   def is_stair?(data)
  195.      return true if data.between?(1541, 1542)
  196.      return true if data.between?(1549, 1550)
  197.      return true if data.between?(1600, 1615)
  198.      false
  199.   end
  200.   #--------------------------------------------------------------------------
  201.   # * Checks if a tile is a table
  202.   #--------------------------------------------------------------------------
  203.   def is_table?(data)
  204.     return true if data.between?(3152, 3199)
  205.     return true if data.between?(3536, 3583)
  206.     return true if data.between?(3920, 3967)
  207.     return true if data.between?(4304, 4351)
  208.     false
  209.   end

  210.   #--------------------------------------------------------------------------
  211.   # * The tileset to be used
  212.   #--------------------------------------------------------------------------
  213.   def tileset
  214.     $data_tilesets[@tileset_id]
  215.   end
  216.   
  217.   #--------------------------------------------------------------------------
  218.   # * Region ID
  219.   #--------------------------------------------------------------------------
  220.   def region_id(x, y)
  221.     valid?(x, y) ? @map.data[x, y, 3] >> 8 : 0
  222.   end
  223.   
  224.   #--------------------------------------------------------------------------
  225.   # * Gets all of the tiles for each layer at position x,y
  226.   #--------------------------------------------------------------------------
  227.   def layered_tiles(x, y)
  228.     [2, 1, 0].collect {|z| @map.data[x, y, z] }
  229.   end
  230.   
  231.   def layered_tiles_flag?(x, y, bit)
  232.     layered_tiles(x, y).any? {|tile_id| tileset.flags[tile_id] & bit != 0 }
  233.   end
  234.    
  235.   def valid?(x, y)
  236.     x >= 0 && x < width && y >= 0 && y < height
  237.   end
  238.   
  239.   def damage_floor?(x, y)
  240.     valid?(x, y) && layered_tiles_flag?(x, y, 0x100)
  241.   end
  242.   
  243.   #--------------------------------------------------------------------------
  244.   # * Specifies which type of autotile is used
  245.   #--------------------------------------------------------------------------
  246.   def auto_tile(id)
  247.     id / 48
  248.   end
  249.   
  250.   #--------------------------------------------------------------------------
  251.   # * Specifies the specific arrangement of autotiles used
  252.   #--------------------------------------------------------------------------
  253.   def auto_index(id)
  254.     id % 48
  255.   end
  256.   
  257.   #--------------------------------------------------------------------------
  258.   # * Put the auto-tile pieces together
  259.   #--------------------------------------------------------------------------
  260.   def make_autotile(rects, sx, sy)
  261.     @tile.clear
  262.     for i in 0...4
  263.       @auto_rect.x = (rects[i] % 4) * 16 + sx
  264.       @auto_rect.y = (rects[i] / 4) * 16 + sy
  265.       @tile.blt((i % 2) * 16,(i / 2) * 16, @tilemap, @auto_rect)
  266.     end
  267.   end
  268.      
  269.   #--------------------------------------------------------------------------
  270.   # * Get auto-tile A1 tiles
  271.   #--------------------------------------------------------------------------
  272.   def autotile_A1(tile_id)
  273.     @tilemap = @bitmaps[0]
  274.     autotile = tile_id / 48
  275.     auto_id = tile_id % 48
  276.     sx, sy = A1_TILES[autotile]
  277.     if is_wall?(tile_id + 2048)
  278.       rects = WATERFALL_PIECES[auto_id]
  279.     else  
  280.       rects = AUTOTILE_PARTS[auto_id]
  281.     end
  282.     make_autotile(rects, sx, sy)
  283.   end
  284.   
  285.   #--------------------------------------------------------------------------
  286.   # * Get auto-tile A2 tiles.
  287.   # 64x96 tiles, 8 per row, 4 rows
  288.   #--------------------------------------------------------------------------
  289.   def autotile_A2(tile_id)
  290.     autotile = tile_id / 48
  291.     auto_id = tile_id % 48
  292.     @tilemap = @bitmaps[1]
  293.     sx = (autotile % 8) * 64
  294.     sy = (autotile / 8 % 4) * 96
  295.     rects = AUTOTILE_PARTS[auto_id]
  296.     make_autotile(rects, sx, sy)
  297.   end
  298.   
  299.   #--------------------------------------------------------------------------
  300.   # * Get auto-tile A3 tiles.
  301.   # 64x64 tiles, 8 per row, 4 rows
  302.   #--------------------------------------------------------------------------
  303.   def autotile_A3(tid)
  304.     @tilemap = @bitmaps[2]
  305.     sx = (auto_tile(tid) % 8) * 64
  306.     sy = (auto_tile(tid) / 8 % 4) * 64
  307.     rects = WALL_PIECES[auto_index(tid)]
  308.     make_autotile(rects, sx, sy)
  309.   end
  310.   
  311.   #--------------------------------------------------------------------------
  312.   # * Get auto-tile A4 tiles (walls)
  313.   #--------------------------------------------------------------------------
  314.   def autotile_A4(tile_id)
  315.     @tilemap = @bitmaps[3]
  316.     autotile = tile_id / 48
  317.     auto_id = tile_id % 48
  318.     sx = (autotile % 8) * 64
  319.     sy = (autotile / 16 * 160) + (autotile / 8 % 2) * 96
  320.     if is_wall?(tile_id + 5888)
  321.       rects = WALL_PIECES[auto_id]
  322.     else
  323.       rects = AUTOTILE_PARTS[auto_id]
  324.     end
  325.     make_autotile(rects, sx, sy)
  326.   end
  327.   
  328.   #--------------------------------------------------------------------------
  329.   # * Get auto-tile A5 tiles (normal)
  330.   #--------------------------------------------------------------------------
  331.   def autotile_A5(tile_id)
  332.     @tilemap = @bitmaps[4]
  333.     sx = (tile_id) % 8 * tilesize
  334.     sy = (tile_id) / 8 * tilesize
  335.     @src_rect.set(sx, sy, tilesize, tilesize)
  336.     @tile.clear
  337.     @tile.blt(0, 0, @tilemap, @src_rect)
  338.   end
  339.   
  340.   #--------------------------------------------------------------------------
  341.   # * Get normal tiles B, C, D, E
  342.   #--------------------------------------------------------------------------
  343.   def normal_tile(tile_id)
  344.     @tilemap = @bitmaps[5 + tile_id / 256]
  345.     sx = (tile_id / 128 % 2 * 8 + tile_id % 8) * tilesize;
  346.     sy = (tile_id % 256 / 8 % 16) * tilesize;
  347.     @src_rect.set(sx, sy, tilesize, tilesize)
  348.     @tile.clear
  349.     @tile.blt(0, 0, @tilemap, @src_rect)
  350.   end
  351.    
  352.   #--------------------------------------------------------------------------
  353.   # * Get bitmap for the specified tile id
  354.   #--------------------------------------------------------------------------
  355.   def get_bitmap(id)
  356.     if id < 1024
  357.       normal_tile(id)
  358.     elsif id < 1664
  359.       autotile_A5(id - 1536)
  360.     elsif id < 2816
  361.       autotile_A1(id - 2048)
  362.     elsif id < 4352
  363.       autotile_A2(id - 2816)
  364.     elsif id < 5888
  365.       autotile_A3(id - 4352)
  366.     else
  367.       autotile_A4(id - 5888)
  368.     end
  369.   end
  370. end

  371. #==============================================================================
  372. # **
  373. #==============================================================================

  374. class Game_Player < Game_Character
  375.   
  376.   alias :th_mapsaver_update :update
  377.   def update
  378.     th_mapsaver_update
  379.     if Input.trigger?(TH::Map_Saver::Mapshot_Button)
  380.       s = Map_Saver.new($game_map.map_id)
  381.       s.set_scale(TH::Map_Saver::Mapshot_Scale)
  382.       s.mapshot
  383.     end
  384.     if Input.trigger?(TH::Map_Saver::Screenshot_Button)
  385.       s = Map_Saver.new($game_map.map_id)
  386.       s.set_scale(TH::Map_Saver::Screenshot_Scale)
  387.       s.screenshot
  388.     end
  389.   end
  390. end

  391. class Game_Vehicle < Game_Character
  392.   attr_reader :map_id
  393. end

  394. class Game_Map
  395.   attr_reader :map
  396. end

  397. #==============================================================================
  398. # **
  399. #==============================================================================

  400. class Map_Saver
  401.   include TH::Map_Saver
  402.   include Map_Tiles
  403.   #--------------------------------------------------------------------------
  404.   # * Constants
  405.   #--------------------------------------------------------------------------

  406.   SHADOW_COLOR = TH::Map_Saver::Shadow_Color
  407.   DAMAGE_COLOR = TH::Map_Saver::Damage_Color

  408.   #--------------------------------------------------------------------------
  409.   # * Public instance variables
  410.   #--------------------------------------------------------------------------
  411.   attr_reader :map_image
  412.   
  413.   def initialize(map_id=$game_map.map_id, x=$game_player.x, y=$game_player.y)
  414.     @scale = 1
  415.     @local_x = x
  416.     @local_y = y
  417.     @screen_local = false
  418.     @shadow_bitmap = Bitmap.new(128, 128)
  419.     @draw_layer0 = true
  420.     @draw_layer1 = true
  421.     @draw_layer2 = true
  422.     @draw_events = Draw_Events
  423.     @draw_vehicles = Draw_Vehicles
  424.     @draw_player = Draw_Player
  425.     @draw_followers = Draw_Followers
  426.     @draw_shadow = Draw_Shadow
  427.     @draw_damage = Highlight_Damage
  428.     @draw_regions = Draw_Regions
  429.     @draw_passages = Draw_Passages
  430.     @tile = Bitmap.new(32, 32) #stores the current tile to be drawn
  431.     @tilemap = nil
  432.     @src_rect = Rect.new
  433.     @auto_rect = Rect.new(0, 0, tilesize / 2, tilesize/ 2) #constant
  434.     @tile_rect = Rect.new(0, 0, tilesize, tilesize)        #constant
  435.   end
  436.   
  437.   def load_tilesets
  438.     bitmaps = []
  439.     tileset.tileset_names.each_with_index do |name, i|
  440.       bitmaps[i] = Cache.tileset(name)
  441.     end
  442.     return bitmaps
  443.   end
  444.   
  445.   #--------------------------------------------------------------------------
  446.   # * Refresh, possibly with a new map
  447.   #--------------------------------------------------------------------------
  448.   def redraw(map_id=$game_map.map_id, x=$game_player.x, y=$game_player.y)
  449.     @map_image.dispose if @map_image
  450.     @map_id = map_id
  451.     @local_x = x
  452.     @local_y = y
  453.     @game_map = Game_Map.new
  454.     @game_map.setup(map_id)
  455.     @map = @game_map.map
  456.     @map_info = $data_mapinfos[map_id]
  457.     @screen = $game_map.screen
  458.     @tileset_id = @game_map.tileset.id
  459.     @bitmaps = load_tilesets
  460.    
  461.     get_bounds
  462.     @map_image = Bitmap.new(@width * tilesize, [url=home.php?mod=space&uid=291977]@height[/url] * tilesize)
  463.     draw_map
  464.     scale_map if @scale != 1
  465.   end
  466.   
  467.   #--------------------------------------------------------------------------
  468.   # * Pre-process. These will never change when drawing the map.
  469.   #--------------------------------------------------------------------------
  470.   def get_bounds
  471.     @start_x = start_x
  472.     @start_y = start_y
  473.     @end_x = end_x
  474.     @end_y = end_y
  475.     @width = width
  476.     @height = height
  477.     @tilesize = tilesize
  478.   end
  479.   
  480.   def screen_tile_x
  481.     Graphics.width / 32
  482.   end
  483.   
  484.   def screen_tile_y
  485.     Graphics.height / 32
  486.   end
  487.   
  488.   #--------------------------------------------------------------------------
  489.   # * Sets the scale for the map
  490.   #--------------------------------------------------------------------------
  491.   def set_scale(scale)
  492.     @scale = scale
  493.   end
  494.   
  495.   #--------------------------------------------------------------------------
  496.   # * Size of a tile
  497.   #--------------------------------------------------------------------------
  498.   def tilesize
  499.     32
  500.   end
  501.   
  502.   #--------------------------------------------------------------------------
  503.   # * Width and height of the map, both locally and globally
  504.   #--------------------------------------------------------------------------
  505.   def width
  506.     end_x - @start_x
  507.   end
  508.   
  509.   def height
  510.     end_y - @start_y
  511.   end
  512.   
  513.   #--------------------------------------------------------------------------
  514.   # * Starting and end positions, relative to the screen or map
  515.   #--------------------------------------------------------------------------
  516.   def start_x
  517.     @screen_local ? [[$game_player.x - screen_tile_x / 2, @map.width - screen_tile_x].min, 0].max : 0
  518.   end

  519.   def start_y
  520.     @screen_local ? [[$game_player.y - screen_tile_y / 2, @map.height - screen_tile_y].min, 0].max : 0
  521.   end
  522.   
  523.   def end_x
  524.     @screen_local ? [[screen_tile_x, @local_x + screen_tile_x / 2 + 1].max, @map.width].min : @map.width
  525.   end
  526.   
  527.   def end_y
  528.     @screen_local ? [[screen_tile_y, @local_y + screen_tile_y / 2 + 1].max, @map.height].min : @map.height
  529.   end

  530.   #--------------------------------------------------------------------------
  531.   # * Draw tile onto image. x and y values are absolute coords. They should
  532.   # be re-mapped based on the start_x and start_y values
  533.   #--------------------------------------------------------------------------
  534.   def draw_tile(x, y, tile, rect)
  535.     ox = (x - @start_x) * tilesize
  536.     oy = (y - @start_y) * tilesize
  537.     @map_image.blt(ox, oy, tile, rect)
  538.   end
  539.   
  540.   def draw_character(x, y, width, height, bmp, rect)
  541.     ox = (x - @start_x) * tilesize
  542.     oy = (y - @start_y) * tilesize
  543.    
  544.     ox = ox - width / 4 if width > 32
  545.     oy = oy - height / 2 if height > 32
  546.     @map_image.blt(ox, oy, bmp, rect)
  547.   end
  548.   
  549.   #--------------------------------------------------------------------------
  550.   # * Get bitmap for the specified character
  551.   #--------------------------------------------------------------------------
  552.   def get_character_bitmap(name)
  553.     charmap = Cache.character(name)
  554.     sign = name[/^[\!\$]./]
  555.     if sign && sign.include?('[/fold])
  556.       cw = charmap.width / 3
  557.       ch = charmap.height / 4
  558.     else
  559.       cw = charmap.width / 12
  560.       ch = charmap.height / 8
  561.     end
  562.     return charmap, cw, ch
  563.   end
  564.   
  565.   #--------------------------------------------------------------------------
  566.   # * Draw the character onto the tile
  567.   #--------------------------------------------------------------------------
  568.   def set_character_bitmap(character, x, y)
  569.     charmap, cw, ch = get_character_bitmap(character.character_name)
  570.     index = character.character_index
  571.     pattern = character.pattern < 3 ? character.pattern : 1
  572.     sx = (index % 4 * 3 + pattern) * cw
  573.     sy = (index / 4 * 4 + (character.direction - 2) / 2) * ch
  574.     @src_rect.set(sx, sy, cw, ch)
  575.     draw_character(x, y, cw, ch, charmap, @src_rect)
  576.   end
  577.   
  578.   #--------------------------------------------------------------------------
  579.   # * create the shadow map
  580.   #--------------------------------------------------------------------------
  581.   def make_shadow_map
  582.     for s in 0 ... 16
  583.       x = s % 4
  584.       y = s / 4
  585.       if s & 0b1000 == 0b1000
  586.         @shadow_bitmap.fill_rect(x*tilesize+16, y*@tilesize+16, 16, 16, SHADOW_COLOR)
  587.       end
  588.       if s & 0b0100 == 0b0100
  589.         @shadow_bitmap.fill_rect(x*tilesize, y*@tilesize+16, 16, 16, SHADOW_COLOR)
  590.       end
  591.       if s & 0b0010 == 0b0010
  592.         @shadow_bitmap.fill_rect(x*tilesize+16, y*@tilesize, 16, 16, SHADOW_COLOR)
  593.       end
  594.       if s & 0b0001 == 0b0001
  595.         @shadow_bitmap.fill_rect(x*tilesize, y*@tilesize, 16, 16, SHADOW_COLOR)
  596.       end
  597.     end
  598.   end
  599.   
  600.   def draw_parallax
  601.     image = Cache.parallax(@map.parallax_name)
  602.     @src_rect.set(0, 0, image.width, image.height)
  603.     @map_image.blt(0, 0, image, @src_rect)
  604.   end
  605.   
  606.   #--------------------------------------------------------------------------
  607.   # * Draw the shadow map
  608.   #--------------------------------------------------------------------------
  609.   def draw_shadow_map
  610.     for x in @start_x ... @end_x
  611.       for y in @start_y ... @end_y
  612.       _x, _y = x*@tilesize, y*@tilesize
  613.         s = @map.data[x, y, 3]  & 0b1111
  614.         if s != 0
  615.           x_ = (s % 4) * @tilesize
  616.           y_ = (s / 4) * @tilesize
  617.           @src_rect.set(x_, y_, @tilesize, @tilesize)
  618.           draw_tile(x, y, @shadow_bitmap, @src_rect)
  619.         end
  620.       end
  621.     end
  622.   end
  623.   
  624.   #--------------------------------------------------------------------------
  625.   # * Draw the specified layer
  626.   #--------------------------------------------------------------------------
  627.   def draw_layer(layer)
  628.     for x in @start_x ... @end_x
  629.       for y in @start_y ... @end_y
  630.         _x, _y = x*@tilesize, y*@tilesize
  631.         tile_id = @map.data[x, y, layer]
  632.         next if tile_id == 0
  633.         get_bitmap(tile_id)
  634.         draw_tile(x, y, @tile, @tile_rect)
  635.       end
  636.     end
  637.   end
  638.   
  639.   #-----------------------------------------------------------------------------
  640.   # Draw game regions
  641.   #-----------------------------------------------------------------------------
  642.   def draw_regions
  643.     if $imported["TH_RegionOverlay"]
  644.       image = SceneManager.scene.instance_variable_get(:@spriteset).instance_variable_get(:@region_map).bitmap
  645.       @src_rect.set(@start_x * tilesize, @start_y * tilesize, image.width, image.height)
  646.       @map_image.blt(0, 0, image, @src_rect, 255)
  647.     end
  648.   end
  649.   
  650.   def draw_passages
  651.     if $imported["TH_OverlayPassageMap"]
  652.       image = SceneManager.scene.instance_variable_get(:@spriteset).instance_variable_get(:@passage_map).bitmap
  653.       @src_rect.set(@start_x * tilesize, @start_y * tilesize, image.width, image.height)
  654.       @map_image.blt(0, 0, image, @src_rect, 255)
  655.     end
  656.   end

  657.   #--------------------------------------------------------------------------
  658.   # * Draw the game player
  659.   #--------------------------------------------------------------------------
  660.   def draw_player
  661.     set_character_bitmap($game_player, $game_player.x, $game_player.y) if @map_id == $game_map.map_id
  662.   end
  663.   
  664.   def draw_followers
  665.   end
  666.   
  667.   #--------------------------------------------------------------------------
  668.   # * Draw map events
  669.   #--------------------------------------------------------------------------
  670.   def draw_events
  671.     @map.events.values.each do |event|
  672.       canDraw = event.pages[0].list.any? do |cmd|
  673.         cmd.code == 108 && cmd.parameters[0] =~ /<screenshot:\s*tile\s*>/i
  674.       end
  675.       next unless @draw_events || canDraw
  676.       id = event.pages[0].graphic.tile_id
  677.       char_name = event.pages[0].graphic.character_name
  678.       if id > 0
  679.         normal_tile(id)
  680.         draw_tile(event.x, event.y, @tilemap, @src_rect)
  681.       elsif char_name != ""
  682.         set_character_bitmap(event.pages[0].graphic, event.x, event.y)
  683.       end
  684.     end
  685.   end
  686.   
  687.   #--------------------------------------------------------------------------
  688.   # * Draw map vehicles
  689.   #--------------------------------------------------------------------------
  690.   def draw_vehicles
  691.     $game_map.vehicles.each do |vehicle|
  692.       set_character_bitmap(vehicle, vehicle.x, vehicle.y) if @map_id == vehicle.map_id
  693.     end
  694.   end
  695.   
  696.   #--------------------------------------------------------------------------
  697.   # * Draw map sprites
  698.   #--------------------------------------------------------------------------
  699.   def draw_sprites
  700.     draw_events
  701.     draw_vehicles if @draw_vehicles
  702.     draw_player if @draw_player
  703.     draw_followers if @draw_followers
  704.   end
  705.   
  706.   #--------------------------------------------------------------------------
  707.   # * Highlight damage tiles
  708.   #--------------------------------------------------------------------------
  709.   def draw_damage
  710.     @tile.clear
  711.     @tile.fill_rect(0, 0, @tilesize, @tilesize, DAMAGE_COLOR)
  712.     @src_rect.set(0, 0, @tilesize, @tilesize)
  713.     for x in @start_x ... @end_x
  714.       for y in @start_y ... @end_y
  715.         _x, _y = x*@tilesize, y*@tilesize
  716.         if damage_floor?(x, y)
  717.           draw_tile(x, y, @tile, @src_rect)
  718.         end
  719.       end
  720.     end
  721.   end
  722.   
  723.   def draw_screen_effects
  724.   end
  725.   #--------------------------------------------------------------------------
  726.   # * Draw the map
  727.   #--------------------------------------------------------------------------
  728.   def draw_map
  729.     make_shadow_map if @draw_shadow
  730.     draw_parallax
  731.     draw_layer(0)
  732.     draw_layer(1)
  733.     draw_shadow_map
  734.     draw_layer(2)
  735.     draw_damage if @draw_damage
  736.     draw_regions if @draw_regions
  737.     draw_passages if @draw_passages
  738.     draw_sprites
  739.     draw_screen_effects
  740.   end
  741.   
  742.   #--------------------------------------------------------------------------
  743.   # * Scale the map
  744.   #--------------------------------------------------------------------------
  745.   def scale_map
  746.     nw = @width * @scale
  747.     nh = @height * @scale
  748.     @src_rect.set(0, 0, @width, @height)
  749.     scaled_map = Bitmap.new(nw, nh)
  750.     scaled_rect = Rect.new(0, 0, nw, nh)
  751.     scaled_map.stretch_blt(scaled_rect, @map_image, @src_rect)
  752.     @map_image = scaled_map
  753.   end
  754.   
  755.   #--------------------------------------------------------------------------
  756.   # * Take a mapshot of the map
  757.   #--------------------------------------------------------------------------
  758.   def mapshot
  759.     @screen_local = false
  760.     redraw
  761.     export(TH::Map_Saver::Mapshot_Directory)
  762.     $game_message.add("Mapshot taken")
  763.   end
  764.    
  765.   #--------------------------------------------------------------------------
  766.   # * Take a screenshot of the map
  767.   #--------------------------------------------------------------------------
  768.   def screenshot
  769.     @screen_local = true
  770.     redraw
  771.     export(TH::Map_Saver::Screenshot_Directory)
  772.     $game_message.add("Screenshot taken")
  773.   end
  774.   
  775.   #--------------------------------------------------------------------------
  776.   # * Get the format to export to
  777.   #--------------------------------------------------------------------------
  778.   def get_format
  779.     TH::Map_Saver::Export_Format
  780.   end
  781.   
  782.   #--------------------------------------------------------------------------
  783.   # * Export the map to a file
  784.   #--------------------------------------------------------------------------
  785.   def export(dirName="")
  786.     format = get_format
  787.     #name = @map.display_name != "" ? @map.display_name : @map_info.name
  788.     name = sprintf("Map%03d" %[@map_id])
  789.     Dir.mkdir(dirName) unless File.directory?(dirName)
  790.     name =
  791.     filename = "%s\\%s.%s" %[dirName, name, format]
  792.     t1 = Time.now
  793.     @map_image.save(filename)
  794.     t2 = Time.now
  795.     $game_message.add("Exported in %f seconds" %[t2 - t1])
  796.   end
  797. end

  798. class Bitmap

  799.   def save(filename, options = {})
  800.     options.merge!(format: File.extname(filename)[1..-1].to_sym)
  801.     retval = false
  802.     #bitmap = Gdiplus::Bitmap.new(:hbitmap, hbitmap)
  803.     #bitmap = Gdiplus::Bitmap.new(:gdidib, *gdidib)
  804.     # this seems to be the fastest one (RGSS 3.0.1, Windows 8 64-bit)
  805.     bitmap = Gdiplus::Bitmap.new(:scan0, width, height, scan0)
  806.     if bitmap
  807.       retval = bitmap.save(:file, filename, options[:format])
  808.       bitmap.dispose
  809.     end
  810.     retval
  811.   end

  812. private

  813.   def _data_struct(offset = 0)
  814.     @_data_struct ||= (DL::CPtr.new((object_id << 1) + 16).ptr + 8).ptr
  815.     (@_data_struct + offset).ptr.to_i
  816.   end

  817.   def gdidib
  818.      [_data_struct(8), _data_struct(16)]
  819.   end

  820.   def hbitmap
  821.     _data_struct(44)
  822.   end

  823.   def scan0
  824.     _data_struct(12)
  825.   end

  826. end

  827. # ★ GDI+ interface
  828. # ★★★★★★★★★★★★
  829. #
  830. # Author : Cremno
  831. #

  832. module Gdiplus
  833.   DLL = 'gdiplus.dll'

  834.   def self.get_function name, import, export = 'L'
  835.     Win32API.new DLL, name, import, export
  836.   end

  837.   FUNCTIONS = {
  838.     GdiplusStartup: get_function('GdiplusStartup', 'PPP'),
  839.     GdiplusShutdown: get_function('GdiplusShutdown', 'P', 'V'),
  840.     GdipDisposeImage: get_function('GdipDisposeImage', 'P'),
  841.     GdipSaveImageToFile: get_function('GdipSaveImageToFile', 'PPPP'),
  842.     GdipCreateBitmapFromGdiDib: get_function('GdipCreateBitmapFromGdiDib', 'LLP'),
  843.     GdipCreateBitmapFromHBITMAP: get_function('GdipCreateBitmapFromHBITMAP', 'LLP'),
  844.     GdipCreateBitmapFromScan0: get_function('GdipCreateBitmapFromScan0', 'LLLLPP')
  845.   }

  846.   @@token = [0].pack('I')
  847.   def self.token
  848.     @@token
  849.   end

  850.   @@clsids = {}
  851.   def self.clsids
  852.     @@clsids
  853.   end

  854.   def self.gen_clsids
  855.     return unless @@clsids.empty?
  856.     func = Win32API.new('rpcrt4.dll', 'UuidFromString', 'PP', 'L')
  857.     {
  858.       bmp:  '557cf400-1a04-11d3-9a73-0000f81ef32e',
  859.       jpeg: '557cf401-1a04-11d3-9a73-0000f81ef32e',
  860.       gif:  '557cf402-1a04-11d3-9a73-0000f81ef32e',
  861.       tiff: '557cf405-1a04-11d3-9a73-0000f81ef32e',
  862.       png:  '557cf406-1a04-11d3-9a73-0000f81ef32e'
  863.     }.each_pair do |k, v|
  864.       clsid = [0].pack('I')
  865.       func.call(v, clsid)
  866.       @@clsids[k] = clsid
  867.     end
  868.     @@clsids[:jpg] = @@clsids[:jpeg]
  869.     @@clsids[:tif] = @@clsids[:tiff]
  870.   end

  871.   # TODO: prepend prefix (Gdip or Gdiplus) automatically
  872.   def self.call(*args)
  873.     name = args.shift
  874.     func = FUNCTIONS[name]
  875.     v = func.call(*args)
  876.     if v && v != 0
  877.       msgbox "GDI+ error: #{v}\n\nFunction: #{name}\nArguments: #{args.inspect}"
  878.       false
  879.     else
  880.       true
  881.     end
  882.   end

  883.   def self.startup
  884.     call :GdiplusStartup, @@token, [1, 0, 0, 0].pack('L4'), 0
  885.   end

  886.   def self.shutdown
  887.     call :GdiplusShutdown, @@token
  888.   end

  889.   class Image

  890.     attr_reader :instance
  891.     def initialize
  892.       @instance = 0
  893.       true
  894.     end

  895.     def save(destination, *args)
  896.       case destination
  897.       when :file
  898.         filename = args.shift << "\0"
  899.         filename.encode!('UTF-16LE')
  900.         argv = [:GdipSaveImageToFile, filename, Gdiplus.clsids[args.shift], 0]
  901.       else
  902.         raise ArgumentError, "unknown GDI+ image destination: #{source}"
  903.       end
  904.       argv.insert(1, @instance)
  905.       Gdiplus.call *argv
  906.     end

  907.     def dispose
  908.       Gdiplus.call :GdipDisposeImage, @instance
  909.     end
  910.   end

  911.   class Bitmap < Image

  912.     def initialize source, *args
  913.       case source
  914.       when :gdidib
  915.         argv = [:GdipCreateBitmapFromGdiDib, args.shift, args.shift]
  916.       when :hbitmap
  917.         argv = [:GdipCreateBitmapFromHBITMAP, args.shift, 0]
  918.       when :scan0
  919.         w = args.shift
  920.         h = args.shift
  921.         argv = [:GdipCreateBitmapFromScan0, w, h, w * -4, 0x26200a, args.shift]
  922.       else
  923.         raise ArgumentError, "unknown GDI+ bitmap source: #{source}"
  924.       end
  925.       argv.push([0].pack('I'))
  926.       retval = Gdiplus.call *argv
  927.       @instance = retval ? argv.last.unpack('I').first : 0
  928.       retval
  929.     end
  930.   end
  931. end

  932. if Gdiplus.startup
  933.   Gdiplus.gen_clsids
  934.   class << SceneManager
  935.     alias_method :run_wo_gdip_shutdown, :run
  936.     def run
  937.       run_wo_gdip_shutdown
  938.       Gdiplus.shutdown
  939.     end
  940.   end
  941. end

  942. #==============================================================================
  943. # * Compatibility add-ons
  944. #==============================================================================
  945. #Yami overlays
  946. if $imported["YSE-OverlayMapping"]
  947.   class Map_Saver
  948.     def draw_overlay_map_ground
  949.       filename = YSA::OVERLAY::GROUND
  950.       filename += $game_map.map_id.to_s
  951.       filename += "-" + $game_variables[YSA::OVERLAY::GROUND_VARIABLE].to_s
  952.       p filename
  953.       image = Cache.overlay(filename)
  954.       @src_rect.set(@start_x*tilesize, @start_y*tilesize, image.width, image.height)
  955.       @map_image.blt(0, 0, image, @src_rect)
  956.     end
  957.    
  958.     def draw_overlay_map_parallax
  959.       filename = YSA::OVERLAY::PARALLAX
  960.       filename += $game_map.map_id.to_s
  961.       filename += "-" + $game_variables[YSA::OVERLAY::PARALLAX_VARIABLE].to_s
  962.       image = Cache.overlay(filename)
  963.       @src_rect.set(@start_x*tilesize, @start_y*tilesize, image.width, image.height)
  964.       @map_image.blt(0, 0, image, @src_rect)
  965.     end
  966.    
  967.     def draw_overlay_map_light
  968.       filename = YSA::OVERLAY::LIGHT
  969.       filename += $game_map.map_id.to_s
  970.       filename += "-" + $game_variables[YSA::OVERLAY::LIGHT_VARIABLE].to_s
  971.       image = Cache.overlay(filename)
  972.       @src_rect.set(@start_x*tilesize, @start_y*tilesize, image.width, image.height)
  973.       @map_image.blt(0, 0, image, @src_rect, 10)
  974.     end
  975.    
  976.     def draw_overlay_map_shadow
  977.       filename = YSA::OVERLAY::SHADOW
  978.       filename += $game_map.map_id.to_s
  979.       filename += "-" + $game_variables[YSA::OVERLAY::SHADOW_VARIABLE].to_s
  980.       image = Cache.overlay(filename)
  981.       @src_rect.set(@start_x*tilesize, @start_y*tilesize, image.width, image.height)
  982.       @map_image.blt(0, 0, image, @src_rect, 10)
  983.     end
  984.   
  985.     alias :th_map_overlay_draw_map :draw_map
  986.     def draw_map
  987.       th_map_overlay_draw_map
  988.       draw_overlay_map_ground if $game_switches[YSA::OVERLAY::GROUND_SWITCH]
  989.       draw_overlay_map_parallax if $game_switches[YSA::OVERLAY::PARALLAX_SWITCH]
  990.       draw_overlay_map_shadow if $game_switches[YSA::OVERLAY::SHADOW_SWITCH]
  991.       draw_overlay_map_light if $game_switches[YSA::OVERLAY::LIGHT_SWITCH]
  992.     end
  993.   end
  994. end

  995. if $imported["TH_AreaOverlay"]
  996.   class Map_Saver
  997.     def draw_overlay_area_map
  998.       image = SceneManager.scene.instance_variable_get(:@spriteset).instance_variable_get(:@area_map).bitmap
  999.       @src_rect.set(@start_x * tilesize, @start_y * tilesize, image.width, image.height)
  1000.       @map_image.blt(0, 0, image, @src_rect, 255)
  1001.     end
  1002.    
  1003.     alias :th_area_overlay_draw_map :draw_map
  1004.     def draw_map
  1005.       th_area_overlay_draw_map
  1006.       draw_overlay_area_map
  1007.     end
  1008.   end
  1009. end
复制代码

评分

参与人数 1星屑 +150 收起 理由
RaidenInfinity + 150 版主认可的答案

查看全部评分

游戏开发工具集,一站式AI生图+图片完美像素化及相关处理网站。
群爆炸重建后状态:论坛老人最多(只剩下了活跃的老人),技术力很强(依旧不变)的编程灌水群:901540785
专门讨论RM相关的Q群:56875149
PS:第一个群不是专门讨论RM的,第二个才是哦。
PS2:接受MV/MZ插件定制(QQ763992443)
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部