mirror of
https://github.com/Xevion/Paths.git
synced 2025-12-06 07:15:44 -06:00
A* adjacents small optimization, new RoomCarving level generation, extend RandomPlacement to allow 'carving', NodeGrid filled grid factory method, IsEdge & ClearRoom
This commit is contained in:
@@ -43,10 +43,12 @@ namespace Algorithms {
|
|||||||
_closedList.Add(current);
|
_closedList.Add(current);
|
||||||
RecordState();
|
RecordState();
|
||||||
|
|
||||||
List<Node> adjacentNodes = this._nodeGrid.GetAdjacentNodesList(current);
|
Node[] adjacentNodes = this._nodeGrid.GetAdjacentNodesArray(current);
|
||||||
|
if (true) {
|
||||||
|
for (int i = 0; i < adjacentNodes.Length; i++) {
|
||||||
|
Node n = adjacentNodes[i];
|
||||||
|
if (n == null) continue;
|
||||||
|
|
||||||
if (adjacentNodes.Count > 0) {
|
|
||||||
foreach (Node n in adjacentNodes) {
|
|
||||||
if (!_closedList.Contains(n) && n.Walkable) {
|
if (!_closedList.Contains(n) && n.Walkable) {
|
||||||
if (!_openList.Contains(n)) {
|
if (!_openList.Contains(n)) {
|
||||||
n.Parent = current;
|
n.Parent = current;
|
||||||
@@ -58,8 +60,6 @@ namespace Algorithms {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RecordState();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -112,5 +112,27 @@ namespace Algorithms {
|
|||||||
public Node GetRandomNode() {
|
public Node GetRandomNode() {
|
||||||
return Grid[Random.Range(0, Width), Random.Range(0, Height)];
|
return Grid[Random.Range(0, Width), Random.Range(0, Height)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static NodeGrid GetFilledNodeGrid(int width, int height) {
|
||||||
|
var nodeGrid = new NodeGrid(width, height);
|
||||||
|
|
||||||
|
// Set each Node to a Wall
|
||||||
|
for (int x = 0; x < width; x++)
|
||||||
|
for (int y = 0; y < height; y++)
|
||||||
|
nodeGrid.Grid[x, y].Walkable = false;
|
||||||
|
|
||||||
|
return nodeGrid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEdge(Vector2Int position) {
|
||||||
|
return position.x == 0 || position.x == Width - 1 || position.y == 0 || position.y == Height - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearRoom(Rect room) {
|
||||||
|
for (float x = room.xMin; x < room.xMax; x++)
|
||||||
|
for (float y = room.yMin; y < room.yMax; y++) {
|
||||||
|
Grid[(int) x, (int) y].Walkable = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -7,7 +7,7 @@ public class GridState {
|
|||||||
public readonly GridNodeType[,] Grid;
|
public readonly GridNodeType[,] Grid;
|
||||||
public readonly float Time;
|
public readonly float Time;
|
||||||
|
|
||||||
public GridState(NodeGrid grid, List<Node> seen, List<Node> expanded, Vector2Int start,
|
public GridState(NodeGrid grid, IReadOnlyList<Node> seen, IReadOnlyList<Node> expanded, Vector2Int start,
|
||||||
Vector2Int end, Stack<Node> path) {
|
Vector2Int end, Stack<Node> path) {
|
||||||
this.Time = UnityEngine.Time.realtimeSinceStartup;
|
this.Time = UnityEngine.Time.realtimeSinceStartup;
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ namespace LevelGeneration {
|
|||||||
public class RandomPlacement : ILevelGenerator {
|
public class RandomPlacement : ILevelGenerator {
|
||||||
private readonly float _percentFill;
|
private readonly float _percentFill;
|
||||||
private readonly bool _fillTo;
|
private readonly bool _fillTo;
|
||||||
|
private readonly bool _add;
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -15,25 +16,33 @@ namespace LevelGeneration {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="percentFill">The target percentage to fill the graph to.</param>
|
/// <param name="percentFill">The target percentage to fill the graph to.</param>
|
||||||
/// <param name="fillTo">If true, the graph will be filled to the target percentage. If false, it will simply add that percentage.</param>
|
/// <param name="fillTo">If true, the graph will be filled to the target percentage. If false, it will simply add that percentage.</param>
|
||||||
public RandomPlacement(float percentFill, bool fillTo) {
|
/// <param name="add">If false, removes walls instead of adding walls.</param>
|
||||||
|
public RandomPlacement(float percentFill, bool fillTo, bool add) {
|
||||||
_percentFill = percentFill;
|
_percentFill = percentFill;
|
||||||
_fillTo = fillTo;
|
_fillTo = fillTo;
|
||||||
|
_add = add;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NodeGrid Generate(NodeGrid nodeGrid) {
|
public NodeGrid Generate(NodeGrid nodeGrid) {
|
||||||
// Calculate the number of walls to place
|
// Calculate the number of walls to place
|
||||||
int wallsLeft = (int) Math.Round(nodeGrid.CellCount * _percentFill);
|
int wallsLeft = (int) Math.Round(nodeGrid.CellCount * _percentFill);
|
||||||
if (_fillTo) wallsLeft -= nodeGrid.Walls().Count();
|
if (_fillTo) wallsLeft -= (_add ? nodeGrid.Walls() : nodeGrid.Empty()).Count();
|
||||||
wallsLeft = Mathf.Clamp(wallsLeft, 0, nodeGrid.CellCount);
|
wallsLeft = Mathf.Clamp(wallsLeft, 0, nodeGrid.CellCount);
|
||||||
|
|
||||||
// Begin adding walls
|
// Begin adding walls
|
||||||
while (wallsLeft > 0) {
|
while (wallsLeft > 0) {
|
||||||
// Grab a node, skip if already a wall
|
// Grab a node, skip if already a wall
|
||||||
Node node = nodeGrid.GetRandomNode();
|
Node node = nodeGrid.GetRandomNode();
|
||||||
if (!node.Walkable) continue;
|
|
||||||
|
|
||||||
// Node is empty, set to a wall
|
if (_add) {
|
||||||
node.Walkable = false;
|
if (!node.Walkable) continue;
|
||||||
|
node.Walkable = false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (node.Walkable) continue;
|
||||||
|
node.Walkable = true;
|
||||||
|
}
|
||||||
|
|
||||||
wallsLeft--;
|
wallsLeft--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
61
Paths/Assets/Scripts/LevelGeneration/RoomCarve.cs
Normal file
61
Paths/Assets/Scripts/LevelGeneration/RoomCarve.cs
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using Algorithms;
|
||||||
|
using UnityEngine;
|
||||||
|
using Random = UnityEngine.Random;
|
||||||
|
|
||||||
|
namespace LevelGeneration {
|
||||||
|
public class RoomCarve : ILevelGenerator {
|
||||||
|
private Vector2Int _roomRange;
|
||||||
|
private Vector2Int _roomSizeRange;
|
||||||
|
private int _maxAttempts;
|
||||||
|
|
||||||
|
public RoomCarve(Vector2Int roomRange, Vector2Int roomSizeRange, int maxAttempts) {
|
||||||
|
_roomRange = roomRange;
|
||||||
|
_roomSizeRange = roomSizeRange;
|
||||||
|
_maxAttempts = maxAttempts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public NodeGrid Generate(NodeGrid nodeGrid) {
|
||||||
|
int roomCount = Random.Range(_roomRange.x, _roomRange.y);
|
||||||
|
int attempts = 0;
|
||||||
|
|
||||||
|
// TODO: Update to latest Unity 2020 update to gain access to RectInt.Overlaps (?)
|
||||||
|
|
||||||
|
// Generate rooms
|
||||||
|
List<Rect> rooms = new List<Rect>();
|
||||||
|
do {
|
||||||
|
// Quit after too many attempts failed
|
||||||
|
if (attempts > _maxAttempts)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Get a position and check that it's not on the edge of the grid
|
||||||
|
Vector2Int pos = nodeGrid.RandomPosition();
|
||||||
|
if (nodeGrid.IsEdge(pos)) continue;
|
||||||
|
|
||||||
|
|
||||||
|
var size = new Vector2Int(
|
||||||
|
Math.Min(Random.Range(_roomSizeRange.x, _roomSizeRange.y), nodeGrid.Width - pos.x),
|
||||||
|
Math.Min(Random.Range(_roomSizeRange.x, _roomSizeRange.y), nodeGrid.Height - pos.y)
|
||||||
|
);
|
||||||
|
var newRoom = new Rect(pos, size);
|
||||||
|
|
||||||
|
// Check that it doesn't overlap with any of the previous rooms
|
||||||
|
bool skip = rooms.Any(room => room.Overlaps(newRoom));
|
||||||
|
|
||||||
|
// If it didn't,
|
||||||
|
if (!skip)
|
||||||
|
rooms.Add(newRoom);
|
||||||
|
else
|
||||||
|
attempts++;
|
||||||
|
} while (rooms.Count < roomCount);
|
||||||
|
|
||||||
|
// Set all nodes within rooms
|
||||||
|
foreach (Rect rect in rooms)
|
||||||
|
nodeGrid.ClearRoom(rect);
|
||||||
|
|
||||||
|
return nodeGrid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
3
Paths/Assets/Scripts/LevelGeneration/RoomCarve.cs.meta
Normal file
3
Paths/Assets/Scripts/LevelGeneration/RoomCarve.cs.meta
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 8b95ad3163134f988aa423b183d65c1d
|
||||||
|
timeCreated: 1605336649
|
||||||
Reference in New Issue
Block a user