じ☆ve冰风 发表于 2024-4-20 00:01:42

[猫儿的RMXP工具箱第七弹]自动绘制迷宫墙壁

有没有很眼馋RMVA、RMMV的“自动元件绘制迷宫”功能?
有没有很苦手RMXP绘制迷宫没有自动元件的墙壁用?(XXX图块为什么没有自动元件屋顶?抓狂!!)
有没有很纠结大量的无意义体力活浪费在填涂迷宫墙壁上?

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

脚本如下:

RUBY 代码
#==============================================================================
# ■ Auto_MazeWalls
#------------------------------------------------------------------------------
#   自动生成迷宫的墙壁,默认支持的迷宫种类有:
#   农村内部(24)、教会内部(29)、城寨内部(38)、塔内部(40)、魔物城堡内部
# (42)、土之洞窟(43)、炎之洞窟(44)、冰之洞窟(45)、水之洞窟(46)、矿山
# (47)、体内(49),也就是不能用自动元件画墙壁的所有图块。
#   使用方法:
#   绘制一张只有一层(F5)层的地图,并只绘制地面的部分(即人可以走到的部分),
# 其他位置全部留空——注意是留空,不要用别的东西填充了
#   插入本脚本到Game_Temp(注意不是Main)之前,然后在末尾添加
#
#   $auto_fill = Auto_MazeWalls.new(地图编号)
#   $auto_fill = fill_wall(墙壁高度)
#   $auto_fill.save
#   exit
#
#   运行完毕后请重新打开工程或相关地图。
#   注释掉本脚本末尾的四行可以屏蔽该功能正常测试游戏。
#   注:
#   1) 地图编号不存在的话,脚本将无效直接关闭
#   2) 部分图块锁定了墙高(24、29、38),墙壁高度填写任何值都是无效的
#   3) 墙壁高度如填写为负数,则会生成悬空式迷宫,但前提是图块支持这种迷宫
#   4) 如果有多张地图需要生成墙壁,请分别执行
#   5) 如果地形有冲突(如墙高度不够),图块会重叠或空白,请手工修改冲突的地方
#==============================================================================

class Auto_MazeWalls
#--------------------------------------------------------------------------
# ● 初始化对像
#--------------------------------------------------------------------------
def initialize(map_id)
    @filename = sprintf("Data/Map%03d.rxdata", map_id)
    ifFileTest.exist?(@filename)
      @map = load_data(@filename)
      @width = @map.width
      @height = @map.height
      setup(@map.tileset_id)
    else
      exit
    end
end

#--------------------------------------------------------------------------
# ● 保存地图
#--------------------------------------------------------------------------
def save
    save_data(@map, @filename)
end

