Created
December 16, 2020 19:17
-
-
Save Ratstail91/1585a40a3380d24fab953457aeb36cef to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//contents based on the type of the tile | |
public enum DungeonContent { | |
EMPTY = 0, STAIRS_UP, STAIRS_DOWN, SPAWN_MONSTER, SPAWN_TREASURE | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEngine.Tilemaps; | |
public class DungeonEtcher : MapEtcher { | |
//structures | |
[Serializable] | |
public struct TileEtch { | |
[SerializeField] | |
public string name; | |
[SerializeField] | |
public TileType type; | |
[SerializeField] | |
public Tile asset; | |
[SerializeField] | |
public DungeonContent content; //TODO: can change later | |
[SerializeField] | |
public bool collision; | |
} | |
//public variables | |
public TileEtch[] tileEtches; | |
//DOCS: returns the collision data as a separate 2d array | |
public override bool[,] EtchTileData(Tilemap tilemap, TileType[,] tileData) { | |
bool[,] collisionData = new bool[tileData.GetLength(0), tileData.GetLength(1)]; | |
tilemap.ClearAllTiles(); | |
for(int i = 0; i < tileData.GetLength(0); i++) { | |
for (int j = 0; j < tileData.GetLength(1); j++) { | |
foreach(TileEtch etch in tileEtches) { | |
if (tileData[i,j] == etch.type) { | |
//actually etch the data | |
tilemap.SetTile(new Vector3Int(i, j, 0), etch.asset); | |
collisionData[i,j] = etch.collision; | |
//if there is supposed to be content here, place it | |
if (etch.content != DungeonContent.EMPTY) { | |
switch (etch.content) { | |
//TODO: more | |
default: | |
//DO NOTHING | |
break; /* switch */ | |
} | |
} | |
break; /* foreach */ | |
} | |
} | |
} | |
} | |
return collisionData; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using Random = UnityEngine.Random; | |
public class DungeonGenerator : MapGenerator { | |
//parameters | |
[SerializeField] | |
int mapWidth = 100; | |
[SerializeField] | |
int mapHeight = 100; | |
[SerializeField] | |
int terminationThreshold = 10; | |
//structures | |
enum Direction { | |
VERTICAL = 0, HORIZONTAL = 1 | |
} | |
//generation methods | |
public override TileType[,] GenerateTileData() { | |
TileType[,] tileData = new TileType[mapWidth, mapHeight]; | |
//zero the array | |
for (int i = 0; i < mapWidth; i++) { | |
for (int j = 0; j < mapHeight; j++) { | |
tileData[i, j] = TileType.WALL; | |
} | |
} | |
PartitionSpace(0, 0, mapWidth, mapHeight, ref tileData); | |
return tileData; | |
} | |
Vector2Int PartitionSpace(int x1, int y1, int x2, int y2, ref TileType[,] tileData) { | |
//calc the width & height | |
int width = x2 - x1; | |
int height = y2 - y1; | |
//check the termination threshold | |
if (width <= terminationThreshold || height <= terminationThreshold) { | |
//draw the box | |
return GenerateRoom(x1, y1, x2, y2, ref tileData); | |
} | |
//get the partition direction | |
Direction direction; | |
if (width == height) { | |
direction = (Direction)Random.Range(0, 2); | |
} else { | |
direction = (Direction)(height < width ? Direction.VERTICAL : Direction.HORIZONTAL); | |
} | |
//split the partition in the middle third | |
switch (direction) { | |
case Direction.VERTICAL: { | |
int splitPos = Random.Range(width/3, (width/3) * 2); | |
Vector2Int a = PartitionSpace(x1, y1, x1 + splitPos, y2, ref tileData); | |
Vector2Int b = PartitionSpace(x1 + splitPos + 1, y1, x2, y2, ref tileData); | |
return GenerateCorridor(a, b, ref tileData); | |
} | |
case Direction.HORIZONTAL: { | |
int splitPos = Random.Range(height/3, (height/3) * 2); | |
Vector2Int a = PartitionSpace(x1, y1, x2, y1 + splitPos, ref tileData); | |
Vector2Int b = PartitionSpace(x1, y1 + splitPos + 1, x2, y2, ref tileData); | |
return GenerateCorridor(a, b, ref tileData); | |
} | |
} | |
throw new System.InvalidOperationException("Unreachable"); | |
} | |
Vector2Int GenerateRoom(int x1, int y1, int x2, int y2, ref TileType[,] tileData) { | |
//calc the partition width & height | |
int width = x2 - x1; | |
int height = y2 - y1; | |
//TODO: prefab room chance | |
//room bounds | |
int xBegin = Random.Range(x1 + 1, x1 + width/2); | |
int xEnd = Random.Range(x1 + width/2 + 1, x2 - 1); | |
int yBegin = Random.Range(y1 + 1, y1 + height/2); | |
int yEnd = Random.Range(y1 + height/2 + 1, y2 - 1); | |
for (int i = xBegin; i <= xEnd; i++) { | |
for (int j = yBegin; j <= yEnd; j++) { | |
tileData[i, j] = TileType.ROOM; | |
} | |
} | |
return new Vector2Int(Random.Range(xBegin, xEnd + 1), Random.Range(yBegin, yEnd + 1)); | |
} | |
Vector2Int GenerateCorridor(Vector2Int a, Vector2Int b, ref TileType[,] tileData) { | |
Vector2Int ret = new Vector2Int(99999,99999); //return value | |
if (a == ret || b == ret) { | |
return ret; | |
} | |
int width = (int)Mathf.Abs(a.x - b.x); | |
int height = (int)Mathf.Abs(a.y - b.y); | |
//initial direction from a | |
Direction direction; | |
if (width == height) { | |
direction = (Direction)Random.Range(0, 2); | |
} else { | |
direction = width > height ? Direction.HORIZONTAL : Direction.VERTICAL; | |
} | |
//draw from a to b, overwriting wall tiles only | |
switch(direction) { | |
case Direction.HORIZONTAL: | |
for (int i = (int)Mathf.Min(a.x, b.x); i <= (int)Mathf.Max(a.x, b.x); i++) { | |
if (tileData[i, a.y] == TileType.WALL) { | |
tileData[i, a.y] = TileType.EMPTY; | |
} | |
CheckCorridorCenter(width, height, i, a.y, ref ret); | |
} | |
for (int j = (int)Mathf.Min(a.y, b.y); j <= (int)Mathf.Max(a.y, b.y); j++) { | |
if (tileData[b.x, j] == TileType.WALL) { | |
tileData[b.x, j] = TileType.EMPTY; | |
} | |
CheckCorridorCenter(width, height, (int)Mathf.Max(a.x, b.x), j, ref ret); | |
} | |
break; | |
case Direction.VERTICAL: | |
for (int j = (int)Mathf.Min(a.y, b.y); j <= (int)Mathf.Max(a.y, b.y); j++) { | |
if (tileData[a.x, j] == TileType.WALL) { | |
tileData[a.x, j] = TileType.EMPTY; | |
} | |
CheckCorridorCenter(width, height, a.x, j, ref ret); | |
} | |
for (int i = (int)Mathf.Min(a.x, b.x); i <= (int)Mathf.Max(a.x, b.x); i++) { | |
if (tileData[i, b.y] == TileType.WALL) { | |
tileData[i, b.y] = TileType.EMPTY; | |
} | |
CheckCorridorCenter(width, height, i, (int)Mathf.Max(a.y, b.y), ref ret); | |
} | |
break; | |
} | |
return ret; | |
} | |
//utility | |
void CheckCorridorCenter(int width, int height, int i, int j, ref Vector2Int center) { | |
if (center == new Vector2Int(99999,99999) && (width + height)/2 < i + j) { | |
center = new Vector2Int(i, j); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEngine.Tilemaps; | |
public class LevelManager : MonoBehaviour { | |
//singleton pattern | |
private static LevelManager _instance; | |
public static LevelManager Instance { | |
get { | |
if (_instance == null) { | |
_instance = GameObject.Find("Level Manager").GetComponent<LevelManager>(); | |
} | |
return _instance; | |
} | |
} | |
//public access members | |
public Tilemap tilemap; | |
public bool[,] Collisions { get { return dungeonCollisionData; }} | |
//dungeon stuff | |
MapGenerator mapGenerator; | |
MapEtcher mapEtcher; | |
TileType[,] dungeonTileData = null; //save this, can regenerate the world using this | |
bool[,] dungeonCollisionData = null; | |
//entity management | |
List<Entity> entities = new List<Entity>(); | |
int entityExcecutionTick = 0; | |
//lifecycle methods | |
void Awake() { | |
mapGenerator = GetComponent<MapGenerator>(); | |
mapEtcher = GetComponent<MapEtcher>(); | |
dungeonTileData = mapGenerator.GenerateTileData(); | |
dungeonCollisionData = mapEtcher.EtchTileData(tilemap, dungeonTileData); | |
} | |
void FixedUpdate() { | |
HandleEntityExecution(); | |
} | |
//handlers | |
void HandleEntityExecution() { | |
List<Entity> executedEntities; | |
List<Entity> pendingEntities; | |
do { | |
executedEntities = new List<Entity>(); | |
pendingEntities = new List<Entity>(); | |
foreach(Entity entity in entities) { | |
if (entityExcecutionTick % entity.GetExecutionSpeed() == 0) { | |
if (entity.Execute() == true) { | |
executedEntities.Add(entity); //record executed entities | |
} else { | |
pendingEntities.Add(entity); //record waiting entities | |
} | |
} | |
} | |
//only increment if nobody is waiting for input | |
if (pendingEntities.Count == 0) { | |
entityExcecutionTick++; | |
} | |
} while (executedEntities.Count == 0 && pendingEntities.Count == 0 && entities.Count > 0); | |
Debug.Log(entityExcecutionTick); | |
} | |
//accessors and mutators | |
public void RegisterEntity(Entity entity) { | |
entities.Add(entity); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEngine.Tilemaps; | |
public abstract class MapEtcher : MonoBehaviour { | |
public abstract bool[,] EtchTileData(Tilemap tilemap, TileType[,] tileData); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
public abstract class MapGenerator : MonoBehaviour { | |
public abstract TileType[,] GenerateTileData(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//every type of tile in the game | |
public enum TileType { | |
WALL = 0, EMPTY, ROOM, ENTRY, EXIT | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment