167 lines
4.9 KiB
C#
167 lines
4.9 KiB
C#
|
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 can’t 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)];
|
|||
|
}
|
|||
|
}
|
|||
|
}
|