рдкреНрд░рдХреНрд░рд┐рдпрд╛рддреНрдордХ рдкреИрдЯрд░реНрди рдЬреЛ рдЯрд╛рдЗрд▓ рдХрд╛рд░реНрдб рдХреЗ рд╕рд╛рде рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВ

рдкреНрд░рдХреНрд░рд┐рдпрд╛рддреНрдордХ рдкреАрдврд╝реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдЦреЗрд▓реЛрдВ рдХреА рдкрд░рд┐рд╡рд░реНрддрдирд╢реАрд▓рддрд╛ рдХреЛ рдмрдврд╝рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЬрд╛рдиреА-рдорд╛рдиреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ Minecraft , Enter the Gungeon, рдФрд░ Descenders рд╢рд╛рдорд┐рд▓ рд╣реИрдВред рдЗрд╕ рдкреЛрд╕реНрдЯ рдореЗрдВ, рдореИрдВ рдЙрди рдХреБрдЫ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ рдХрд░реВрдБрдЧрд╛ , рдЬрд┐рдирдХрд╛ рдЙрдкрдпреЛрдЧ рддрд┐рд▓рдордк рдкреНрд░рдгрд╛рд▓реА рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╕рдордп рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬреЛ рдХрд┐ рдпреВрдирд┐рдЯреА 2017.2 рдореЗрдВ 2 рдбреА рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд░реВрдк рдореЗрдВ рдФрд░ рд░реВрд▓рдЯрд╛рдЗрд▓ рдХреЗ рд╕рд╛рде рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛ ред

рдирдХреНрд╢реЛрдВ рдХреЗ рдкреНрд░рдХреНрд░рд┐рдпрд╛рддреНрдордХ рдирд┐рд░реНрдорд╛рдг рдХреЗ рд╕рд╛рде, рдкреНрд░рддреНрдпреЗрдХ рдкрд╛рд╕рд┐рдВрдЧ рдЧреЗрдо рдЕрджреНрд╡рд┐рддреАрдп рд╣реЛрдЧрд╛ред рдЖрдк рдЦреЗрд▓ рдХреЗ рдЕрд╕реЗрдВрдмрд▓реА рдХреЗ рдмрд╛рдж рднреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рдЧрддрд┐рд╢реАрд▓ рд░реВрдк рд╕реЗ рдмрджрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рднрд┐рдиреНрди рдЗрдирдкреБрдЯ рдбреЗрдЯрд╛, рдЬреИрд╕реЗ рд╕рдордп рдпрд╛ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЗ рд╡рд░реНрддрдорд╛рди рд╕реНрддрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдпрд╣ рдкреЛрд╕реНрдЯ рдХрд┐рд╕ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИ?


рд╣рдо рдкреНрд░рдХреНрд░рд┐рдпрд╛рддреНрдордХ рджреБрдирд┐рдпрд╛ рдмрдирд╛рдиреЗ рдХреЗ рд╕рдмрд╕реЗ рд╕рд╛рдорд╛рдиреНрдп рддрд░реАрдХреЛрдВ рдореЗрдВ рд╕реЗ рдХреБрдЫ рдкрд░ рдЧреМрд░ рдХрд░реЗрдВрдЧреЗ, рд╕рд╛рде рд╣реА рдореИрдВрдиреЗ рдХреБрдЫ рдмрджрд▓рд╛рд╡ рднреА рдХрд┐рдП рд╣реИрдВред рдпрд╣рд╛рдБ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИ рдХрд┐ рдЖрдк рд▓реЗрдЦ рдкрдврд╝рдиреЗ рдХреЗ рдмрд╛рдж рдХреНрдпрд╛ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рддреАрди рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдПрдХ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдорд╛рдирдЪрд┐рддреНрд░ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рддрд┐рд▓рдореИрдк рдФрд░ рдирд┐рдпрдо :


рдХрд┐рд╕реА рднреА рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдПрдХ рдорд╛рдирдЪрд┐рддреНрд░ рдмрдирд╛рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ, рд╣рдореЗрдВ рд╕рднреА рдирдП рдбреЗрдЯрд╛ рд╡рд╛рд▓реЗ рдПрдХ int рд╕рд░рдгреА рдорд┐рд▓рддреЗ рд╣реИрдВред рдЖрдк рдЗрд╕ рдбреЗрдЯрд╛ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ рдЗрд╕реЗ рдЯрд╛рдЗрд▓ рдорд╛рдирдЪрд┐рддреНрд░ рдкрд░ рдкреНрд░рд╕реНрддреБрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рдЖрдЧреЗ рдкрдврд╝рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЬрд╛рдирдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛:

  1. рд╣рдо рднреЗрдж рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдПрдХ рдЯрд╛рдЗрд▓ рдХреНрдпрд╛ рд╣реИ рдФрд░ рдмрд╛рдЗрдирд░реА рдорд╛рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░ рд░рд╣рд╛ рд╣реИред 1 рдПрдХ рдЯрд╛рдЗрд▓ рд╣реИ, 0 рдЗрд╕рдХреА рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐ рд╣реИред
  2. рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдЕрдВрдд рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рд▓реМрдЯрд╛рдП рдЧрдП рджреЛ-рдЖрдпрд╛рдореА рдкреВрд░реНрдгрд╛рдВрдХ рд╕рд░рдгреА рдореЗрдВ рд╕рднреА рдХрд╛рд░реНрдбреЛрдВ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░реЗрдВрдЧреЗ (рдЙрд╕ рд╕реНрдерд╛рди рдХреЛ рдЫреЛрдбрд╝рдХрд░ рдЬрд╣рд╛рдВ рдкреНрд░рддрд┐рдкрд╛рджрди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ)ред
  3. рдореИрдВ рдкреНрд░рддреНрдпреЗрдХ рдорд╛рдирдЪрд┐рддреНрд░ рдХреА рдКрдВрдЪрд╛рдИ рдФрд░ рдЪреМрдбрд╝рд╛рдИ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЧреЗрдЯрдЕрдкрдмрд╛рдЙрдВрдб () рд╕рд░рдгреА рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВрдЧрд╛ , рддрд╛рдХрд┐ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХрдо рдЪрд░ рдорд┐рд▓реЗрдВ рдФрд░ рдХреЛрдб рдХреНрд▓реАрдирд░ рд╣реЛред
  4. рдореИрдВ рдЕрдХреНрд╕рд░ Mathf.FloorToInt () рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ рдХреНрдпреЛрдВрдХрд┐ рдЯрд┐рд▓реЗрдореИрдк рд╕рдордиреНрд╡рдп рдкреНрд░рдгрд╛рд▓реА рдиреАрдЪреЗ рдмрд╛рдИрдВ рдУрд░ рд╢реБрд░реВ рд╣реЛрддреА рд╣реИ рдФрд░ Mathf.FloorToInt () рдЖрдкрдХреЛ рдкреВрд░реНрдгрд╛рдВрдХ рдореЗрдВ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЛ рдЧреЛрд▓ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
  5. рдЗрд╕ рдкреЛрд╕реНрдЯ рдХреЗ рд╕рднреА рдХреЛрдб C # рдореЗрдВ рд▓рд┐рдЦреЗ рдЧрдП рд╣реИрдВред

рдЕрд░реНрд░реЗ рдкреАрдврд╝реА


GenerateArray рджрд┐рдП рдЧрдП рдЖрдХрд╛рд░ рдХрд╛ рдПрдХ рдирдпрд╛ int рд╕рд░рдгреА рдмрдирд╛рддрд╛ рд╣реИред рд╣рдо рдпрд╣ рднреА рдЗрдВрдЧрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рд╕рд░рдгреА рдХреЛ рднрд░рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдпрд╛ рдЦрд╛рд▓реА (1 рдпрд╛ 0) рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣рд╛рдБ рдХреЛрдб рд╣реИ:

 public static int[,] GenerateArray(int width, int height, bool empty) { int[,] map = new int[width, height]; for (int x = 0; x < map.GetUpperBound(0); x++) { for (int y = 0; y < map.GetUpperBound(1); y++) { if (empty) { map[x, y] = 0; } else { map[x, y] = 1; } } } return map; } 

