Project1

标题: [猫儿的RMXP工具箱第七弹]自动绘制迷宫墙壁 [打印本页]

作者: SailCat    时间: 2016-1-26 00:33
标题: [猫儿的RMXP工具箱第七弹]自动绘制迷宫墙壁
有没有很眼馋RMVA、RMMV的“自动元件绘制迷宫”功能?
有没有很苦手RMXP绘制迷宫没有自动元件的墙壁用?(XXX图块为什么没有自动元件屋顶?抓狂!!)
有没有很纠结大量的无意义体力活浪费在填涂迷宫墙壁上?

这一切都结束了!
有了这个工具脚本, 所有迷宫的绘制过程,将从
铺地板>>涂墙壁>>局部修改>>装饰
简化为
铺地板>>运行脚本>>局部修改>>装饰

脚本如下:

RUBY 代码复制
  1. #==============================================================================
  2. # ■ Auto_MazeWalls
  3. #------------------------------------------------------------------------------
  4. #   自动生成迷宫的墙壁,默认支持的迷宫种类有:
  5. #   农村内部(24)、教会内部(29)、城寨内部(38)、塔内部(40)、魔物城堡内部
  6. # (42)、土之洞窟(43)、炎之洞窟(44)、冰之洞窟(45)、水之洞窟(46)、矿山
  7. # (47)、体内(49),也就是不能用自动元件画墙壁的所有图块。
  8. #   使用方法:
  9. #   绘制一张只有一层(F5)层的地图,并只绘制地面的部分(即人可以走到的部分),
  10. # 其他位置全部留空——注意是留空,不要用别的东西填充了
  11. #   插入本脚本到Game_Temp(注意不是Main)之前,然后在末尾添加
  12. #
  13. #   $auto_fill = Auto_MazeWalls.new(地图编号)
  14. #   $auto_fill = fill_wall(墙壁高度)
  15. #   $auto_fill.save
  16. #   exit
  17. #
  18. #   运行完毕后请重新打开工程或相关地图。
  19. #   注释掉本脚本末尾的四行可以屏蔽该功能正常测试游戏。
  20. #   注:
  21. #   1) 地图编号不存在的话,脚本将无效直接关闭
  22. #   2) 部分图块锁定了墙高(24、29、38),墙壁高度填写任何值都是无效的
  23. #   3) 墙壁高度如填写为负数,则会生成悬空式迷宫,但前提是图块支持这种迷宫
  24. #   4) 如果有多张地图需要生成墙壁,请分别执行
  25. #   5) 如果地形有冲突(如墙高度不够),图块会重叠或空白,请手工修改冲突的地方
  26. #==============================================================================
  27.  
  28. class Auto_MazeWalls
  29.   #--------------------------------------------------------------------------
  30.   # ● 初始化对像
  31.   #--------------------------------------------------------------------------  
  32.   def initialize(map_id)
  33.     @filename = sprintf("Data/Map%03d.rxdata", map_id)
  34.     if FileTest.exist?(@filename)
  35.       @map = load_data(@filename)
  36.       @width = @map.width
  37.       @height = @map.height
  38.       setup(@map.tileset_id)
  39.     else
  40.       exit
  41.     end
  42.   end
  43.  
  44.   #--------------------------------------------------------------------------
  45.   # ● 保存地图
  46.   #--------------------------------------------------------------------------  
  47.   def save
  48.     save_data(@map, @filename)
  49.   end
  50.  
  51.   #--------------------------------------------------------------------------
  52.   # ● 根据图块ID获得填涂ID表
  53.   #--------------------------------------------------------------------------  
  54.   def setup(tileset_id)
  55.     case tileset_id
  56.     when 24 # 农村 内部
  57.       @force_height = 2
  58.       @floor = 384
  59.       @dark = 396
  60.       @covers = [387, 388, 389]
  61.       @walls_low = [-419, 420, -421]
  62.       @walls_med = [411, 412, 413]
  63.       @walls_top = [403, 404, 405]
  64.       @line_l = 395
  65.       @line_r = 397
  66.       @corner_lu = 390
  67.       @corner_ru = 391
  68.       @corner_lb = 398
  69.       @corner_rb = 399
  70.       @d_corner1 = 0
  71.       @d_corner2 = 0
  72.       @allow_deep = false
  73.       @shades = {384 => 385, 404 => 404, 412 => 401, 420 => 409}
  74.     when 29 # 教会 内部
  75.       @force_height = 3
  76.       @floor = 384
  77.       @dark = 409
  78.       @covers = [400, 401, 402]
  79.       @walls_low = [440, 441, 442]
  80.       @walls_med = [432, 433, 434]
  81.       @walls_rim = [424, 425, 426]
  82.       @walls_top = [416, 417, 418]
  83.       @line_l = 408
  84.       @line_r = 410
  85.       @corner_lu = 403
  86.       @corner_ru = 404
  87.       @corner_lb = 411
  88.       @corner_rb = 412
  89.       @d_corner1 = 0
  90.       @d_corner2 = 0
  91.       @allow_deep = false
  92.       @shades = {384 => 385, 417 => 417, 425 => 427, 433 => 435, 441 => 443}
  93.     when 38 # 城寨 内部
  94.       @force_height = 2
  95.       @floor = 384
  96.       @dark = 409
  97.       @covers = [400, 401, 402]
  98.       @walls_low = [-432, 433, -434]
  99.       @walls_med = [424, 425, 426]
  100.       @walls_top = [416, 417, 418]
  101.       @line_l = 408
  102.       @line_r = 410
  103.       @corner_lu = 403
  104.       @corner_ru = 404
  105.       @corner_lb = 411
  106.       @corner_rb = 412
  107.       @d_corner1 = 0
  108.       @d_corner2 = 0
  109.       @allow_deep = false
  110.       @shades = {384 => 386, 417 => 417, 425 => 419, 433 => 427}
  111.     when 40 # 塔 内部
  112.       @force_height = 0
  113.       @floor = 384
  114.       @dark = 409
  115.       @covers = [400, 401, 402]
  116.       @walls_low = [432, 433, 434]
  117.       @walls_med = [424, 425, 426]
  118.       @walls_top = [416, 417, 418]
  119.       @line_l = 408
  120.       @line_r = 410
  121.       @corner_lu = 403
  122.       @corner_ru = 404
  123.       @corner_lb = 411
  124.       @corner_rb = 412
  125.       @d_corner1 = 0
  126.       @d_corner2 = 0
  127.       @allow_deep = false
  128.       @shades = {384 => 385, 417 => 417, 425 => 427, 433 => 435}
  129.     when 42 # 魔物城堡 内部
  130.       @force_height = 0
  131.       @floor = 384
  132.       @dark = 409
  133.       @covers = [400, 401, 402]
  134.       @walls_low = [432, 433, 434]
  135.       @walls_med = [424, 425, 426]
  136.       @walls_top = [416, 417, 418]
  137.       @line_l = 408
  138.       @line_r = 410
  139.       @corner_lu = 403
  140.       @corner_ru = 404
  141.       @corner_lb = 411
  142.       @corner_rb = 412
  143.       @d_corner1 = 0
  144.       @d_corner2 = 0
  145.       @allow_deep = true
  146.       @depths = [437, 438, 439, 445, 446, 447, 453, 454, 455, 461, 462, 463, 469, 470, 471]
  147.       @void = 393
  148.       @flat_top = [405, 406, 407]
  149.       @flat_l = 413
  150.       @flat_r = 415
  151.       @flat_bottom = [421, 422, 423]
  152.       @d_flat1 = 0
  153.       @d_flat2 = 0
  154.       @flat_lu = 419
  155.       @flat_ru = 420
  156.       @flat_lb = 427
  157.       @flat_rb = 428
  158.       @shades = {384 => 385, 417 => 440, 425 => 448, 433 => 456}
  159.     when 43..46 # 属性洞穴
  160.       @force_height = 0
  161.       @floor = 384
  162.       @dark = 425
  163.       @covers = [416, 417, 418]
  164.       @walls_low = [448, 449, 450]
  165.       @walls_med = [440, 441, 442]
  166.       @walls_top = [432, 433, 434]
  167.       @line_l = 424
  168.       @line_r = 426
  169.       @corner_lu = 419
  170.       @corner_ru = 420
  171.       @corner_lb = 427
  172.       @corner_rb = 428
  173.       @d_corner1 = 435
  174.       @d_corner2 = 436
  175.       @allow_deep = true
  176.       @depths = [488, 489, 490, 496, 497, 498, 504, 505, 506,
  177.                  512, 513, 514, 520, 521, 522, 528, 529, 530]
  178.       @void = 425
  179.       @flat_top = [421, 422, 423]
  180.       @flat_l = 429
  181.       @flat_r = 431
  182.       @flat_bottom = [437, 438, 439]
  183.       @d_flat1 = 443
  184.       @d_flat2 = 444
  185.       @flat_lu = 451
  186.       @flat_ru = 452
  187.       @flat_lb = 459
  188.       @flat_rb = 460
  189.       @shades = {384 => 96, 433 => 445, 441 => 453, 449 => 461}
  190.     when 47 # 矿山
  191.       @force_height = 0
  192.       @floor = 384
  193.       @dark = 409
  194.       @covers = [400, 401, 402]
  195.       @walls_low = [-432, -433, -434]
  196.       @walls_med = [424, 425, 426]
  197.       @walls_top = [416, 417, 418]
  198.       @line_l = 408
  199.       @line_r = 410
  200.       @corner_lu = 403
  201.       @corner_ru = 404
  202.       @corner_lb = 411
  203.       @corner_rb = 412
  204.       @d_corner1 = 0
  205.       @d_corner2 = 0
  206.       @allow_deep = true
  207.       @depths = [429, 430, 431, 437, 438, 439, 445, 446, 447,
  208.                  453, 454, 455, 461, 462, 463, 469, 470, 471]
  209.       @void = 409
  210.       @flat_top = [405, 406, 407]
  211.       @flat_l = 413
  212.       @flat_r = 415
  213.       @flat_bottom = [421, 422, 423]
  214.       @d_flat1 = 0
  215.       @d_flat2 = 0
  216.       @flat_lu = 419
  217.       @flat_ru = 420
  218.       @flat_lb = 427
  219.       @flat_rb = 428
  220.       @shades = {384 => 385, 417 => 464, 425 => 472, 433 => 480}
  221.     when 49 # 体内
  222.       @force_height = 0
  223.       @floor = 384
  224.       @dark = 433
  225.       @covers = [424, 425, 426]
  226.       @walls_low = [-456, -457, -458]
  227.       @walls_med = [448, 449, 450]
  228.       @walls_top = [440, 441, 442]
  229.       @line_l = 432
  230.       @line_r = 434
  231.       @corner_lu = 435
  232.       @corner_ru = 436
  233.       @corner_lb = 443
  234.       @corner_rb = 444
  235.       @d_corner1 = 0
  236.       @d_corner2 = 0
  237.       @allow_deep = true
  238.       @depths = [461, 462, 463, 469, 470, 471, 477, 478, 479, 485, 486, 487, 493, 494, 495]
  239.       @void = 433
  240.       @flat_top = [429, 430, 431]
  241.       @flat_l = 437
  242.       @flat_r = 439
  243.       @flat_bottom = [445, 446, 447]
  244.       @d_flat1 = 0
  245.       @d_flat2 = 0
  246.       @flat_lu = 451
  247.       @flat_ru = 452
  248.       @flat_lb = 459
  249.       @flat_rb = 460
  250.       @shades = {384 => 385, 441 => 464, 449 => 472, 457 => 480}
  251.     end
  252.   end
  253.  
  254.   #--------------------------------------------------------------------------
  255.   # ● 填涂墙壁
  256.   #     wall_height: 墙壁高度(负值为悬空式,可能会被图块锁定)
  257.   #--------------------------------------------------------------------------  
  258.   def fill_wall(wall_height = 2)
  259.     # 检查深渊地形
  260.     if wall_height < 0
  261.       if @allow_deep
  262.         fill_depth
  263.         return
  264.       else # 图块没有深渊地形的情况下,按2格默认高度填涂墙壁
  265.         wall_height = [2, @force_height].max
  266.       end
  267.     end
  268.     # 强制墙高生效
  269.     wall_height = @force_height if @force_height != 0
  270.     # 勾勒地板边缘
  271.     tile_data = Table.new(@width, @height)
  272.     for i in 0...@width
  273.       for j in 0...@height
  274.         tile_data[i, j] = get_border_tile(i, j)
  275.       end
  276.     end
  277.     # 填涂地板边缘和F5层(背板遮挡填在F6层)
  278.     for i in 0...@width
  279.       for j in 0...@height
  280.         unless @covers.include?(tile_data[i, j])
  281.           if tile_data[i, j] > 0
  282.             @map.data[i, j, 0] = tile_data[i, j]
  283.           else
  284.             @map.data[i, j, 0] = @floor
  285.             @map.data[i, j, 1] = -tile_data[i, j]
  286.           end
  287.         else
  288.           @map.data[i, j - 1, 1] = tile_data[i, j] if j > 0
  289.           case tile_data[i, j]
  290.           when @covers[0]
  291.             if j < @height - 1 and tile_data[i, j + 1] == @dark
  292.               @map.data[i, j, 0] = @corner_lu
  293.             else
  294.               @map.data[i, j, 0] = @line_l
  295.             end
  296.           when @covers[1]
  297.             @map.data[i, j, 0] = @dark
  298.           when @covers[2]
  299.             if j < @height - 1 and tile_data[i, j + 1] == @dark
  300.               @map.data[i, j, 0] = @corner_ru
  301.             else
  302.               @map.data[i, j, 0] = @line_r
  303.             end
  304.           end
  305.         end
  306.       end
  307.     end
  308.     # 墙高及纵向墙线的增长
  309.     wall_data = {}
  310.     for i in 0...@width
  311.       for j in 0...@height
  312.         index = @walls_low.index(@map.data[i, j, 0])
  313.         index = @walls_low.index([email]-@map.data[/email][i, j, 1]) if index == nil
  314.         if index != nil
  315.           # 不是固定墙高3的情况下
  316.           unless @force_height == 3
  317.             (wall_height - 1).times do |n|
  318.               wall_data[[i, j - n - 1]] = @walls_med[index] if j > n
  319.             end
  320.           else
  321.             wall_data[[i, j - 1]] = @walls_med[index] if j > 0
  322.             wall_data[[i, j - 2]] = @walls_rim[index] if j > 1
  323.           end
  324.           wall_data[[i, j - wall_height]] = @walls_top[index] if j >= wall_height
  325.         elsif @map.data[i, j, 0] == @line_l and @map.data[i, j - 1, 0] == @dark
  326.           (wall_height - 1).times do |n|
  327.             wall_data[[i, j - n - 1]] = @line_l if j > n
  328.           end
  329.           # 交角处理
  330.           if j >= wall_height
  331.             if @map.data[i, j - wall_height, 0] == @corner_ru
  332.               wall_data[[i, j - wall_height]] = @d_corner2
  333.             else
  334.               wall_data[[i, j - wall_height]] = @corner_lb
  335.             end
  336.           end
  337.         elsif @map.data[i, j, 0] == @line_r and @map.data[i, j - 1, 0] == @dark
  338.           (wall_height - 1).times do |n|
  339.             wall_data[[i, j - n - 1]] = @line_r if j > n
  340.           end
  341.           # 交角处理
  342.           if j >= wall_height
  343.             if @map.data[i, j - wall_height, 0] == @corner_lu
  344.               wall_data[[i, j - wall_height]] = @d_corner1
  345.             else
  346.               wall_data[[i, j - wall_height]] = @corner_rb
  347.             end
  348.           end
  349.         end
  350.       end
  351.     end
  352.     # 填涂墙壁
  353.     wall_data.each do |k, v|
  354.       @map.data[k[0], k[1], 0] = v
  355.     end
  356.     # 末行处理
  357.     for i in 0...@width
  358.       if @map.data[i, @height - 1, 0] == @floor
  359.         @map.data[i, @height - 1, 1] = @covers[1]
  360.       end
  361.     end
  362.     # 阴影处理
  363.     @width.times do |n|
  364.       i = @width - n
  365.       for j in 0...@height
  366.         # 地板的阴影
  367.         if @map.data[i, j, 0] == @floor
  368.           unless @map.data[i - 1, j - 1, 0] == @floor or
  369.             @map.data[i - 1, j, 0] == @floor or
  370.             (@map.data[i - 1, j + 1, 0] == @floor and
  371.             @map.data[i - 1, j + 1, 1] != -@walls_low[2])
  372.             @map.data[i, j, 0] = @shades[@floor]
  373.           end
  374.         end
  375.         # 墙壁的阴影
  376.         if @map.data[i, j, 0] == @walls_top[1]
  377.           if @map.data[i - 1, j + 1, 0] == @line_r
  378.             for k in 0..wall_height
  379.               if j + k < @height
  380.                 @map.data[i, j + k, 0] = @shades[@map.data[i, j + k, 0]]
  381.                 if @map.data[i, j + k, 1] == -@walls_low[1]
  382.                   @map.data[i, j + k, 1] = @shades[@map.data[i, j + k, 1]]
  383.                 end
  384.               end
  385.             end
  386.           end
  387.         end
  388.       end
  389.     end
  390.   end
  391.  
  392.   #--------------------------------------------------------------------------
  393.   # ● 获得勾勒墙壁图块
  394.   #     x: 地图的 x 坐标
  395.   #     y: 地图的 y 坐标
  396.   #--------------------------------------------------------------------------   
  397.   def get_border_tile(x, y)
  398.     s = @map.data[x, y, 0]
  399.     return s if s != 0
  400.     case neighbor_data(x, y)
  401.     when 0, 2, 128
  402.       return @dark
  403.     when 1, 3, 129, 131
  404.       return @covers[1]
  405.     when 16, 24, 48, 56
  406.       return @walls_low[1]
  407.     when 4, 6
  408.       return @corner_ru
  409.     when 64, 192
  410.       return @corner_lu
  411.     when 8, 12, 14
  412.       return @line_r
  413.     when 32, 96, 224
  414.       return @line_l
  415.     when 80, 88, 112, 120, 208, 216, 240, 248
  416.       return @walls_low[0]
  417.     when 20, 22, 28, 30, 52, 54, 60, 62
  418.       return @walls_low[2]
  419.     when 65, 67, 97, 99, 193, 195, 225, 227
  420.       return @covers[0]
  421.     when 5, 7, 13, 15, 133, 135, 141, 143
  422.       return @covers[2]
  423.     else
  424.       return 0
  425.     end
  426.   end
  427.  
  428.   #--------------------------------------------------------------------------
  429.   # ● 填涂深渊
  430.   #--------------------------------------------------------------------------  
  431.   def fill_depth
  432.     # 勾勒地板边缘
  433.     tile_data = Table.new(@width, @height)
  434.     for i in 0...@width
  435.       for j in 0...@height
  436.         tile_data[i, j] = get_depth_tile(i, j)
  437.       end
  438.     end
  439.     # 填涂地板边缘和F5层(高台遮挡填在F6层)
  440.     for i in 0...@width
  441.       for j in 0...@height
  442.         unless @flat_top.include?(tile_data[i, j])
  443.           @map.data[i, j, 0] = tile_data[i, j]
  444.         else
  445.           @map.data[i, j, 1] = tile_data[i, j]
  446.           @map.data[i, j, 0] = @void
  447.         end
  448.       end
  449.     end
  450.     # 深渊的增长
  451.     for i in 0...@width
  452.       for j in 0...@height
  453.         index = @flat_bottom.index(@map.data[i, j, 0])
  454.         if index != nil
  455.           for k in [email]0...@depths.length[/email] / 3
  456.             break if @map.data[i, j + k + 1, 0] != @void or j + k + 1 >= @height
  457.             @map.data[i, j + k + 1, 0] = @depths[k * 3 + index]
  458.           end
  459.         end
  460.       end
  461.     end
  462.   end
  463.  
  464.   #--------------------------------------------------------------------------
  465.   # ● 获得勾勒深渊图块
  466.   #     x: 地图的 x 坐标
  467.   #     y: 地图的 y 坐标
  468.   #--------------------------------------------------------------------------   
  469.   def get_depth_tile(x, y)
  470.     s = @map.data[x, y, 0]
  471.     return s if s != 0
  472.     case neighbor_data(x, y)
  473.     when 0
  474.       return @void
  475.     when 2
  476.       return @flat_bottom[0]
  477.     when 1, 3, 129, 131
  478.       return @flat_bottom[1]
  479.     when 128
  480.       return @flat_bottom[2]
  481.     when 8
  482.       return @flat_top[0]
  483.     when 16, 24, 48, 56
  484.       return @flat_top[1]
  485.     when 32
  486.       return @flat_top[2]
  487.     when 4, 6, 12, 14
  488.       return @flat_l
  489.     when 64, 96, 192, 224
  490.       return @flat_r
  491.     when 65, 67, 97, 99, 193, 195, 225, 227
  492.       return @flat_rb
  493.     when 5, 7, 13, 15, 133, 135, 141, 143
  494.       return @flat_lb
  495.     when 80, 88, 112, 120, 208, 216, 240, 248
  496.       return @flat_ru
  497.     when 20, 22, 28, 30, 52, 54, 60, 62
  498.       return @flat_lu
  499.     else
  500.       return 0
  501.     end
  502.   end
  503.  
  504.   #--------------------------------------------------------------------------
  505.   # ● 获得图块的邻近值
  506.   #     x: 地图的 x 坐标
  507.   #     y: 地图的 y 坐标
  508.   #--------------------------------------------------------------------------   
  509.   def neighbor_data(x, y)
  510.     neighbor = [0, 0, 0, 0, 0, 0, 0, 0]
  511.     neighbor[0] = @map.data[x-1, y-1, 0] if x > 0 and y > 0
  512.     neighbor[1] = @map.data[x-1, y, 0] if x > 0
  513.     neighbor[2] = @map.data[x-1, y+1, 0] if x > 0 and y < @height - 1
  514.     neighbor[3] = @map.data[x, y+1, 0] if y < @height - 1
  515.     neighbor[4] = @map.data[x+1, y+1, 0] if x < @width - 1 and y < @height - 1
  516.     neighbor[5] = @map.data[x+1, y, 0] if x < @width - 1
  517.     neighbor[6] = @map.data[x+1, y-1, 0] if x < @width - 1 and y > 0
  518.     neighbor[7] = @map.data[x, y-1, 0] if y > 0
  519.     neighbor.collect!{|n| n > 0 ? 1 : 0}
  520.     return neighbor.inject(0) {|v, n| v = v * 2 + n}
  521.   end
  522. end
  523. # 以下为使用脚本,发布前请删除或注释
  524. $auto_fill = Auto_MazeWalls.new(1)
  525. $auto_fill.fill_wall
  526. $auto_fill.save
  527. exit


