文章首发见博客:https://mwhls.top/4848.html。
无图/格式错误/后续更新请见首发页。
更多更新请到mwhls.top查看
欢迎留言提问或批评建议,私信不回。
汇总:Unity 记录
摘要:随机选择若干地形块,并与周围地形连续。
struct _DirectionsInfo{
public string[] direction;
public int ID;
public int[] up;
public int[] down;
public int[] left;
public int[] right;
public float[] up_prob;
public float[] down_prob;
public float[] left_prob;
public float[] right_prob;
}
/* ---------- surface direction ----------
* ┌---┬---┬---┐
* │ 7 │ 8 │ 9 │ I label these directions with numbers
* ├---┼---┼---┤ corresponding to the number pad positions for the block's solid area.
* │ 4 │ 5 │ 6 │ For example,
* ├---┼---┼---┤ 1 in left-down, only left-down tiles are solid, i.e. from left to down
* │ 1 │ 2 │ 3 │ 4 in left, the tiles in left are solid, i.e. from up-left to down-right
* └---┴---┴---┘ 7,9 are opposite which denotes the empty area
* 0. [empty, ] : no tile in this block
* 1. [left, down] : from left to down
* 2. [horizontal, ] : from left to right
* 3. [right, down] : from right to down
* 4. [vertical, left] : from up-left to down-right
* 5. [full, ] : all tiles are soild
* 6. [vertical, right] : from up-right to down-left
* 7. [left, up] : from left to up
* 8. [horizontal, ] : 8. == 2.
* 9. [right, up] : from right to up
*
* ---------- Additional directions ----------
* -1.[error, ] : relation error
*
* ---------- direction relation ----------
* If direction of this block is 'x', which block can connect it?
* ┌---┬---┬---┐ ┌---┬---┬---┐ ┌---┬---┬---┐
* │ │3 6│ │ │ │ │ │ │ │1 4│ │
* ├---┼---┼---┤ ├---┼---┼---┤ ├---┼---┼---┤
* │239│ 7 │459│ │ │ 2 │ │ │567│ 9 │127│
* ├---┼---┼---┤ ├---┼---┼---┤ ├---┼---┼---┤
* │ │ 5 │ │ │ │ │ │ │ │ 5 │ │
* └---┴---┴---┘ └---┴---┴---┘ └---┴---┴---┘
*
* ┌---┬---┬---┐ ┌---┬---┬---┐ ┌---┬---┬---┐
* │ │1 4│ │ │ │279│ │ │ │3 6│ │
* ├---┼---┼---┤ ├---┼---┼---┤ ├---┼---┼---┤
* │567│ 4 │036│ │6 7│ 5*│4 9│ │014│ 6 │459│
* ├---┼---┼---┤ ├---┼---┼---┤ ├---┼---┼---┤
* │ │4 9│ │ │ │ │ │ │ │6 7│ │
* └---┴---┴---┘ └---┴---┴---┘ └---┴---┴---┘
*
* ┌---┬---┬---┐ ┌---┬---┬---┐ ┌---┬---┬---┐
* │ │ 0 │ │ │ │ 0 │ │ │ │ 0 │ │
* ├---┼---┼---┤ ├---┼---┼---┤ ├---┼---┼---┤
* │239│ 1 │036│ │239│ 2 │127│ │014│ 3 │127│
* ├---┼---┼---┤ ├---┼---┼---┤ ├---┼---┼---┤
* │ │4 9│ │ │ │ 5 │ │ │ │6 7│ │
* └---┴---┴---┘ └---┴---┴---┘ └---┴---┴---┘
*
* ┌---┬---┬---┐
* │ │ │ │ x*: around with x
* ├---┼---┼---┤
* │1 4│ 0*│3 6│
* ├---┼---┼---┤
* │ │123│ │
* └---┴---┴---┘
*
*
*/
class _DirectionsConfig{
_DirectionsInfo[] directions_info = new _DirectionsInfo[] {
new _DirectionsInfo{ ID = 0, direction = new string[] {"empty", ""},
up = new int[]{0}, up_prob = new float[]{1},
down = new int[]{0, 1, 2, 3}, down_prob = new float[]{1, 1, 1, 1},
left = new int[]{0, 1, 4}, left_prob = new float[]{1, 1, 1},
right = new int[]{0, 3, 6}, right_prob = new float[]{1, 1, 1}
},
new _DirectionsInfo{ ID = 1, direction = new string[] {"left", "down"},
up = new int[]{0}, up_prob = new float[]{1},
down = new int[]{4, 9}, down_prob = new float[]{1, 1},
left = new int[]{2, 3, 9}, left_prob = new float[]{1, 1, 1},
right = new int[]{0, 3, 6}, right_prob = new float[]{1, 1, 1}
},
new _DirectionsInfo{ ID = 2, direction = new string[] {"horizontal", ""},
up = new int[]{0}, up_prob = new float[]{1},
down = new int[]{5}, down_prob = new float[]{1},
left = new int[]{2, 3, 9}, left_prob = new float[]{1, 1, 1},
right = new int[]{1, 2, 7}, right_prob = new float[]{1, 1, 1}
},
new _DirectionsInfo{ ID = 3, direction = new string[] {"right", "down"},
up = new int[]{0}, up_prob = new float[]{1},
down = new int[]{6, 7}, down_prob = new float[]{1, 1},
left = new int[]{0, 1, 4}, left_prob = new float[]{1, 1, 1},
right = new int[]{1, 2, 7}, right_prob = new float[]{1, 1, 1}
},
new _DirectionsInfo{ ID = 4, direction = new string[] {"vertical", "left"},
up = new int[]{1, 4}, up_prob = new float[]{1, 1},
down = new int[]{4, 9}, down_prob = new float[]{1, 1},
left = new int[]{5, 6, 7}, left_prob = new float[]{1, 1, 1},
right = new int[]{0, 3, 6}, right_prob = new float[]{1, 1, 1}
},
new _DirectionsInfo{ ID = 5, direction = new string[] {"full", ""},
up = new int[]{2, 5, 7, 9}, up_prob = new float[]{1, 1, 1, 1},
down = new int[]{5}, down_prob = new float[]{1},
left = new int[]{5, 6, 7}, left_prob = new float[]{1, 1, 1},
right = new int[]{4, 5, 9}, right_prob = new float[]{1, 1, 1}
},
new _DirectionsInfo{ ID = 6, direction = new string[] {"vertical", "right"},
up = new int[]{3, 6}, up_prob = new float[]{1, 1},
down = new int[]{6, 7}, down_prob = new float[]{1, 1},
left = new int[]{0, 1, 4}, left_prob = new float[]{1, 1, 1},
right = new int[]{4, 5, 9}, right_prob = new float[]{1, 1, 1}
},
new _DirectionsInfo{ ID = 7, direction = new string[] {"left", "up"},
up = new int[]{3, 6}, up_prob = new float[]{1, 1},
down = new int[]{5}, down_prob = new float[]{1},
left = new int[]{2, 3, 9}, left_prob = new float[]{1, 1, 1},
right = new int[]{4, 5, 9}, right_prob = new float[]{1, 1, 1}
},
new _DirectionsInfo{ ID = 2, direction = new string[] {"horizontal", ""},
up = new int[]{0}, up_prob = new float[]{1},
down = new int[]{5}, down_prob = new float[]{1},
left = new int[]{2, 3, 9}, left_prob = new float[]{1, 1, 1},
right = new int[]{1, 2, 7}, right_prob = new float[]{1, 1, 1}
}, // ID8 == ID2
new _DirectionsInfo{ ID = 9, direction = new string[] {"right", "up"},
up = new int[]{1, 4}, up_prob = new float[]{1, 1},
down = new int[]{5}, down_prob = new float[]{1},
left = new int[]{5, 6, 7}, left_prob = new float[]{1, 1, 1},
right = new int[]{1, 2, 7}, right_prob = new float[]{1, 1, 1}
}
};
public string[] select_direction(_BlockAround block_around) {
int[] available_directions = _get_available_direction(block_around);
if (available_directions.Length == 0)
return new string[] {"error", ""};
float[] directions_prob = new float[available_directions.Length];
for(int i = 0; i < available_directions.Length; i++){
directions_prob[i] = 1f;
}
int direction_index = _random_by_prob(directions_prob);
int direction_ID = available_directions[direction_index];
string [] direction = directions_info[direction_ID].direction;
return direction;
}
int _random_by_prob(float[] probs){
float sum = probs.Sum();
float target = Random.Range(0f, sum);
for(int i = 0; i < probs.Length; i++){
target -= probs[i];
if(target <= 0){
return i;
}
}
return probs.Length - 1;
}
int[] _get_available_direction(_BlockAround block_around){
// int[] around_directions = _get_around_directions(block_around);
int[] availables = new int[directions_info.Length];
for(int i = 0; i < directions_info.Length; i++){
availables[i] = directions_info[i].ID;
}
if(block_around.up.isExist){
int direction_ID = _mapping_direction_to_index(block_around.up.direction);
int[] avail = directions_info[direction_ID].down;
availables = availables.Intersect(avail).ToArray();
}
if(block_around.down.isExist){
int direction_ID = _mapping_direction_to_index(block_around.down.direction);
int[] avail = directions_info[direction_ID].up;
availables = availables.Intersect(avail).ToArray();
}
if(block_around.left.isExist){
int direction_ID = _mapping_direction_to_index(block_around.left.direction);
int[] avail = directions_info[direction_ID].right;
availables = availables.Intersect(avail).ToArray();
}
if(block_around.right.isExist){
int direction_ID = _mapping_direction_to_index(block_around.right.direction);
int[] avail = directions_info[direction_ID].left;
availables = availables.Intersect(avail).ToArray();
}
return availables;
}
int _mapping_direction_to_index(string[] direction){
for(int i = 0; i < directions_info.GetLength(0); i++)
if(direction[0] == directions_info[i].direction[0] && direction[1] == directions_info[i].direction[1])
return i;
return -1;
}
}