1- 分析
通过对照观察,我们会发现,在这个自动拼接元素上,小元素可以分为以下几种:
A- 向内转角(也就是0,1,6,7,以及12, 17, 42, 47,这里只取一组即可 )(FIXED:这里选择12,17,42,47这组,因为部分特殊元素这四个才是真实的向内转角)
B- 向外转角(4,5,10,11)
C- 上下连接(24,29,30,35)
D- 左右连接(14,15,44,45)
E- 填充物(26,27,32,33)
通过观察组合图块,我们会发现下面的几条规律
A- 斜方向的同类块对目标块的影响当且仅当斜方向相邻的两个垂直方向上都有同类块的时候才会出现。也就是将目标块的对应小图块变成填充物。
B- 当两个相邻的垂直方向上都有同类块,且他们之间的斜方向上没有同类块的时候,目标快对应的小图块变成向外转角
C- 当某个垂直方向上有同类块,且相邻的一个垂直方向上没有同类块,无论相邻的斜方向上有没有同类块,目标块对应的小图块变成连接(向上下或者向左右连接)
D- 当某个垂直方向上没有同类块,且相邻的垂直方向上也没有同类块,无论相邻的斜方向上有没有同类块,目标块对应的小图块变成向内转角
2- 生成算法(C#代码)
1 // 填充物 26 27 32 33
2 // 向外转角 4 5 10 11
3 // 上下连接 24 29 30 35
4 // 左右连接 14 15 44 45
5 // 向内转角 12 17 42 47
6
7 // 各方向比特 1 2 4 8 16 32 64 128
8
9 // 4 个小图块对应的索引
10 // 0 1 小图块在大图块里
11 // 2 3 按照这种顺序排列
12 byte[] mTile = new byte[4];
13 // 调色板数组,每个元素是一个包含4个索引的DWORD
14 UInt32[] mAutoTilePal = new UInt32[256];
15
16 for (uint nIndex = 0; nIndex < 256; nIndex++)
17 {
18 // 初始化成向内转角
19 mTile[0] = 12;
20 mTile[1] = 17;
21 mTile[2] = 42;
22 mTile[3] = 47;
23 // 如果上方有同类块
24 if ((nIndex & 2) > 0)
25 {
26 // 如果左方有同类块
27 if ((nIndex & 128) > 0)
28 {
29 // 如果左上方有同类块
30 if ((nIndex & 1) > 0)
31 {
32 // 目标块左上为填充物
33 mTile[0] = 26;
34 }
35 else
36 {
37 // 目标块左上为向外转角
38 mTile[0] = 4;
39 }
40 }
41 else
42 {
43 // 目标块左上为向上连接
44 mTile[0] = 24;
45 }
46
47 // 如果右方有同类块
48 if ((nIndex & 8) > 0)
49 {
50 // 如果右上方有同类块
51 if ((nIndex & 4) > 0)
52 {
53 // 目标块右上为填充物
54 mTile[1] = 27;
55 }
56 else
57 {
58 // 目标块右上为向外转角
59 mTile[1] = 5;
60 }
61 }
62 else
63 {
64 // 目标块右上为向上连接
65 mTile[1] = 29;
66 }
67 }
68 else
69 {
70 // 如果左方有同类块
71 if ((nIndex & 128) > 0)
72 {
73 // 目标左上为向左连接
74 mTile[0] = 14;
75 }
76 // 如果右方有同类块
77 if ((nIndex & 8) > 0)
78 {
79 // 目标右上为向右连接
80 mTile[1] = 15;
81 }
82 }
83
84 // 如果下方有同类块
85 if ((nIndex & 32) > 0)
86 {
87 // 如果左方有同类块
88 if ((nIndex & 128) > 0)
89 {
90 // 如果左下方有同类块
91 if ((nIndex & 64) > 0)
92 {
93 // 目标块左下为填充物
94 mTile[2] = 32;
95 }
96 else
97 {
98 // 目标块左下为向外转角
99 mTile[2] = 10;
100 }
101 }
102 else
103 {
104 // 目标块左下为向下连接
105 mTile[2] = 30;
106 }
107
108 // 如果右方有同类块
109 if ((nIndex & 8) > 0)
110 {
111 // 如果右下方有同类块
112 if ((nIndex & 16) > 0)
113 {
114 // 目标块右下为填充物
115 mTile[3] = 33;
116 }
117 else
118 {
119 // 目标块右下为向外转角
120 mTile[3] = 11;
121 }
122 }
123 else
124 {
125 // 目标块右下为向下连接
126 mTile[3] = 35;
127 }
128 }
129 else
130 {
131 // 如果左方有同类块
132 if ((nIndex & 128) > 0)
133 {
134 // 目标块左下为向左连接
135 mTile[2] = 44;
136 }
137 // 如果右方有同类块
138 if ((nIndex & 8) > 0)
139 {
140 // 目标块右下为向右连接
141 mTile[3] = 45;
142 }
143 }
144
145 mAutoTilePal[nIndex] = (UInt32)mTile[0];
146 mAutoTilePal[nIndex] |= ((UInt32)mTile[1]) << 8;
147 mAutoTilePal[nIndex] |= ((UInt32)mTile[2]) << 16;
148 mAutoTilePal[nIndex] |= ((UInt32)mTile[3]) << 24;
149 }