效果如下:
Before

After

After-2

范例工程:
AutoFillMap.zip (207.12 KB, 下载次数: 227, 售价: 2 星屑)


作者: yang1zhi    时间: 2016-1-26 10:16
先收下了。


看1楼感觉和这个差不多吧
随机地图生成脚本 v0.80   by tonbi
#
#     汉化修改 66RPG bbschat(2006.1.2)
#
#     随机地图自动生成脚本。
#
作者: SailCat    时间: 2016-1-26 13:33
yang1zhi 发表于 2016-1-26 10:16
先收下了。



不一样,那个是完全凭空生成地形和相应的迷宫,需要设置一堆事件条件,是内嵌插件型脚本。
我这个是交给你自己决定迷宫的地形,脚本省去体力活填充墙壁的时间,是辅助工具型脚本。
作者: yxc990831    时间: 2016-5-23 02:19
求助。。提示280行错误

QQ图片20160523021840.jpg (22.12 KB, 下载次数: 33)

QQ图片20160523021840.jpg

作者: yxc990831    时间: 2016-5-23 02:26
yxc990831 发表于 2016-5-23 02:19
求助。。提示280行错误

还有一个问题就是范例地图测试游戏自动弹出,即闪退
作者: yxc990831    时间: 2016-5-23 03:27
yxc990831 发表于 2016-5-23 02:26
还有一个问题就是范例地图测试游戏自动弹出,即闪退

不好意思,,是我没仔细看{:2_254:}
作者: 喜之狼    时间: 2016-6-5 18:58


求教,是我操作错误吗?
  1.          for k in [email][email protected][/email] / 3
复制代码
是这句
作者: lobee    时间: 2016-8-4 12:54
不会用啊




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1