holopy3/Assets/Scripts/RecursiveBacktrackerChris.cs
2020-12-10 15:25:12 +01:00

166 lines
4.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RecursiveBacktrackerChris : MonoBehaviour
{
private MyTile[,] levelTiles;
private GameObject level;
private Vector2Int currentPos;
private Stack<Vector2Int> positions;
public GameObject Ground;
public GameObject Wall;
public int MapSize;
public int StepLength;
private void Awake()
{
level = new GameObject("Level");
positions = new Stack<Vector2Int>();
CreateLevel(MapSize);
MakeMaze();
}
private void CreateLevel(int size)
{
levelTiles = new MyTile[size, size];
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
//GameObject temp = GameObject.Instantiate(Wall);
GameObject temp = GameObject.CreatePrimitive(PrimitiveType.Cube); //kann verwendet werden, wenn du keine eigenen Assets für Wall hast.
temp.transform.position = new Vector3(i, j, 0);
temp.transform.SetParent(level.transform);
levelTiles[i, j] = temp.AddComponent<MyTile>();
// frame as ground  cant dig there
if (i == 0 || j == 0 || i == size - 1 || j == size - 1)
{
levelTiles[i, j].type = MyTile.TileType.Ground;
}
}
}
}
private void MakeMaze()
{
currentPos = GetRandomStartPosition();
SetTileType(currentPos, MyTile.TileType.Ground);
positions.Push(currentPos);
while (positions.Count > 0)
{
Vector2Int digDirection = GetRandomDirection(currentPos);
while (digDirection == Vector2Int.zero)
{
positions.Pop();
if (positions.Count == 0)
return;
currentPos = positions.Peek();
digDirection = GetRandomDirection(currentPos);
}
currentPos = DigDirection(currentPos, digDirection, StepLength);
positions.Push(currentPos);
}
}
// zufälligen Startpunkt wählen
private Vector2Int GetRandomStartPosition()
{
int startX = Random.Range(1, MapSize - 1);
int startY = Random.Range(1, MapSize - 1);
startX = startX % 2 == 0 ? startX - 1 : startX;
startY = startY % 2 == 0 ? startY - 1 : startY;
Vector2Int startPos = new Vector2Int(startX, startY);
return startPos;
}
private MyTile GetNeighbor(Vector2Int position, Vector2Int direction)
{
MyTile temp = null;
try
{
temp = levelTiles[position.x + StepLength * direction.x,
position.y + StepLength * direction.y];
if (temp.type == MyTile.TileType.Ground)
{
temp = null;
}
}
catch (System.IndexOutOfRangeException e)
{
Debug.LogWarning(e.Message);
}
return temp;
}
private Vector2Int DigDirection(Vector2Int position, Vector2Int direction, int stepLength)
{
for (int i = 0; i <= stepLength; i++)
{
SetTileType(position + i * direction, MyTile.TileType.Ground);
}
return position + stepLength * direction;
}
private void SetTileType(Vector2Int position, MyTile.TileType tileType)
{
try
{
levelTiles[position.x, position.y].type = tileType;
if (tileType == MyTile.TileType.Ground)
{
Destroy(levelTiles[position.x, position.y].gameObject);
GameObject temp = GameObject.Instantiate(Ground,
new Vector3(position.x, position.y, 0),
Quaternion.identity);
temp.transform.SetParent(level.transform);
}
}
catch (System.IndexOutOfRangeException e)
{
Debug.LogWarning($"{e.Message}: position = {position}");
}
}
// zufällige Richtung graben
private Vector2Int GetRandomDirection(Vector2Int position)
{
List<Vector2Int> directions = new List<Vector2Int>();
if (GetNeighbor(position, Vector2Int.right) != null)
{
directions.Add(Vector2Int.right);
}
if (GetNeighbor(position, Vector2Int.left) != null)
{
directions.Add(Vector2Int.left);
}
if (GetNeighbor(position, Vector2Int.down) != null)
{
directions.Add(Vector2Int.down);
}
if (GetNeighbor(position, Vector2Int.up) != null)
{
directions.Add(Vector2Int.up);
}
// wenn Sackgasse, Position vom Stack nehmen
if (directions.Count == 0)
{
// keine Nachbarn gefunden
return Vector2Int.zero;
}
else
{
return directions[Random.Range(0, directions.Count)];
}
}
}