рдирдХреНрд╢рд╛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдирд╛


рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдЯрд╛рдЗрд▓ рдХреЗ рдирдХреНрд╢реЗ рдкрд░ рдорд╛рдирдЪрд┐рддреНрд░ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣рдо рдирдХреНрд╢реЗ рдХреА рдЪреМрдбрд╝рд╛рдИ рдФрд░ рдКрдВрдЪрд╛рдИ рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рд▓реВрдк рдХрд░рддреЗ рд╣реИрдВ, рдХреЗрд╡рд▓ рдЯрд╛рдЗрд▓реЗрдВ рд▓рдЧрд╛рддреЗ рд╣реИрдВ рдЬрдм рдкрд░реАрдХреНрд╖рдг рдмрд┐рдВрджреБ рдкрд░ рд╕рд░рдгреА рдХрд╛ рдорд╛рди 1 рд╣реЛрддрд╛ рд╣реИред

 public static void RenderMap(int[,] map, Tilemap tilemap, TileBase tile) { //Clear the map (ensures we dont overlap) tilemap.ClearAllTiles(); //Loop through the width of the map for (int x = 0; x < map.GetUpperBound(0) ; x++) { //Loop through the height of the map for (int y = 0; y < map.GetUpperBound(1); y++) { // 1 = tile, 0 = no tile if (map[x, y] == 1) { tilemap.SetTile(new Vector3Int(x, y, 0), tile); } } } } 

рдирдХреНрд╢рд╛ рдЕрджреНрдпрддрди


рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рдХреЗрд╡рд▓ рдореИрдк рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рди рдХрд┐ рд░реА-рд░реЗрдВрдбрд░рд┐рдВрдЧ рдХреЗ рд▓рд┐рдПред рдЗрд╕рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдЯрд╛рдЗрд▓ рдФрд░ рдЙрд╕рдХреЗ рдЯрд╛рдЗрд▓ рдбреЗрдЯрд╛ рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдП рдмрд┐рдирд╛ рдХрдо рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

 public static void UpdateMap(int[,] map, Tilemap tilemap) //Takes in our map and tilemap, setting null tiles where needed { for (int x = 0; x < map.GetUpperBound(0); x++) { for (int y = 0; y < map.GetUpperBound(1); y++) { //We are only going to update the map, rather than rendering again //This is because it uses less resources to update tiles to null //As opposed to re-drawing every single tile (and collision data) if (map[x, y] == 0) { tilemap.SetTile(new Vector3Int(x, y, 0), null); } } } } 

рд╢реЛрд░рдЧреБрд▓


рдкреЗрд░реНрд▓рд┐рди рд╢реЛрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╡рд┐рднрд┐рдиреНрди рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рдЗрд╕реЗ рдЕрдкрдиреЗ рдорд╛рдирдЪрд┐рддреНрд░ рдХреА рд╢реАрд░реНрд╖ рдкрд░рдд рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдмрд╕ рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ x рдФрд░ рдмреАрдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рдирдпрд╛ рдмрд┐рдВрджреБ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВред

рд╕рд░рд▓ рдЙрдкрд╛рдп


рдпрд╣ рдкреАрдврд╝реА рдкрджреНрдзрддрд┐ рд╕реНрддрд░реЛрдВ рдХреА рдкреАрдврд╝реА рдореЗрдВ рдкреЗрд░реНрд▓рд┐рди рд╢реЛрд░ рдХреА рдкреНрд░рд╛рдкреНрддрд┐ рдХреЗ рд╕рд░рд▓рддрдо рд░реВрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреА рд╣реИред рд╣рдо Perlin рдХреЗ рд╢реЛрд░ рдХреЗ рд▓рд┐рдП рдПрдХрддрд╛ рдлрд╝рдВрдХреНрд╢рди рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рд╣рдо рд╕реНрд╡рдпрдВ рдХреЛрдб рди рд▓рд┐рдЦреЗрдВред рд╣рдо Mathf.FloorToInt () рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЯрд╛рдЗрд▓ рдХреЗ рдирдХреНрд╢реЗ рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ рдкреВрд░реНрдгрд╛рдВрдХ рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред

 public static int[,] PerlinNoise(int[,] map, float seed) { int newPoint; //Used to reduced the position of the Perlin point float reduction = 0.5f; //Create the Perlin for (int x = 0; x < map.GetUpperBound(0); x++) { newPoint = Mathf.FloorToInt((Mathf.PerlinNoise(x, seed) - reduction) * map.GetUpperBound(1)); //Make sure the noise starts near the halfway point of the height newPoint += (map.GetUpperBound(1) / 2); for (int y = newPoint; y >= 0; y--) { map[x, y] = 1; } } return map; } 

рдЯрд╛рдЗрд▓ рдХреЗ рдирдХреНрд╢реЗ рдХреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рдпрд╣ рдХреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИ:


рдЪреМрд░рд╕рд╛рдИ


рдЖрдк рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рднреА рд▓реЗ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕реЗ рдЪрд┐рдХрдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдкреЗрд░рд▓рд┐рди рдХреА рдКрдВрдЪрд╛рдЗрдпреЛрдВ рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдВрддрд░рд╛рд▓ рд╕реЗрдЯ рдХрд░реЗрдВ, рдФрд░ рдлрд┐рд░ рдЗрди рдмрд┐рдВрджреБрдУрдВ рдХреЗ рдмреАрдЪ рдЪреМрд░рд╕рд╛рдИ рдХрд░реЗрдВред рдпрд╣ рдлрд╝рдВрдХреНрд╢рди рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реЛ рдЬрд╛рдПрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдЕрдВрддрд░рд╛рд▓ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдкреВрд░реНрдгрд╛рдВрдХ рдорд╛рдиреЛрдВ рдХреА рд╕реВрдЪреА рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред

 public static int[,] PerlinNoiseSmooth(int[,] map, float seed, int interval) { //Smooth the noise and store it in the int array if (interval > 1) { int newPoint, points; //Used to reduced the position of the Perlin point float reduction = 0.5f; //Used in the smoothing process Vector2Int currentPos, lastPos; //The corresponding points of the smoothing. One list for x and one for y List<int> noiseX = new List<int>(); List<int> noiseY = new List<int>(); //Generate the noise for (int x = 0; x < map.GetUpperBound(0); x += interval) { newPoint = Mathf.FloorToInt((Mathf.PerlinNoise(x, (seed * reduction))) * map.GetUpperBound(1)); noiseY.Add(newPoint); noiseX.Add(x); } points = noiseY.Count; 

рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдкрд╣рд▓реЗ рднрд╛рдЧ рдореЗрдВ, рд╣рдо рдкрд╣рд▓реЗ рдЬрд╛рдВрдЪрддреЗ рд╣реИрдВ рдХрд┐ рдЕрдВрддрд░рд╛рд▓ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рд╣реИ рдпрд╛ рдирд╣реАрдВред рдпрджрд┐ рдРрд╕рд╛ рд╣реИ, рддреЛ рд╢реЛрд░ рдЙрддреНрдкрдиреНрди рдХрд░реЗрдВред рдкреАрдврд╝реА рдЕрдВрддрд░рд╛рд▓ рдкрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддрд╛рдХрд┐ рдЪреМрд░рд╕рд╛рдИ рдХреЛ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХреЗред рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЕрдЧрд▓рд╛ рднрд╛рдЧ рдмрд┐рдВрджреБрдУрдВ рдХреЛ рд╕реБрдЪрд╛рд░реВ рдХрд░рдирд╛ рд╣реИред

 //Start at 1 so we have a previous position already for (int i = 1; i < points; i++) { //Get the current position currentPos = new Vector2Int(noiseX[i], noiseY[i]); //Also get the last position lastPos = new Vector2Int(noiseX[i - 1], noiseY[i - 1]); //Find the difference between the two Vector2 diff = currentPos - lastPos; //Set up what the height change value will be float heightChange = diff.y / interval; //Determine the current height float currHeight = lastPos.y; //Work our way through from the last x to the current x for (int x = lastPos.x; x < currentPos.x; x++) { for (int y = Mathf.FloorToInt(currHeight); y > 0; y--) { map[x, y] = 1; } currHeight += heightChange; } } } 

рдЪреМрд░рд╕рд╛рдИ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рддреА рд╣реИ:

  1. рд╣рдореЗрдВ рд╡рд░реНрддрдорд╛рди рдФрд░ рдЕрдВрддрд┐рдо рд╕реНрдерд┐рддрд┐ рдорд┐рд▓рддреА рд╣реИ
  2. рд╣рдо рджреЛ рдмрд┐рдВрджреБрдУрдВ рдХреЗ рдмреАрдЪ рдЕрдВрддрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ, рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЬрд╛рдирдХрд╛рд░реА рдЬреЛ рд╣рдореЗрдВ рдЪрд╛рд╣рд┐рдП рд╡рд╣ рд╣реИ y рдЕрдХреНрд╖ рдХреЗ рд╕рд╛рде рдЕрдВрддрд░
  3. рдлрд┐рд░ рд╣рдо рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдмрд┐рдВрджреБ рдкрд░ рдкрд╣реБрдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рддрдирд╛ рдкрд░рд┐рд╡рд░реНрддрди рдХрд░рдирд╛ рд╣реИ, рдпрд╣ рдЕрдВрддрд░рд╛рд▓ рдЪрд░ рджреНрд╡рд╛рд░рд╛ y рдореЗрдВ рдЕрдВрддрд░ рдХреЛ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
  4. рдЗрд╕рдХреЗ рдмрд╛рдж, рд╣рдо рд╕реНрдерд╛рди рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рд╕реЗ рд╕рднреА рд╢реВрдиреНрдп рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВ
  5. рдЬрдм рд╣рдо y рдЕрдХреНрд╖ рдкрд░ 0 рддрдХ рдкрд╣реБрдВрдЪрддреЗ рд╣реИрдВ, рддреЛ рдКрдВрдЪрд╛рдИ рдХреЛ рд╡рд░реНрддрдорд╛рди рдКрдВрдЪрд╛рдИ рдореЗрдВ рдЬреЛрдбрд╝ рджреЗрдВ рдФрд░ рдЕрдЧрд▓реЗ x рд╕реНрдерд┐рддрд┐ рдХреЗ рд▓рд┐рдП рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рджреЛрд╣рд░рд╛рдПрдВ
  6. рдЕрдВрддрд┐рдо рдФрд░ рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреЗ рдмреАрдЪ рдкреНрд░рддреНрдпреЗрдХ рд╕реНрдерд┐рддрд┐ рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реЛрдиреЗ рдкрд░, рд╣рдо рдЕрдЧрд▓реЗ рдмрд┐рдВрджреБ рдкрд░ рдЬрд╛рддреЗ рд╣реИрдВ

рдпрджрд┐ рдЕрдВрддрд░рд╛рд▓ рдПрдХ рд╕реЗ рдХрдо рд╣реИ, рддреЛ рд╣рдо рдмрд╕ рдкрд┐рдЫрд▓реЗ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рд╕рднреА рдХрд╛рдо рдХрд░реЗрдЧрд╛ред

  else { //Defaults to a normal Perlin gen map = PerlinNoise(map, seed); } return map; 

рдЖрдЗрдП рд░реЗрдВрдбрд░ рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ:


рдмреЗрддрд░рддреАрдм рдЪрд▓рдирд╛


рд░реИрдВрдбрдо рд╡реЙрдХ рдЯреЙрдк


рдпрд╣ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдПрдХ рд╕рд┐рдХреНрдХрд╛ рдлреНрд▓рд┐рдк рдХрд░рддрд╛ рд╣реИред рд╣рдо рджреЛ рдкрд░рд┐рдгрд╛рдореЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрджрд┐ рдкрд░рд┐рдгрд╛рдо "рдИрдЧрд▓" рд╣реИ, рддреЛ рд╣рдо рдПрдХ рдмреНрд▓реЙрдХ рдКрдкрд░ рд▓реЗ рдЬрд╛рддреЗ рд╣реИрдВ, рдпрджрд┐ рдкрд░рд┐рдгрд╛рдо "рдкреВрдВрдЫ" рд╣реИ, рддреЛ рд╣рдо рдмреНрд▓реЙрдХ рдХреЛ рдиреАрдЪреЗ рд▓реЗ рдЬрд╛рддреЗ рд╣реИрдВред рдпрд╣ рд▓рдЧрд╛рддрд╛рд░ рдКрдкрд░ рдпрд╛ рдиреАрдЪреЗ рдЬрд╛рдХрд░ рдКрдБрдЪрд╛рдИ рдмрдирд╛рддрд╛ рд╣реИред рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХрд╛ рдПрдХрдорд╛рддреНрд░ рджреЛрд╖ рдЗрд╕рдХреА рдмрд╣реБрдд рд╣реА рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рдЕрд╡рд░реЛрдз рд╣реИред рдЖрдЗрдП рдирдЬрд╝рд░ рдбрд╛рд▓рддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

 public static int[,] RandomWalkTop(int[,] map, float seed) { //Seed our random System.Random rand = new System.Random(seed.GetHashCode()); //Set our starting height int lastHeight = Random.Range(0, map.GetUpperBound(1)); //Cycle through our width for (int x = 0; x < map.GetUpperBound(0); x++) { //Flip a coin int nextMove = rand.Next(2); //If heads, and we aren't near the bottom, minus some height if (nextMove == 0 && lastHeight > 2) { lastHeight--; } //If tails, and we aren't near the top, add some height else if (nextMove == 1 && lastHeight < map.GetUpperBound(1) - 2) { lastHeight++; } //Circle through from the lastheight to the bottom for (int y = lastHeight; y >= 0; y--) { map[x, y] = 1; } } //Return the map return map; } 


рдПрдВрдЯреА-рдЕрд▓рд┐рдпрд╛рд╕рд┐рдВрдЧ рдХреЗ рд╕рд╛рде рд░реИрдВрдбрдо рд╡реЙрдХ рдЯреЙрдк

рдРрд╕реА рдкреАрдврд╝реА рд╣рдореЗрдВ рдкреЗрд░рд▓рд┐рди рд╢реЛрд░ рдкреАрдврд╝реА рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдЪрд┐рдХрдиреА рдКрдВрдЪрд╛рдЗрдпрд╛рдВ рдкреНрд░рджрд╛рди рдХрд░рддреА рд╣реИред

рд░реИрдВрдбрдо рд╡реЙрдХ рдХреА рдпрд╣ рднрд┐рдиреНрдирддрд╛ рдкрд┐рдЫрд▓реЗ рд╕рдВрд╕реНрдХрд░рдг рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдЪрд┐рдХрдиреА рдкрд░рд┐рдгрд╛рдо рдкреНрд░рджрд╛рди рдХрд░рддреА рд╣реИред рд╣рдо рдЗрд╕реЗ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рджреЛ рдФрд░ рдЪрд░ рдЬреЛрдбрд╝рдХрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

  • рдкрд╣рд▓реЗ рдЪрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдХрд┐ рд╡рд░реНрддрдорд╛рди рдКрдВрдЪрд╛рдИ рдХреЛ рдмрдирд╛рдП рд░рдЦрдиреЗ рдореЗрдВ рдХрд┐рддрдирд╛ рд╕рдордп рд▓рдЧрддрд╛ рд╣реИред рдпрд╣ рдкреВрд░реНрдгрд╛рдВрдХ рд╣реИ рдФрд░ рдКрдВрдЪрд╛рдИ рдмрджрд▓рдиреЗ рдкрд░ рд░реАрд╕реЗрдЯ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ
  • рджреВрд╕рд░рд╛ рдЪрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд▓рд┐рдП рдЗрдирдкреБрдЯ рд╣реИ рдФрд░ рдЗрд╕реЗ рдКрдВрдЪрд╛рдИ рдХреЗ рд▓рд┐рдП рдиреНрдпреВрдирддрдо рдЦрдВрдб рдЪреМрдбрд╝рд╛рдИ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЬрдм рд╣рдо рдлрд╝рдВрдХреНрд╢рди рдХреЛ рджреЗрдЦреЗрдВрдЧреЗ рддреЛ рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЬрд╛рдПрдЧрд╛ред

рдЕрдм рд╣рдо рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдЬреЛрдбрд╝рдирд╛ рд╣реИред рдЖрдЗрдП рдлрд╝рдВрдХреНрд╢рди рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ:

 public static int[,] RandomWalkTopSmoothed(int[,] map, float seed, int minSectionWidth) { //Seed our random System.Random rand = new System.Random(seed.GetHashCode()); //Determine the start position int lastHeight = Random.Range(0, map.GetUpperBound(1)); //Used to determine which direction to go int nextMove = 0; //Used to keep track of the current sections width int sectionWidth = 0; //Work through the array width for (int x = 0; x <= map.GetUpperBound(0); x++) { //Determine the next move nextMove = rand.Next(2); //Only change the height if we have used the current height more than the minimum required section width if (nextMove == 0 && lastHeight > 0 && sectionWidth > minSectionWidth) { lastHeight--; sectionWidth = 0; } else if (nextMove == 1 && lastHeight < map.GetUpperBound(1) && sectionWidth > minSectionWidth) { lastHeight++; sectionWidth = 0; } //Increment the section width sectionWidth++; //Work our way from the height down to 0 for (int y = lastHeight; y >= 0; y--) { map[x, y] = 1; } } //Return the modified map return map; } 

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдиреАрдЪреЗ рджрд┐рдЦрд╛рдП рдЧрдП gif рдореЗрдВ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдЪрд▓рдирд╛ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЛ рдЪреМрд░рд╕рд╛рдИ рдХрд░рдиреЗ рд╕реЗ рдЖрдк рд╕реНрддрд░ рдкрд░ рд╕реБрдВрджрд░ рдлреНрд▓реИрдЯ рдЦрдВрдб рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред


рдирд┐рд╖реНрдХрд░реНрд╖


рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рд▓реЗрдЦ рдЖрдкрдХреЛ рдЕрдкрдиреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдкреНрд░рдХреНрд░рд┐рдпрд╛рддреНрдордХ рдкреАрдврд╝реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░реЗрд░рд┐рдд рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рдкреНрд░рдХреНрд░рд┐рдпрд╛рддреНрдордХ рд░реВрдк рд╕реЗ рдЙрддреНрдкрдиреНрди рдирдХреНрд╢реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдкреНрд░рдХреНрд░рд┐рдпрд╛рддреНрдордХ рдкреАрдврд╝реА рд╡рд┐рдХреА рдпрд╛ Roguebitant.com рдХреЗ рдЙрддреНрдХреГрд╖реНрдЯ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдПрдВ ред

рд▓реЗрдЦ рдХреЗ рджреВрд╕рд░реЗ рднрд╛рдЧ рдореЗрдВ, рд╣рдо рдЧреБрдлрд╛ рдкреНрд░рдгрд╛рд▓реА рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░рдХреНрд░рд┐рдпрд╛рддреНрдордХ рдкреАрдврд╝реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред

рднрд╛рдЧ реи


рдЗрд╕ рднрд╛рдЧ рдореЗрдВ рд╣рдо рдЬреЛ рдХреБрдЫ рднреА рдЪрд░реНрдЪрд╛ рдХрд░реЗрдВрдЧреЗ рд╡рд╣ рдЗрд╕ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдорд┐рд▓ рд╕рдХрддрд╛ рд╣реИред рдЖрдк рд╕рдВрдкрддреНрддрд┐ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдкреНрд░рдХреНрд░рд┐рдпрд╛рддреНрдордХ рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдЖрдЬрд╝рдорд╛ рд╕рдХрддреЗ рд╣реИрдВред


рд╢реЛрд░рдЧреБрд▓


рдкрд┐рдЫрд▓реЗ рднрд╛рдЧ рдореЗрдВ, рд╣рдордиреЗ рд╢реАрд░реНрд╖ рдкрд░рддреЛрдВ рдХреЛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкреЗрд░рд▓рд┐рди рд╢реЛрд░ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЛрдВ рдкрд░ рдзреНрдпрд╛рди рджрд┐рдпрд╛ред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, рдкрд░реНрд▓рд┐рди рдХреЗ рд╢реЛрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЧреБрдлрд╛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рднреА рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рдирдП рдкреЗрд░реНрд▓рд┐рди рд╢реЛрд░ рдореВрд▓реНрдп рдХреА рдЧрдгрдирд╛ рдХрд░рдХреЗ рдорд╣рд╕реВрд╕ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рд╕рдВрд╢реЛрдзрдХ рд╕реЗ рдЧреБрдгрд╛ рдХрд░рддрд╛ рд╣реИред рд╕рдВрд╢реЛрдзрдХ 0 рд╕реЗ 1 рддрдХ рдХрд╛ рдорд╛рди рд╣реИред рд╕рдВрд╢реЛрдзрдХ рдореВрд▓реНрдп рдЬрд┐рддрдирд╛ рдЕрдзрд┐рдХ рд╣реЛрддрд╛ рд╣реИ, рдЙрддрдирд╛ рд╣реА рдЕрд░рд╛рдЬрдХ рдкреЗрд░рд▓рд┐рди рдкреАрдврд╝реА рд╣реЛрддрд╛ рд╣реИред рдлрд┐рд░ рд╣рдо рдЗрд╕ рдорд╛рди рдХреЛ рдкреВрд░реНрдгрд╛рдВрдХ (0 рдпрд╛ 1) рдкрд░ рд░рд╛рдЙрдВрдб рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕реЗ рд╣рдо рдореИрдк рдРрд░реЗ рдореЗрдВ рд╕реНрдЯреЛрд░ рдХрд░рддреЗ рд╣реИрдВред рджреЗрдЦреЗрдВ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:

 public static int[,] PerlinNoiseCave(int[,] map, float modifier, bool edgesAreWalls) { int newPoint; for (int x = 0; x < map.GetUpperBound(0); x++) { for (int y = 0; y < map.GetUpperBound(1); y++) { if (edgesAreWalls && (x == 0 || y == 0 || x == map.GetUpperBound(0) - 1 || y == map.GetUpperBound(1) - 1)) { map[x, y] = 1; //Keep the edges as walls } else { //Generate a new point using Perlin noise, then round it to a value of either 0 or 1 newPoint = Mathf.RoundToInt(Mathf.PerlinNoise(x * modifier, y * modifier)); map[x, y] = newPoint; } } } return map; } 

рд╣рдо рдмреАрдЬ рдХреЗ рдмрдЬрд╛рдп рд╕рдВрд╢реЛрдзрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ 0 рд╕реЗ 0.5 рдХреА рд╕рдВрдЦреНрдпрд╛ рд╕реЗ рдЧреБрдгрд╛ рдХрд░рдиреЗ рдкрд░ рдкреЗрд░рд▓рд┐рди рдХреА рдкреАрдврд╝реА рдХреЗ рдкрд░рд┐рдгрд╛рдо рдмреЗрд╣рддрд░ рджрд┐рдЦрддреЗ рд╣реИрдВред рдореВрд▓реНрдп рдЬрд┐рддрдирд╛ рдХрдо рд╣реЛрдЧрд╛, рдкрд░рд┐рдгрд╛рдо рдЙрддрдирд╛ рдЕрдзрд┐рдХ рдЕрд╡рд░реБрджреНрдз рд╣реЛрдЧрд╛ред рдирдореВрдирд╛ рдкрд░рд┐рдгрд╛рдореЛрдВ рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВред Gif 0.01 рдХреЗ рд╕рдВрд╢реЛрдзрдХ рдореВрд▓реНрдп рд╕реЗ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рд╡реГрджреНрдзрд┐рд╢реАрд▓ 0.25 рдХреЗ рдорд╛рди рддрдХ рдкрд╣реБрдВрдЪрддрд╛ рд╣реИред


рдЗрд╕ gif рд╕реЗ рдпрд╣ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рд╡реГрджреНрдзрд┐ рдХреЗ рд╕рд╛рде Perlin рдкреАрдврд╝реА рдХреЗрд╡рд▓ рдкреИрдЯрд░реНрди рдХреЛ рдмрдврд╝рд╛рддреА рд╣реИред

рдмреЗрддрд░рддреАрдм рдЪрд▓рдирд╛


рдкрд┐рдЫрд▓реЗ рднрд╛рдЧ рдореЗрдВ, рд╣рдордиреЗ рджреЗрдЦрд╛ рдХрд┐ рдЖрдк рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд┐рдХреНрдХреЗ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдКрдкрд░ рдпрд╛ рдиреАрдЪреЗ рдХрд╣рд╛рдБ рдЬрд╛рдПрдЧрд╛ред рдЗрд╕ рднрд╛рдЧ рдореЗрдВ, рд╣рдо рдПрдХ рд╣реА рд╡рд┐рдЪрд╛рд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ, рд▓реЗрдХрд┐рди
рдмрд╛рдПрдБ рдФрд░ рджрд╛рдПрдБ рдмрджрд▓рд╛рд╡ рдХреЗ рд▓рд┐рдП рджреЛ рдЕрддрд┐рд░рд┐рдХреНрдд рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЗ рд╕рд╛рдеред рд░реИрдВрдбрдо рд╡реЙрдХ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреА рдпрд╣ рднрд┐рдиреНрдирддрд╛ рд╣рдореЗрдВ рдЧреБрдлрд╛рдУрдВ рдХреЛ рдмрдирд╛рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рдПрдХ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рджрд┐рд╢рд╛ рдХрд╛ рдЪрдпрди рдХрд░рддреЗ рд╣реИрдВ, рдлрд┐рд░ рд╣рдорд╛рд░реА рд╕реНрдерд┐рддрд┐ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЯрд╛рдЗрд▓ рд╣рдЯрд╛рддреЗ рд╣реИрдВред рд╣рдо рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рддрдм рддрдХ рдЬрд╛рд░реА рд░рдЦрддреЗ рд╣реИрдВ рдЬрдм рддрдХ рд╣рдо рдЖрд╡рд╢реНрдпрдХ рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдЯрд╛рдЗрд▓реЛрдВ рддрдХ рдирд╣реАрдВ рдкрд╣реБрдВрдЪ рдЬрд╛рддреЗ рдЬрд┐рдиреНрд╣реЗрдВ рдирд╖реНрдЯ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдЕрдм рддрдХ, рд╣рдо рдХреЗрд╡рд▓ 4 рджрд┐рд╢рд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ: рдКрдкрд░, рдиреАрдЪреЗ, рдмрд╛рдПрдВ, рджрд╛рдПрдВред

 public static int[,] RandomWalkCave(int[,] map, float seed, int requiredFloorPercent) { //Seed our random System.Random rand = new System.Random(seed.GetHashCode()); //Define our start x position int floorX = rand.Next(1, map.GetUpperBound(0) - 1); //Define our start y position int floorY = rand.Next(1, map.GetUpperBound(1) - 1); //Determine our required floorAmount int reqFloorAmount = ((map.GetUpperBound(1) * map.GetUpperBound(0)) * requiredFloorPercent) / 100; //Used for our while loop, when this reaches our reqFloorAmount we will stop tunneling int floorCount = 0; //Set our start position to not be a tile (0 = no tile, 1 = tile) map[floorX, floorY] = 0; //Increase our floor count floorCount++; 

рдлрд╝рдВрдХреНрд╢рди рдирд┐рдореНрди рд╕реЗ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ:

  1. рд╢реБрд░реБрдЖрддреА рд╕реНрдерд┐рддрд┐ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдПрдВ
  2. рд╣рдЯрд╛рдП рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ рдлрд░реНрд╢ рдЯрд╛рдЗрд▓реНрд╕ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВред
  3. рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдЯрд╛рдЗрд▓ рдХреЛ рд╣рдЯрд╛ рджреЗрдВ
  4. рдЯрд╛рдЗрд▓реНрд╕ рдХреА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдПрдХ рдЬреЛрдбрд╝реЗрдВред

рдлрд┐рд░ рд╣рдо while ред рд╡рд╣ рдПрдХ рдЧреБрдлрд╛ рдмрдирд╛рдПрдЧрд╛:

 while (floorCount < reqFloorAmount) { //Determine our next direction int randDir = rand.Next(4); switch (randDir) { //Up case 0: //Ensure that the edges are still tiles if ((floorY + 1) < map.GetUpperBound(1) - 1) { //Move the y up one floorY++; //Check if that piece is currently still a tile if (map[floorX, floorY] == 1) { //Change it to not a tile map[floorX, floorY] = 0; //Increase floor count floorCount++; } } break; //Down case 1: //Ensure that the edges are still tiles if ((floorY - 1) > 1) { //Move the y down one floorY--; //Check if that piece is currently still a tile if (map[floorX, floorY] == 1) { //Change it to not a tile map[floorX, floorY] = 0; //Increase the floor count floorCount++; } } break; //Right case 2: //Ensure that the edges are still tiles if ((floorX + 1) < map.GetUpperBound(0) - 1) { //Move the x to the right floorX++; //Check if that piece is currently still a tile if (map[floorX, floorY] == 1) { //Change it to not a tile map[floorX, floorY] = 0; //Increase the floor count floorCount++; } } break; //Left case 3: //Ensure that the edges are still tiles if ((floorX - 1) > 1) { //Move the x to the left floorX--; //Check if that piece is currently still a tile if (map[floorX, floorY] == 1) { //Change it to not a tile map[floorX, floorY] = 0; //Increase the floor count floorCount++; } } break; } } //Return the updated map return map; } 

рд╣рдо рдпрд╣рд╛рдВ рдХреНрдпрд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВ?


рдЦреИрд░, рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдПрдХ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд╕рдВрдЦреНрдпрд╛ рдХреА рдорджрдж рд╕реЗ, рд╣рдо рдЪреБрдирддреЗ рд╣реИрдВ рдХрд┐ рдХрд┐рд╕ рджрд┐рд╢рд╛ рдореЗрдВ рдЬрд╛рдирд╛ рд╣реИред рдлрд┐рд░ рд╣рдо switch case рд╕рд╛рде рдирдИ рджрд┐рд╢рд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреЗ рд╣реИрдВред рдЗрд╕ рдХрдерди рдореЗрдВ, рд╣рдо рдЬрд╛рдБрдЪрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рд╕реНрдерд┐рддрд┐ рдПрдХ рджреАрд╡рд╛рд░ рд╣реИред рдпрджрд┐ рдирд╣реАрдВ, рддреЛ рд╕рд░рдгреА рд╕реЗ рдЯрд╛рдЗрд▓ рдХреЗ рд╕рд╛рде рддрддреНрд╡ рдХреЛ рд╣рдЯрд╛ рджреЗрдВред рд╣рдо рдРрд╕рд╛ рддрдм рддрдХ рдХрд░рддреЗ рд░рд╣рддреЗ рд╣реИрдВ рдЬрдм рддрдХ рд╣рдо рд╡рд╛рдВрдЫрд┐рдд рдордВрдЬрд┐рд▓ рдХреНрд╖реЗрддреНрд░ рддрдХ рдирд╣реАрдВ рдкрд╣реБрдБрдЪ рдЬрд╛рддреЗред рдкрд░рд┐рдгрд╛рдо рдиреАрдЪреЗ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ:


рдореИрдВрдиреЗ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЕрдкрдирд╛ рд╕рдВрд╕реНрдХрд░рдг рднреА рдмрдирд╛рдпрд╛, рдЬрд┐рд╕рдореЗрдВ рд╡рд┐рдХрд░реНрдг рджрд┐рд╢рд╛рдПрдВ рднреА рд╢рд╛рдорд┐рд▓ рд╣реИрдВред рдлрд╝рдВрдХреНрд╢рди рдХреЛрдб рдХрд╛рдлреА рд▓рдВрдмрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрджрд┐ рдЖрдк рдЗрд╕реЗ рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд▓реЗрдЦ рдХреЗ рдЗрд╕ рднрд╛рдЧ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рд▓рд┐рдВрдХ рд╕реЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдбрд╛рдЙрдирд▓реЛрдб рдХрд░реЗрдВред

рджрд┐рд╢рд╛рддреНрдордХ рд╕реБрд░рдВрдЧ


рдПрдХ рджрд┐рд╢рд╛рддреНрдордХ рд╕реБрд░рдВрдЧ рдирдХреНрд╢реЗ рдХреЗ рдПрдХ рдХрд┐рдирд╛рд░реЗ рд╕реЗ рд╢реБрд░реВ рд╣реЛрддреА рд╣реИ рдФрд░ рд╡рд┐рдкрд░реАрдд рдЫреЛрд░ рддрдХ рдкрд╣реБрдВрдЪрддреА рд╣реИред рд╣рдо рдЗрдирдкреБрдЯ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкрд╛рд╕ рдХрд░рдХреЗ рд╕реБрд░рдВрдЧ рдХреА рд╡рдХреНрд░рддрд╛ рдФрд░ рдЦреБрд░рджрд░рд╛рдкрди рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╣рдо рд╕реБрд░рдВрдЧ рдХреЗ рд╣рд┐рд╕реНрд╕реЛрдВ рдХреА рдиреНрдпреВрдирддрдо рдФрд░ рдЕрдзрд┐рдХрддрдо рд▓рдВрдмрд╛рдИ рднреА рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдЗрдП рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ:

 public static int[,] DirectionalTunnel(int[,] map, int minPathWidth, int maxPathWidth, int maxPathChange, int roughness, int curvyness) { //This value goes from its minus counterpart to its positive value, in this case with a width value of 1, the width of the tunnel is 3 int tunnelWidth = 1; //Set the start X position to the center of the tunnel int x = map.GetUpperBound(0) / 2; //Set up our random with the seed System.Random rand = new System.Random(Time.time.GetHashCode()); //Create the first part of the tunnel for (int i = -tunnelWidth; i <= tunnelWidth; i++) { map[x + i, 0] = 0; } 

рдХреНрдпрд╛ рдЪрд▓ рд░рд╣рд╛ рд╣реИ?


рдкрд╣рд▓реЗ рд╣рдо рдЪреМрдбрд╝рд╛рдИ рдорд╛рди рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВред рдЪреМрдбрд╝рд╛рдИ рдорд╛рди рд╢реВрдиреНрдп рд╕реЗ рдзрдирд╛рддреНрдордХ рдХреЗ рдорд╛рди рд╕реЗ рдЬрд╛рдПрдЧрд╛ред рдЗрд╕рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж рд╣рдореЗрдВ рд╡рд╣ рдЖрдХрд╛рд░ рдорд┐рд▓реЗрдЧрд╛ рдЬрд┐рд╕рдХреА рд╣рдореЗрдВ рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рд╣рдо рдорд╛рди 1 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЬреЛ рдмрджрд▓реЗ рдореЗрдВ рд╣рдореЗрдВ рдХреБрд▓ 3 рдХреА рдЪреМрдбрд╝рд╛рдИ рджреЗрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдорд╛рди -1, 0, 1 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред

рдЕрдЧрд▓рд╛, рд╣рдо рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕реНрдерд┐рддрд┐ рдХреЛ x рдореЗрдВ рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рдХреЗ рд▓рд┐рдП рд╣рдо рдорд╛рдирдЪрд┐рддреНрд░ рдХреА рдЪреМрдбрд╝рд╛рдИ рдХреЗ рдордзреНрдп рдХреЛ рд▓реЗрддреЗ рд╣реИрдВред рдЙрд╕рдХреЗ рдмрд╛рдж, рд╣рдо рдирдХреНрд╢реЗ рдХреЗ рдкрд╣рд▓реЗ рднрд╛рдЧ рдореЗрдВ рдПрдХ рд╕реБрд░рдВрдЧ рдмрд┐рдЫрд╛ рд╕рдХрддреЗ рд╣реИрдВред


рдЕрдм рдмрд╛рдХреА рдХреЗ рдирдХреНрд╢реЗ рдореЗрдВ рдЖрддреЗ рд╣реИрдВред

  //Cycle through the array for (int y = 1; y < map.GetUpperBound(1); y++) { //Check if we can change the roughness if (rand.Next(0, 100) > roughness) { //Get the amount we will change for the width int widthChange = Random.Range(-maxPathWidth, maxPathWidth); //Add it to our tunnel width value tunnelWidth += widthChange; //Check to see we arent making the path too small if (tunnelWidth < minPathWidth) { tunnelWidth = minPathWidth; } //Check that the path width isnt over our maximum if (tunnelWidth > maxPathWidth) { tunnelWidth = maxPathWidth; } } //Check if we can change the curve if (rand.Next(0, 100) > curvyness) { //Get the amount we will change for the x position int xChange = Random.Range(-maxPathChange, maxPathChange); //Add it to our x value x += xChange; //Check we arent too close to the left side of the map if (x < maxPathWidth) { x = maxPathWidth; } //Check we arent too close to the right side of the map if (x > (map.GetUpperBound(0) - maxPathWidth)) { x = map.GetUpperBound(0) - maxPathWidth; } } //Work through the width of the tunnel for (int i = -tunnelWidth; i <= tunnelWidth; i++) { map[x + i, y] = 0; } } return map; } 

рд╣рдо рдЦреБрд░рджрд░рд╛рдкрди рдореВрд▓реНрдп рдХреЗ рд╕рд╛рде рддреБрд▓рдирд╛ рдХреЗ рд▓рд┐рдП рдПрдХ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд╕рдВрдЦреНрдпрд╛ рдЙрддреНрдкрдиреНрди рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдпрджрд┐ рдпрд╣ рдЗрд╕ рдореВрд▓реНрдп рд╕реЗ рдЕрдзрд┐рдХ рд╣реИ, рддреЛ рдкрде рдХреА рдЪреМрдбрд╝рд╛рдИ рдХреЛ рдмрджрд▓рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╣рдо рдорд╛рди рдХреА рдЬрд╛рдБрдЪ рднреА рдХрд░рддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдЪреМрдбрд╝рд╛рдИ рдмрд╣реБрдд рдЫреЛрдЯреА рди рд╣реЛред рдХреЛрдб рдХреЗ рдЕрдЧрд▓реЗ рднрд╛рдЧ рдореЗрдВ, рд╣рдо рдорд╛рдирдЪрд┐рддреНрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЕрдкрдирд╛ рд░рд╛рд╕реНрддрд╛ рдмрдирд╛рддреЗ рд╣реИрдВред рдкреНрд░рддреНрдпреЗрдХ рдЪрд░рдг рдореЗрдВ, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╣реЛрддрд╛ рд╣реИ:

  1. рд╣рдо рд╡рдХреНрд░рддрд╛ рдХреЗ рдореВрд▓реНрдп рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдПрдХ рдирдпрд╛ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд╕рдВрдЦреНрдпрд╛ рдЙрддреНрдкрдиреНрди рдХрд░рддреЗ рд╣реИрдВред рдкрд┐рдЫрд▓реЗ рдкрд░реАрдХреНрд╖рдг рдХреА рддрд░рд╣, рдпрджрд┐ рдпрд╣ рдореВрд▓реНрдп рд╕реЗ рдЕрдзрд┐рдХ рд╣реИ, рддреЛ рд╣рдо рдкрде рдХреЗ рдХреЗрдВрджреНрд░ рдмрд┐рдВрджреБ рдХреЛ рдмрджрд▓рддреЗ рд╣реИрдВред рд╣рдо рдПрдХ рдЬрд╛рдВрдЪ рднреА рдХрд░рддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рдирдХреНрд╢реЗ рд╕реЗ рдЖрдЧреЗ рди рдмрдврд╝ рд╕рдХреЗрдВред
  2. рдЕрдВрдд рдореЗрдВ, рд╣рдо рдирдП рдмрдирд╛рдП рдЧрдП рднрд╛рдЧ рдореЗрдВ рдПрдХ рд╕реБрд░рдВрдЧ рдмрд┐рдЫрд╛ рд░рд╣реЗ рд╣реИрдВред

рдЗрд╕ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдкрд░рд┐рдгрд╛рдо рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддреЗ рд╣реИрдВ:


рд╕реЗрд▓реБрд▓рд░ рдСрдЯреЛрдореЗрдЯрд╛


рд╕реЗрд▓реНрдпреВрд▓рд░ рдСрдЯреЛрдореЗрдЯрд╛ рдкрдбрд╝реЛрд╕реА рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рд╡рд░реНрддрдорд╛рди рд╕реЗрд▓ рдЪрд╛рд▓реВ рд╣реИ (1) рдпрд╛ рдмрдВрдж (0)ред рдкрдбрд╝реЛрд╕реА рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХрд╛ рдирд┐рд░реНрдзрд╛рд░рдг рдХрд░рдиреЗ рдХрд╛ рдЖрдзрд╛рд░ рдХреЛрд╢рд┐рдХрд╛рдУрдВ рдХреЗ рдмреЗрддрд░рддреАрдм рдврдВрдЧ рд╕реЗ рдЙрддреНрдкрдиреНрди рдЧреНрд░рд┐рдб рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред рд╣рдо C # Random.Next рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕ рд╕реНрд░реЛрдд рдЧреНрд░рд┐рдб рдХреЛ рдЙрддреНрдкрдиреНрди рдХрд░реЗрдВрдЧреЗред

рдЪреВрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╕реЗрд▓реБрд▓рд░ рдСрдЯреЛрдореЗрдЯрд╛ рдХреЗ рд╡рд┐рднрд┐рдиреНрди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдЗрд╕ рдореВрд▓ рдЧреНрд░рд┐рдб рдХреЛ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрд▓рдЧ рдлрд╝рдВрдХреНрд╢рди рд▓рд┐рдЦрд╛ рд╣реИред рдлрд╝рдВрдХреНрд╢рди рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:

 public static int[,] GenerateCellularAutomata(int width, int height, float seed, int fillPercent, bool edgesAreWalls) { //Seed our random number generator System.Random rand = new System.Random(seed.GetHashCode()); //Initialise the map int[,] map = new int[width, height]; for (int x = 0; x < map.GetUpperBound(0); x++) { for (int y = 0; y < map.GetUpperBound(1); y++) { //If we have the edges set to be walls, ensure the cell is set to on (1) if (edgesAreWalls && (x == 0 || x == map.GetUpperBound(0) - 1 || y == 0 || y == map.GetUpperBound(1) - 1)) { map[x, y] = 1; } else { //Randomly generate the grid map[x, y] = (rand.Next(0, 100) < fillPercent) ? 1 : 0; } } } return map; } 

рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ, рдЖрдк рдпрд╣ рднреА рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдЧреНрд░рд┐рдб рдХреЛ рджреАрд╡рд╛рд░реЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдпрд╛ рдирд╣реАрдВред рдЕрдиреНрдп рд╕рднреА рдорд╛рдорд▓реЛрдВ рдореЗрдВ, рдпрд╣ рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИред рд╡рд░реНрддрдорд╛рди рд╕реЗрд▓ рд╕рдХреНрд╖рдо рд╣реИ рдпрд╛ рдирд╣реАрдВ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╣рдо рдкреНрд░рддрд┐рд╢рдд рднрд░рдиреЗ рдХреЗ рд╕рд╛рде рдПрдХ рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд╕рдВрдЦреНрдпрд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреЗ рд╣реИрдВред рдкрд░рд┐рдгрд╛рдо рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ:


рдореВрд░ рдХрд╛ рдкрдбрд╝реЛрд╕


рдореВрд░ рдкрдбрд╝реЛрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╕реЗрд▓реБрд▓рд░ рдСрдЯреЛрдореЗрдЯрд╛ рдХреА рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдкреАрдврд╝реА рдХреЛ рд╕реБрдЪрд╛рд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдореВрд░ рдХрд╛ рдкрдбрд╝реЛрд╕ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:


рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдирд┐рдпрдо рдкрдбрд╝реЛрд╕ рдкрд░ рд▓рд╛рдЧреВ рд╣реЛрддреЗ рд╣реИрдВ:

  • рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рджрд┐рд╢рд╛ рдореЗрдВ рдкрдбрд╝реЛрд╕реА рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреЗ рд╣реИрдВред
  • рдпрджрд┐ рдкрдбрд╝реЛрд╕реА рдПрдХ рд╕рдХреНрд░рд┐рдп рдЯрд╛рдЗрд▓ рд╣реИ, рддреЛ рдЖрд╕рдкрд╛рд╕ рдХреЗ рдЯрд╛рдЗрд▓реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдПрдХ рдЬреЛрдбрд╝реЗрдВред
  • рдпрджрд┐ рдкрдбрд╝реЛрд╕реА рдПрдХ рдирд┐рд╖реНрдХреНрд░рд┐рдп рдЯрд╛рдЗрд▓ рд╣реИ, рддреЛ рд╣рдо рдХреБрдЫ рднреА рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред
  • рдпрджрд┐ рдХрд┐рд╕реА рд╕реЗрд▓ рдореЗрдВ 4 рд╕реЗ рдЕрдзрд┐рдХ рдЖрд╕рдкрд╛рд╕ рдХреА рдЯрд╛рдЗрд▓реЗрдВ рд╣реИрдВ, рддреЛ рд╕реЗрд▓ рдХреЛ рд╕рдХреНрд░рд┐рдп рдХрд░реЗрдВред
  • рдпрджрд┐ рд╕реЗрд▓ рдореЗрдВ рд▓рдЧрднрдЧ 4 рдЯрд╛рдЗрд▓реЗрдВ рд╣реИрдВ, рддреЛ рд╣рдо рдЗрд╕рдХреЗ рд╕рд╛рде рдХреБрдЫ рднреА рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред
  • рддрдм рддрдХ рджреЛрд╣рд░рд╛рдПрдВ рдЬрдм рддрдХ рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдорд╛рдирдЪрд┐рддреНрд░ рдЯрд╛рдЗрд▓ рдХреА рдЬрд╛рдВрдЪ рдирд╣реАрдВ рдХрд░рддреЗред

рдореВрд░ рдХрд╛ рдкрдбрд╝реЛрд╕ рдЬрд╛рдБрдЪ рдХрд╛рд░реНрдп рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╣реИ:

 static int GetMooreSurroundingTiles(int[,] map, int x, int y, bool edgesAreWalls) { /* Moore Neighbourhood looks like this ('T' is our tile, 'N' is our neighbours) * * NNN * NTN * NNN * */ int tileCount = 0; for(int neighbourX = x - 1; neighbourX <= x + 1; neighbourX++) { for(int neighbourY = y - 1; neighbourY <= y + 1; neighbourY++) { if (neighbourX >= 0 && neighbourX < map.GetUpperBound(0) && neighbourY >= 0 && neighbourY < map.GetUpperBound(1)) { //We don't want to count the tile we are checking the surroundings of if(neighbourX != x || neighbourY != y) { tileCount += map[neighbourX, neighbourY]; } } } } return tileCount; } 

рдЯрд╛рдЗрд▓ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдЗрд╕ рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рд╕реНрдореВрдерд┐рдВрдЧ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣рд╛рдВ, рд╕реЗрд▓реБрд▓рд░ рдСрдЯреЛрдореЗрдЯрд╛ рдХреА рдкреАрдврд╝реА рдХреЗ рд░реВрдк рдореЗрдВ, рдХреЛрдИ рдпрд╣ рдЗрдВрдЧрд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдХреНрдпрд╛ рдирдХреНрд╢реЗ рдХреЗ рдХрд┐рдирд╛рд░реЛрдВ рдХреА рджреАрд╡рд╛рд░реЗрдВ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред

 public static int[,] SmoothMooreCellularAutomata(int[,] map, bool edgesAreWalls, int smoothCount) { for (int i = 0; i < smoothCount; i++) { for (int x = 0; x < map.GetUpperBound(0); x++) { for (int y = 0; y < map.GetUpperBound(1); y++) { int surroundingTiles = GetMooreSurroundingTiles(map, x, y, edgesAreWalls); if (edgesAreWalls && (x == 0 || x == (map.GetUpperBound(0) - 1) || y == 0 || y == (map.GetUpperBound(1) - 1))) { //Set the edge to be a wall if we have edgesAreWalls to be true map[x, y] = 1; } //The default moore rule requires more than 4 neighbours else if (surroundingTiles > 4) { map[x, y] = 1; } else if (surroundingTiles < 4) { map[x, y] = 0; } } } } //Return the modified map return map; } 

рдпрд╣рд╛рдВ рдпрд╣ рдиреЛрдЯ рдХрд░рдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдХрд┐ рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдПрдХ рд▓реВрдк рд╣реИ рдЬреЛ рдХрдИ рдмрд╛рд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдЪреМрд░рд╕рд╛рдИ рдХрд░рддрд╛ рд╣реИред рдЗрд╕рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рдПрдХ рдЕрдзрд┐рдХ рд╕реБрдВрджрд░ рдХрд╛рд░реНрдб рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред


рд╣рдо рдЗрд╕ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЛ рд╣рдореЗрд╢рд╛ рдХрдорд░реЗ рдХреЛ рдЬреЛрдбрд╝рдХрд░ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЙрдирдХреЗ рдмреАрдЪ рдХреЗрд╡рд▓ рджреЛ рдмреНрд▓реЙрдХ рд╣реИрдВред

рд╡реЙрди рдиреНрдпреВрдореИрди рдкрдбрд╝реЛрд╕


рд╡реЙрди рдиреНрдпреВрдореИрди рдкрдбрд╝реЛрд╕ рд╕реЗрд▓реБрд▓рд░ рдСрдЯреЛрдореЗрдЯрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдФрд░ рд▓реЛрдХрдкреНрд░рд┐рдп рддрд░реАрдХрд╛ рд╣реИред рдРрд╕реА рдкреАрдврд╝реА рдХреЗ рд▓рд┐рдП, рд╣рдо рдореВрд░ рдкреАрдврд╝реА рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдПрдХ рд╕рд░рд▓ рдкрдбрд╝реЛрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдкрдбрд╝реЛрд╕ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:


рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдирд┐рдпрдо рдкрдбрд╝реЛрд╕ рдкрд░ рд▓рд╛рдЧреВ рд╣реЛрддреЗ рд╣реИрдВ:

  • рд╣рдо рддрд┐рд░рдЫреЗ рд▓реЛрдЧреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реБрдП, рдЯрд╛рдЗрд▓ рдХреЗ рддрддреНрдХрд╛рд▓ рдкрдбрд╝реЛрд╕рд┐рдпреЛрдВ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреЗ рд╣реИрдВред
  • рдпрджрд┐ рдХреЛрд╢рд┐рдХрд╛ рд╕рдХреНрд░рд┐рдп рд╣реИ, рддреЛ рдПрдХ рдорд╛рддреНрд░рд╛ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВред
  • рдпрджрд┐ рд╕реЗрд▓ рдирд┐рд╖реНрдХреНрд░рд┐рдп рд╣реИ, рддреЛ рдХреБрдЫ рднреА рди рдХрд░реЗрдВред
  • рдпрджрд┐ рд╕реЗрд▓ рдореЗрдВ 2 рд╕реЗ рдЕрдзрд┐рдХ рдкрдбрд╝реЛрд╕реА рд╣реИрдВ, рддреЛ рд╣рдо рд╡рд░реНрддрдорд╛рди рд╕реЗрд▓ рдХреЛ рд╕рдХреНрд░рд┐рдп рдмрдирд╛рддреЗ рд╣реИрдВред
  • рдпрджрд┐ рд╕реЗрд▓ рдореЗрдВ 2 рд╕реЗ рдХрдо рдкрдбрд╝реЛрд╕реА рд╣реИрдВ, рддреЛ рд╣рдо рд╡рд░реНрддрдорд╛рди рд╕реЗрд▓ рдХреЛ рдирд┐рд╖реНрдХреНрд░рд┐рдп рдХрд░рддреЗ рд╣реИрдВред
  • рдпрджрд┐ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ 2 рдкрдбрд╝реЛрд╕реА рд╣реИрдВ, рддреЛ рд╡рд░реНрддрдорд╛рди рд╕реЗрд▓ рдХреЛ рди рдмрджрд▓реЗрдВред

рджреВрд╕рд░рд╛ рдкрд░рд┐рдгрд╛рдо рдкрд╣рд▓реЗ рдХреЗ рд╕рдорд╛рди рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдкрдбрд╝реЛрд╕ рдХреЗ рдХреНрд╖реЗрддреНрд░ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рддрд╛ рд╣реИред

рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рд╛рде рдкрдбрд╝реЛрд╕рд┐рдпреЛрдВ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддреЗ рд╣реИрдВ:

 static int GetVNSurroundingTiles(int[,] map, int x, int y, bool edgesAreWalls) { /* von Neumann Neighbourhood looks like this ('T' is our Tile, 'N' is our Neighbour) * * N * NTN * N * */ int tileCount = 0; //Keep the edges as walls if(edgesAreWalls && (x - 1 == 0 || x + 1 == map.GetUpperBound(0) || y - 1 == 0 || y + 1 == map.GetUpperBound(1))) { tileCount++; } //Ensure we aren't touching the left side of the map if(x - 1 > 0) { tileCount += map[x - 1, y]; } //Ensure we aren't touching the bottom of the map if(y - 1 > 0) { tileCount += map[x, y - 1]; } //Ensure we aren't touching the right side of the map if(x + 1 < map.GetUpperBound(0)) { tileCount += map[x + 1, y]; } //Ensure we aren't touching the top of the map if(y + 1 < map.GetUpperBound(1)) { tileCount += map[x, y + 1]; } return tileCount; } 

рдкрдбрд╝реЛрд╕рд┐рдпреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рд╕рд░рдгреА рдХреЛ рд╕реБрдЪрд╛рд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдЧреЗ рдмрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред рдкрд╣рд▓реЗ рдХреА рддрд░рд╣, рд╣рдореЗрдВ forрдЗрдирдкреБрдЯ рдХреЛ рдкрд╛рд░рд┐рдд рдХрд┐рдП рдЧрдП рдЪреМрд░рд╕рд╛рдИ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐рдпреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдкреВрд░рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд▓реВрдк рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ ред

 public static int[,] SmoothVNCellularAutomata(int[,] map, bool edgesAreWalls, int smoothCount) { for (int i = 0; i < smoothCount; i++) { for (int x = 0; x < map.GetUpperBound(0); x++) { for (int y = 0; y < map.GetUpperBound(1); y++) { //Get the surrounding tiles int surroundingTiles = GetVNSurroundingTiles(map, x, y, edgesAreWalls); if (edgesAreWalls && (x == 0 || x == map.GetUpperBound(0) - 1 || y == 0 || y == map.GetUpperBound(1))) { //Keep our edges as walls map[x, y] = 1; } //von Neuemann Neighbourhood requires only 3 or more surrounding tiles to be changed to a tile else if (surroundingTiles > 2) { map[x, y] = 1; } else if (surroundingTiles < 2) { map[x, y] = 0; } } } } //Return the modified map return map; } 

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдиреАрдЪреЗ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдЕрдВрддрд┐рдо рдкрд░рд┐рдгрд╛рдо рдореВрд░ рдХреЗ рдкрдбрд╝реЛрд╕ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рдЕрд╡рд░реБрджреНрдз рд╣реИ:


рдпрд╣рд╛рдБ, рдореВрд░ рдХреЗ рдЖрд╕рдкрд╛рд╕ рдХреЗ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ, рдЖрдк рдирдХреНрд╢реЗ рдХреЗ рд╣рд┐рд╕реНрд╕реЛрдВ рдХреЗ рдмреАрдЪ рдХрдиреЗрдХреНрд╢рди рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВред

рдирд┐рд╖реНрдХрд░реНрд╖


рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рд▓реЗрдЦ рдЖрдкрдХреЛ рдЕрдкрдиреА рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛рддреНрдордХ рдкреАрдврд╝реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкреНрд░реЗрд░рд┐рдд рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдЖрдкрдиреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдбрд╛рдЙрдирд▓реЛрдб рдирд╣реАрдВ рдХрд┐рдпрд╛ рд╣реИ, рддреЛ рдЖрдк рдЗрд╕реЗ рдпрд╣рд╛рдВ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ ред

Source: https://habr.com/ru/post/hi471084/


All Articles