XP オートタイルで迷路

オートタイルセットを使って、迷路を作るためのものです。

class Game_Map
attr_reader :map
end

def make_maze_map(type = 0, layer = 1, ox = 0, oy = 0, width = 20, height = 15)
layer -= 1
maze = Maze.new(width, height)
array = [1,0,1,0,0,0,1,0,1]
for y in oy .. oy + height - 1
for x in ox .. ox + width - 1
now_data = maze.data[x - ox][y - oy]
array[7] = now_data[0] ? 0 : 1
array[5] = now_data[1] ? 0 : 1
array[1] = now_data[2] ? 0 : 1
array[3] = now_data[3] ? 0 : 1
$game_map.map.data[x, y, layer] = auto_tile(type, array)
end
end
end

# 迷路データのクラス
class Maze
attr_reader :data # 座標毎に[上, 右, 下, 左]それぞれ通行可能かどうか
attr_reader :width # 迷路の幅
attr_reader :height # 迷路の高さ

# 縦横のますの数を指定して初期化するためのメソッド
def initialize(width, height)
@width = width
@height = height
make_maze(@width, @height)
end

# 迷路のデータだけを作り直すときはこのメソッドを呼び出す
def make_maze(width = @width, height = @height)
dig_i = 0
shift_x = [0, 1, 0, -1]
shift_y = [-1, 0, 1, 0]
dig = []
digable = []
for x in 0 .. width - 1
dig[x] = []
end
for y in 1 .. height - 2
dig[0][y] = [false, false, false, nil, false]
dig[width - 1][y] = [false, nil, false, false, false]
for x in 1 .. width - 2
dig[x][y] = [false, false, false, false, false]
end
end
for x in 1 .. width - 2
dig[x][0] = [nil, false, false, false, false]
dig[x][height - 1] = [false, false, nil, false, false]
end
dig[0][0] = [nil, false, false, nil, false]
dig[0][height - 1] = [false, false, nil, nil, false]
dig[width - 1][0] = [nil, nil, false, false, false]
dig[width - 1][height - 1] = [false, nil, nil, false, false]
x = width / 2
y = height / 2
loop do
dirable = []
dir = rand(4)
for i in dir .. dir + 3
j = i % 4
if dig[x][y][j] == nil
next
end
if dig[x + shift_x[j]][y + shift_y[j]][4] == false
dirable.push(j)
digable[dig_i] = [x + shift_x[j], y + shift_y[j]]
dig_i += 1
end
end
if dirable == []
loop do
if dig_i == 0
break
end
dig_i -= 1
x = digable[dig_i][0]
y = digable[dig_i][1]
if dig[x][y][4] == false
break
end
end
if dig_i == 0
break
end
dir = rand(4)
for i in dir .. dir + 3
j = i % 4
if dig[x][y][j] == nil
next
end
if dig[x + shift_x[j]][y + shift_y[j]][4] == true
dig[x][y][j] = true
dig[x][y][4] = true
dig[x + shift_x[j]][y + shift_y[j]][(j + 2) % 4] = true
break
end
end
next
end
dir = dirable[rand(dirable.size)]
dig[x][y][dir] = true
dig[x][y][4] = true
x += shift_x[dir]
y += shift_y[dir]
dig[x][y][(dir + 2) % 4] = true
dig[x][y][4] = true
end
dig[0][0][0] = true
dig[width - 1][height - 1][2] = true
@data = dig
end
end

# 壁・通路フラグ→オートタイルID変換用定配列
module TKS
Plus_Arrays = []
Plus_Arrays[ 0] = [8, 0, 4, 0, 0, 0, 1, 0, 2]
Plus_Arrays[ 1] = [0, 0, 2,16, 0, 0, 0, 0, 1]
Plus_Arrays[ 2] = [2, 0, 1, 0, 0, 0, 0,20, 0]
Plus_Arrays[ 3] = [0, 0, 1,17, 0, 0, 0,17, 0]
Plus_Arrays[ 4] = [1, 0, 0, 0, 0,24, 2, 0, 0]
Plus_Arrays[ 5] = [0, 0, 0,16, 0,16, 0, 0, 0]
Plus_Arrays[ 6] = [1, 0, 0, 0, 0,18, 0,18, 0]
Plus_Arrays[ 7] = [0, 0, 0,14, 0,14, 0,14, 0]
Plus_Arrays[ 8] = [0,28, 0, 0, 0, 0, 1, 0, 2]
Plus_Arrays[ 9] = [0,20, 0,20, 0, 0, 0, 0, 1]
Plus_Arrays[10] = [0,16, 0, 0, 0, 0, 0,17, 0]
Plus_Arrays[11] = [0,14, 0,14, 0, 0, 0,15, 0]
Plus_Arrays[12] = [0,19, 0, 0, 0,19, 1, 0, 0]
Plus_Arrays[13] = [0,14, 0,15, 0,15, 0, 0, 0]
Plus_Arrays[14] = [0,15, 0, 0, 0,15, 0,15, 0]
Plus_Arrays[15] = [1,11, 0,11, 0,12, 0,12, 0]
end

# 壁・通路フラグ→オートタイルID変換関数
def auto_tile(type = 0, array = [0, 0, 0, 0, 0, 0, 0, 0, 0])
number = (type + 1) * 48
pos = array[1] * 8 + array[3] + array[5] * 4 + array[7] * 2
for i in 0 .. 8
number += array[i] * TKS::Plus_Arrays[pos][i]
end
return number
end


そして、イベントコマンドのスクリプトで、

◆スクリプト:make_maze_map(type,layer,ox,oy,width,height)

を実行させれば、目的の位置に迷路ができます。

備考
type :オートタイルセットの番号(0〜6)
layer :レイヤー番号(1〜3)
ox :迷路の左上が来るX座標
oy :迷路の左上が来るY座標
width :迷路の幅
height :迷路の高さ