#--------------------------------------------------------------------------
# ● 根据图块ID获得填涂ID表
#--------------------------------------------------------------------------
def setup(tileset_id)
    case tileset_id
    when24# 农村 内部
      @force_height = 2
      @floor = 384
      @dark = 396
      @covers =
      @walls_low = [-419, 420, -421]
      @walls_med =
      @walls_top =
      @line_l = 395
      @line_r = 397
      @corner_lu = 390
      @corner_ru = 391
      @corner_lb = 398
      @corner_rb = 399
      @d_corner1 = 0
      @d_corner2 = 0
      @allow_deep = false
      @shades = {384 => 385, 404 => 404, 412 => 401, 420 => 409}
    when29# 教会 内部
      @force_height = 3
      @floor = 384
      @dark = 409
      @covers =
      @walls_low =
      @walls_med =
      @walls_rim =
      @walls_top =
      @line_l = 408
      @line_r = 410
      @corner_lu = 403
      @corner_ru = 404
      @corner_lb = 411
      @corner_rb = 412
      @d_corner1 = 0
      @d_corner2 = 0
      @allow_deep = false
      @shades = {384 => 385, 417 => 417, 425 => 427, 433 => 435, 441 => 443}
    when38# 城寨 内部
      @force_height = 2
      @floor = 384
      @dark = 409
      @covers =
      @walls_low = [-432, 433, -434]
      @walls_med =
      @walls_top =
      @line_l = 408
      @line_r = 410
      @corner_lu = 403
      @corner_ru = 404
      @corner_lb = 411
      @corner_rb = 412
      @d_corner1 = 0
      @d_corner2 = 0
      @allow_deep = false
      @shades = {384 => 386, 417 => 417, 425 => 419, 433 => 427}
    when40# 塔 内部
      @force_height = 0
      @floor = 384
      @dark = 409
      @covers =
      @walls_low =
      @walls_med =
      @walls_top =
      @line_l = 408
      @line_r = 410
      @corner_lu = 403
      @corner_ru = 404
      @corner_lb = 411
      @corner_rb = 412
      @d_corner1 = 0
      @d_corner2 = 0
      @allow_deep = false
      @shades = {384 => 385, 417 => 417, 425 => 427, 433 => 435}
    when42# 魔物城堡 内部
      @force_height = 0
      @floor = 384
      @dark = 409
      @covers =
      @walls_low =
      @walls_med =
      @walls_top =
      @line_l = 408
      @line_r = 410
      @corner_lu = 403
      @corner_ru = 404
      @corner_lb = 411
      @corner_rb = 412
      @d_corner1 = 0
      @d_corner2 = 0
      @allow_deep = true
      @depths =
      @void = 393
      @flat_top =
      @flat_l = 413
      @flat_r = 415
      @flat_bottom =
      @d_flat1 = 0
      @d_flat2 = 0
      @flat_lu = 419
      @flat_ru = 420
      @flat_lb = 427
      @flat_rb = 428
      @shades = {384 => 385, 417 => 440, 425 => 448, 433 => 456}
    when43..46# 属性洞穴
      @force_height = 0
      @floor = 384
      @dark = 425
      @covers =
      @walls_low =
      @walls_med =
      @walls_top =
      @line_l = 424
      @line_r = 426
      @corner_lu = 419
      @corner_ru = 420
      @corner_lb = 427
      @corner_rb = 428
      @d_corner1 = 435
      @d_corner2 = 436
      @allow_deep = true
      @depths = [488, 489, 490, 496, 497, 498, 504, 505, 506,
               512, 513, 514, 520, 521, 522, 528, 529, 530]
      @void = 425
      @flat_top =
      @flat_l = 429
      @flat_r = 431
      @flat_bottom =
      @d_flat1 = 443
      @d_flat2 = 444
      @flat_lu = 451
      @flat_ru = 452
      @flat_lb = 459
      @flat_rb = 460
      @shades = {384 => 96, 433 => 445, 441 => 453, 449 => 461}
    when47# 矿山
      @force_height = 0
      @floor = 384
      @dark = 409
      @covers =
      @walls_low = [-432, -433, -434]
      @walls_med =
      @walls_top =
      @line_l = 408
      @line_r = 410
      @corner_lu = 403
      @corner_ru = 404
      @corner_lb = 411
      @corner_rb = 412
      @d_corner1 = 0
      @d_corner2 = 0
      @allow_deep = true
      @depths = [429, 430, 431, 437, 438, 439, 445, 446, 447,
               453, 454, 455, 461, 462, 463, 469, 470, 471]
      @void = 409
      @flat_top =
      @flat_l = 413
      @flat_r = 415
      @flat_bottom =
      @d_flat1 = 0
      @d_flat2 = 0
      @flat_lu = 419
      @flat_ru = 420
      @flat_lb = 427
      @flat_rb = 428
      @shades = {384 => 385, 417 => 464, 425 => 472, 433 => 480}
    when49# 体内
      @force_height = 0
      @floor = 384
      @dark = 433
      @covers =
      @walls_low = [-456, -457, -458]
      @walls_med =
      @walls_top =
      @line_l = 432
      @line_r = 434
      @corner_lu = 435
      @corner_ru = 436
      @corner_lb = 443
      @corner_rb = 444
      @d_corner1 = 0
      @d_corner2 = 0
      @allow_deep = true
      @depths =
      @void = 433
      @flat_top =
      @flat_l = 437
      @flat_r = 439
      @flat_bottom =
      @d_flat1 = 0
      @d_flat2 = 0
      @flat_lu = 451
      @flat_ru = 452
      @flat_lb = 459
      @flat_rb = 460
      @shades = {384 => 385, 441 => 464, 449 => 472, 457 => 480}
    end
