加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有帐号?注册会员
x
本帖最后由 guoxiaomi 于 2020-4-7 18:33 编辑
XP的自动元件总共有48个样式,在地图编辑器里绘制时会根据其周围8格有没有跟它一样的自动元件改变自己的样式,但是如果要在游戏里生成随机的地图,自动元件的ID就需要自己算了。
论坛上我找了找好像没有?不过我找了网上的一些分析文章:
1. 浅谈RPG Maker XP自动地图元件的绘制原理_xp_古的博客-CSDN博客
2. 浅析RMXP自动元件绘制原理_网络_sky的游戏开发博客-CSDN博客
3. Auto-tiling-algorithm
然后写了个方法,可以以二维数组输入地图上某个自动元件的占据情况,输出一个同样大小的二维数组,其元素是此处自动元件的ID
基本上是苦力活,原理上面的方法都讲清楚了
# encoding: utf-8 # RMXP Autotiles 算法 # 首先用以下标记来标注一个AutoTile # + - + - + - + # | 1 | 6 | 2 | # | 5 | | 7 | # | 4 | 8 | 3 | # + - + - + - + # 1234 构成 0-15 的数 c = 4321 # 5678 构成 0-15 的数 b = 8765 def get_autotile(b, c) case b when 0b1111 15 - c when 0b1110 19 - (c / 2) % 4 when 0b1101 23 - (c / 4) % 4 when 0b1011 27 - c / 8 - (c * 2) % 4 when 0b0111 31 - c % 4 when 0b1010 then 32 when 0b0101 then 33 when 0b1100 35 - (c / 4) % 2 when 0b1001 37 - c / 8 when 0b0011 39 - c % 2 when 0b0110 41 - (c / 2) % 2 when 0b1000 then 42 when 0b0100 then 43 when 0b0010 then 44 when 0b0001 then 45 when 0b0000 then 46 end end # t 是一个二维的数组 def fill_table(t) width = t[0].size height = t.size tt = [] tt << [1] * (width + 2) for row in 1..height tt << [1] + t[row - 1] + [1] end tt << [1] * (width + 2) # 默认是 -1 id = Array.new(height) { [-1] * width } for x in 1..width for y in 1..height if tt[y][x] == 1 b = tt[y + 1][x] * 8 + tt[y][x + 1] * 4 + tt[y - 1][x] * 2 + tt[y][x - 1] c = tt[y + 1][x - 1] * 8 + tt[y + 1][x + 1] * 4 + tt[y - 1][x + 1] * 2 + tt[y - 1][x - 1] a = get_autotile(b, c) id[y - 1][x - 1] = a end end end return id end
# encoding: utf-8
# RMXP Autotiles 算法
# 首先用以下标记来标注一个AutoTile
# + - + - + - +
# | 1 | 6 | 2 |
# | 5 | | 7 |
# | 4 | 8 | 3 |
# + - + - + - +
# 1234 构成 0-15 的数 c = 4321
# 5678 构成 0-15 的数 b = 8765
def get_autotile(b, c)
case b
when 0b1111
15 - c
when 0b1110
19 - (c / 2) % 4
when 0b1101
23 - (c / 4) % 4
when 0b1011
27 - c / 8 - (c * 2) % 4
when 0b0111
31 - c % 4
when 0b1010 then 32
when 0b0101 then 33
when 0b1100
35 - (c / 4) % 2
when 0b1001
37 - c / 8
when 0b0011
39 - c % 2
when 0b0110
41 - (c / 2) % 2
when 0b1000 then 42
when 0b0100 then 43
when 0b0010 then 44
when 0b0001 then 45
when 0b0000 then 46
end
end
# t 是一个二维的数组
def fill_table(t)
width = t[0].size
height = t.size
tt = []
tt << [1] * (width + 2)
for row in 1..height
tt << [1] + t[row - 1] + [1]
end
tt << [1] * (width + 2)
# 默认是 -1
id = Array.new(height) { [-1] * width }
for x in 1..width
for y in 1..height
if tt[y][x] == 1
b = tt[y + 1][x] * 8 + tt[y][x + 1] * 4 + tt[y - 1][x] * 2 + tt[y][x - 1]
c = tt[y + 1][x - 1] * 8 + tt[y + 1][x + 1] * 4 + tt[y - 1][x + 1] * 2 + tt[y - 1][x - 1]
a = get_autotile(b, c)
id[y - 1][x - 1] = a
end
end
end
return id
end
用这个脚本在初始的地图里测试:
t = Array.new(15) { Array.new(20) { rand < 0.5 ? 1 : 0 } } id = fill_table(t) for i in 0...20 for j in 0...15 if id[j][i] > 0 $game_map.data[i,j,0] = 48 + id[j][i] else $game_map.data[i,j,0] = 384 end end end
t = Array.new(15) {
Array.new(20) { rand < 0.5 ? 1 : 0 }
}
id = fill_table(t)
for i in 0...20
for j in 0...15
if id[j][i] > 0
$game_map.data[i,j,0] = 48 + id[j][i]
else $game_map.data[i,j,0] = 384
end
end
end
效果如图:
|