Project1
标题: XP自动元件生成算法 [打印本页]
作者: guoxiaomi 时间: 2020-4-7 18:22
标题: XP自动元件生成算法
本帖最后由 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
效果如图:
作者: 灯笼菜刀王 时间: 2020-4-7 19:26
本帖最后由 灯笼菜刀王 于 2020-4-7 19:34 编辑
这文章早点出来就好了, 正在做一个建设系统, 卡在自动元件上好久, 无法处理自动元件的变形, 后来干脆不用自动元件了... 把树全部割成图块使用, 也因此决定用铺事件调用图块的方式进行建造, 毕竟可以利用行走图做动态图块和循环动画~
作者: RyanBern 时间: 2020-4-7 20:36
醋瞎。怕是自动生成地图的时候才用得到。
作者: fux2 时间: 2020-4-7 21:11
这直接就强惊天,不过之前好像有见过一样的东西,忘了在哪里了
作者: 89444640 时间: 2020-4-7 21:12
本帖最后由 89444640 于 2020-4-7 21:20 编辑
所以这个能做随机寻宝地图了?除了可能场景会限定比较单调。只有自动原件和底下图块,而且要可通行,
作者: Im剑侠客 时间: 2020-4-8 00:46
自动元件一直都觉得是一个谜团,这下好了~云开月明。
作者: SailCat 时间: 2020-4-8 00:55
我当年发迷宫自动描边的时候就发过算法上来的啊……
https://rpg.blue/thread-388732-1-1.html
欢迎光临 Project1 (https://rpg.blue/) |
Powered by Discuz! X3.1 |