end

#--------------------------------------------------------------------------
# ● 填涂墙壁
#   wall_height: 墙壁高度(负值为悬空式,可能会被图块锁定)
#--------------------------------------------------------------------------
def fill_wall(wall_height = 2)
    # 检查深渊地形
    if wall_height < 0
      if@allow_deep
      fill_depth
      return
      else# 图块没有深渊地形的情况下,按2格默认高度填涂墙壁
      wall_height = .max
      end
    end
    # 强制墙高生效
    wall_height = @force_heightif@force_height != 0
    # 勾勒地板边缘
    tile_data = Table.new(@width, @height)
    for i in0...@width
      for j in0...@height
      tile_data = get_border_tile(i, j)
      end
    end
    # 填涂地板边缘和F5层(背板遮挡填在F6层)
    for i in0...@width
      for j in0...@height
      unless@covers.include?(tile_data)
          if tile_data > 0
            @map.data = tile_data
          else
            @map.data = @floor
            @map.data = -tile_data
          end
      else
          @map.data = tile_dataif j > 0
          case tile_data
          when@covers
            if j < @height - 1and tile_data == @dark
            @map.data = @corner_lu
            else
            @map.data = @line_l
            end
          when@covers
            @map.data = @dark
          when@covers
            if j < @height - 1and tile_data == @dark
            @map.data = @corner_ru
            else
            @map.data = @line_r
            end
          end
      end
      end
    end
    # 墙高及纵向墙线的增长
    wall_data = {}
    for i in0...@width
      for j in0...@height
      index = @walls_low.index(@map.data)
      index = @walls_low.index(-@map.data)if index == nil
      if index != nil
          # 不是固定墙高3的情况下
          unless@force_height == 3
            (wall_height - 1).timesdo |n|
            wall_data[] = @walls_medif j > n
            end
          else
            wall_data[] = @walls_medif j > 0
            wall_data[] = @walls_rimif j > 1
          end
          wall_data[] = @walls_topif j >= wall_height
      elsif@map.data == @line_land@map.data == @dark
          (wall_height - 1).timesdo |n|
            wall_data[] = @line_lif j > n
          end
          # 交角处理
          if j >= wall_height
            if@map.data == @corner_ru
            wall_data[] = @d_corner2
            else
            wall_data[] = @corner_lb
            end
          end
      elsif@map.data == @line_rand@map.data == @dark
          (wall_height - 1).timesdo |n|
            wall_data[] = @line_rif j > n
          end
          # 交角处理
          if j >= wall_height
            if@map.data == @corner_lu
            wall_data[] = @d_corner1
            else
            wall_data[] = @corner_rb
            end
          end
      end
      end
    end
    # 填涂墙壁
    wall_data.eachdo |k, v|
      @map.data, k, 0] = v
    end
    # 末行处理
    for i in0...@width
      if@map.data == @floor
      @map.data = @covers
      end
    end
    # 阴影处理
    @width.timesdo |n|
      i = @width - n
      for j in0...@height
      # 地板的阴影
      if@map.data == @floor
          unless@map.data == @flooror
            @map.data == @flooror
            (@map.data == @floorand
            @map.data != -@walls_low)
            @map.data = @shades[@floor]
          end
      end
      # 墙壁的阴影
      if@map.data == @walls_top
          if@map.data == @line_r
            for k in0..wall_height
            if j + k < @height
                @map.data = @shades[@map.data]
                if@map.data == -@walls_low
                  @map.data = @shades[@map.data]
                end
            end
            end
          end
      end
      end
    end
end

#--------------------------------------------------------------------------
# ● 获得勾勒墙壁图块
#   x: 地图的 x 坐标
#   y: 地图的 y 坐标
#--------------------------------------------------------------------------   
def get_border_tile(x, y)
    s = @map.data
    return s if s != 0
    case neighbor_data(x, y)
    when0, 2, 128
      return@dark
    when1, 3, 129, 131
      return@covers
    when16, 24, 48, 56
      return@walls_low
    when4, 6
      return@corner_ru
    when64, 192
      return@corner_lu
    when8, 12, 14
      return@line_r
    when32, 96, 224
      return@line_l
    when80, 88, 112, 120, 208, 216, 240, 248
      return@walls_low
    when20, 22, 28, 30, 52, 54, 60, 62
      return@walls_low
    when65, 67, 97, 99, 193, 195, 225, 227
      return@covers
    when5, 7, 13, 15, 133, 135, 141, 143
      return@covers
    else
      return0
    end
end

#--------------------------------------------------------------------------
# ● 填涂深渊
#--------------------------------------------------------------------------
def fill_depth
    # 勾勒地板边缘
    tile_data = Table.new(@width, @height)
    for i in0...@width
      for j in0...@height
      tile_data = get_depth_tile(i, j)
      end
    end
    # 填涂地板边缘和F5层(高台遮挡填在F6层)
    for i in0...@width
      for j in0...@height
      unless@flat_top.include?(tile_data)
          @map.data = tile_data
      else
          @map.data = tile_data
          @map.data = @void
      end
      end
    end
    # 深渊的增长
    for i in0...@width
      for j in0...@height
      index = @flat_bottom.index(@map.data)
      if index != nil
          for k in0...@depths.length / 3
            breakif@map.data != @voidor j + k + 1 >= @height
            @map.data = @depths
          end
      end
      end
    end
end

#--------------------------------------------------------------------------
# ● 获得勾勒深渊图块
#   x: 地图的 x 坐标
#   y: 地图的 y 坐标
#--------------------------------------------------------------------------   
def get_depth_tile(x, y)
    s = @map.data
    return s if s != 0
    case neighbor_data(x, y)
    when0
      return@void
    when2
      return@flat_bottom
    when1, 3, 129, 131
      return@flat_bottom
    when128
      return@flat_bottom
    when8
      return@flat_top
    when16, 24, 48, 56
      return@flat_top
    when32
      return@flat_top
    when4, 6, 12, 14
      return@flat_l
    when64, 96, 192, 224
      return@flat_r
    when65, 67, 97, 99, 193, 195, 225, 227
      return@flat_rb
    when5, 7, 13, 15, 133, 135, 141, 143
      return@flat_lb
    when80, 88, 112, 120, 208, 216, 240, 248
      return@flat_ru
    when20, 22, 28, 30, 52, 54, 60, 62
      return@flat_lu
    else
      return0
    end
end

#--------------------------------------------------------------------------
# ● 获得图块的邻近值
#   x: 地图的 x 坐标
#   y: 地图的 y 坐标
#--------------------------------------------------------------------------   
def neighbor_data(x, y)
    neighbor =
    neighbor = @map.dataif x > 0and y > 0
    neighbor = @map.dataif x > 0
    neighbor = @map.dataif x > 0and y < @height - 1
    neighbor = @map.dataif y < @height - 1
    neighbor = @map.dataif x < @width - 1and y < @height - 1
    neighbor = @map.dataif x < @width - 1
    neighbor = @map.dataif x < @width - 1and y > 0
    neighbor = @map.dataif y > 0
    neighbor.collect!{|n| n > 0 ? 1 : 0}
    return neighbor.inject(0){|v, n| v = v * 2 + n}
end
end
# 以下为使用脚本,发布前请删除或注释
$auto_fill = Auto_MazeWalls.new(1)
$auto_fill.fill_wall
$auto_fill.save
exit


效果如下:
Before

After

After-2

范例工程:



             本帖来自P1论坛作者yang1zhi,因Project1站服务器在国外有时候访问缓慢不方便作者交流学习,经联系P1站长fux2同意署名转载一起分享游戏制作经验,共同为国内独立游戏作者共同创造良好交流环境,原文地址:https://rpg.blue/forum.php?mod=viewthread&tid=388732若有侵权,发帖作者可联系底部站长QQ在线咨询功能删除,谢谢。
页: [1]
查看完整版本: [猫儿的RMXP工具箱第七弹]自动绘制迷宫墙壁