//Build a room using only the center of the room private void buildRoom(p2D center) { Room room = new Room(center, roomRadius); int minX = center.getX() - roomRadius; int maxX = center.getX() + roomRadius + 1; int minY = center.getY() - roomRadius; int maxY = center.getY() + roomRadius + 1; for (int x = minX; x < maxX; x++) { for (int y = minY; y < maxY; y++) { dungeonMaze [x, y] = 1; } } this.rooms.Add(room); //I keep a list of all the rooms for game purposes //Add the doorways of this room to the list //The doors are on all 4 walls in the center this.doorways.Add(new p2D(center.getX() + roomRadius + 1, center.getY())); this.doorways.Add(new p2D(center.getX() - roomRadius - 1, center.getY())); this.doorways.Add(new p2D(center.getX(), center.getY() + roomRadius + 1)); this.doorways.Add(new p2D(center.getX(), center.getY() - roomRadius - 1)); } //buildRoom
} //pickdoorways //This function determines what the door is currently connected to public string findPrevious(KeyValuePair <p2D, int> doorway) { p2D door = doorway.Key; //Door coordinate int direction = doorway.Value; //Door direction p2D check1 = new p2D(width / 2, height / 2); p2D check2 = new p2D(width / 2, height / 2); p2D temp = p2D.translateDirectional2(door, 1, (direction + 2) % 4); check1 = p2D.translateDirectional2(temp, 1, (direction + 1) % 4); check2 = p2D.translateDirectional2(temp, 1, (direction + 1) % 4); /** * Check 1 and check 2 are now (x being the door coordinate, > the direction) * * 100 * 0X> * 200 */ //Check weither at least one of them is occupied; then it's a room //(or you at least won't be able to place a room next to it) if (dungeonMaze[check1.getX(), check1.getY()] == 1 || dungeonMaze[check2.getX(), check2.getY()] == 1) { return("room"); } else { return("corridor"); } } //findprevious
public static p2D translateDirectional2(p2D coord, int delta, int direction) { p2D translated = new p2D(int.MaxValue, int.MaxValue); translated.setP(coord.X, coord.Y); switch (direction) { case 0: translated.setY(coord.Y + delta); break; case 1: translated.setX(coord.X + delta); break; case 2: translated.setY(coord.Y - delta); break; case 3: translated.setX(coord.X - delta); break; default: //Debug.Log(direction + " " + coord.X + ", " + coord.Y + " Not translated, max,max returned"); break; } return(translated); }
} //lineFree //Checks available space of a recangle, plus a row of space around it private bool rectangleFree(p2D coord, int direction, int rectangleWidthRadius, int rectangleLength) { int searchWidth = rectangleWidthRadius + 1; int x = coord.getX(); int y = coord.getY(); switch (direction) { case 0: case 2: //Cases whem you're on a horizontal wall int minX = x - searchWidth; int maxX = x + searchWidth; //Make sure you're looking within the available space if (minX <= 0 || maxX >= width - 1) { return(false); } //Check all lines starting at the wall for (int i = minX; i <= maxX; i++) { if (!lineFree(new p2D(i, y), direction, rectangleLength)) { return(false); } } break; case 1: case 3: //Cases when you're on a vertical wall int minY = y - searchWidth; int maxY = y + searchWidth; //Make sure you're looking within the available space if (minY <= 0 || maxY >= height - 1) { return(false); } //Check all lines starting at the wall for (int i = minY; i <= maxY; i++) { if (!lineFree(new p2D(x, i), direction, rectangleLength)) { return(false); } } break; default: //Debug.Log("Incorrect direction - not checked;"); return(false); } return(true); } //rectangleFree
} //getSurrounding //Find the direction that the chosen door is facing, by comparing its neighbours public int findDirection(p2D coord) { int[] surrounding = getSurrounding(coord); int direction = -1; //The direction is one of the two opposing directions that differ //So 0 and 2 are compared and 1 and 3 are //Then the direction is chosen of the two that has value 0 /** * 000 * 121 The case for a room-door (2 is the door) * ` 111 * * 000 * 020 The case for a corridor-door * 010 * * Other cases it will have trouble with recognizing - there we try a random direction */ if (surrounding [1] == surrounding [3] && surrounding[1] == 0) { if (surrounding [0] == 0 && surrounding[2] == 1) { direction = 0; //North } else if (surrounding [2] == 0 && surrounding[0] == 1) { direction = 2; //South } } else if (surrounding [0] == surrounding [2] && surrounding[0] == 0) { if (surrounding [1] == 0 && surrounding[3] == 1) { direction = 1; //East } else if (surrounding [3] == 0 && surrounding[1] == 1) { direction = 3; //West } } else if (surrounding[1] == surrounding[3] && surrounding[0] == surrounding[2] && surrounding[0] != surrounding[1]) { //System.err.println("Shortcorridor found"); this.corridorLength = 0; return((surrounding[1] == 1) ? 1 : 0); } else { //Catch if anything goes wrong: then assign a random direction. direction = Random.Range(0, 4); } return(direction); } //findDirection
public Corridor(p2D start, p2D end, int direction) { this.start = start; this.end = end; this.direction = direction; doorways = new List <p2D> (); assignDoorways(); }
public Corridor(int startX, int startY, int endX, int endY, int direction) { this.start = new p2D(startX, startY); this.end = new p2D(endX, endY); this.direction = direction; doorways = new List <p2D> (); assignDoorways(); }
public Room(p2D c, int radius) { this.center = c; this.radius = radius; this.doorways = new List <p2D> (); this.directiondoors = new int[] { 0, 0, 0, 0 }; assignDoorways(); }
//Move over the given coordinate so that the center build method can be used private void buildRoomDirectional(p2D start, int direction) { //The buildRoom function uses the room center, so we search for that place //using the door coordinate & direction p2D translated = p2D.translateDirectional2(start, roomRadius + 1, direction); buildRoom(translated); }
public bool Equals(p2D other) { if ((object)other == null) { return(false); } return(other.getX() == this.X && other.getY() == this.Y); }
} //rectangleFree //Sees if there's space for a room private bool roomFree(p2D coord, int direction) { //Needs to translate so that it doesn't start at the door itself, but one step further //Otherwise it will say false anyway p2D translated = p2D.translateDirectional2(coord, 1, direction); return(rectangleFree(translated, direction, roomRadius, (roomRadius * 2) + 1)); }
void populatePuzzles() { int random = 0; //Make beginningRoom random = Random.Range(0, puzzleCenters.Count); p2D beginning = puzzleCenters [random]; startpoint = new Vector3(beginning.getX() * 6 + 1, 0, beginning.getY() * 6 + 1); startpoint += new Vector3(-4f, 0, -4f); Instantiate(BeginningRoom, startpoint, Quaternion.identity, Dungeon.transform); //Remove from list List <p2D> temp1 = new List <p2D> (); temp1.Add(beginning); p2D.myRemove(puzzleCenters, temp1); //Make endRoom random = Random.Range(0, puzzleCenters.Count); p2D ending = puzzleCenters [random]; endpoint = new Vector3(ending.getX() * 6 + 1, 0, ending.getY() * 6 + 1); endpoint += new Vector3(-4f, 0, -4f); Instantiate(EndingRoom, endpoint, Quaternion.Euler(new Vector3(0, Random.Range(0, 4) * 90, 0)), Dungeon.transform); //Remove from list List <p2D> temp2 = new List <p2D> (); temp2.Add(ending); p2D.myRemove(puzzleCenters, temp2); sbPuzzles.Append("\n\nPuzzles in this dungeon: "); foreach (p2D center in puzzleCenters) { Vector3 convCenter = new Vector3(center.getX() * 6 + 1, 0, center.getY() * 6 + 1); convCenter += new Vector3(-4f, 0, -4f); int x = DeterminePuzzleRoom(); GameObject thispuzzle = Instantiate(puzzleRooms [x], convCenter, Quaternion.identity, Dungeon.transform) as GameObject; GameObject thesedoors = Instantiate(PuzzleDoors, convCenter, Quaternion.identity, thispuzzle.transform) as GameObject; if (thispuzzle.GetComponent <myLever> () != null) { thispuzzle.GetComponent <myLever> ().Reread(); } thesedoors.GetComponent <puzzleDoors> ().RoomType = thispuzzle.name; buildDoors(center, convCenter, thesedoors); Instantiate(PuzzleMist, convCenter, Quaternion.identity, thispuzzle.transform); } sbPuzzles.Append("\n\n"); Debug.Log(sbPuzzles.ToString()); }
public int[] roomDoorLocations(Room room) { int[] locations = new int[4] { 0, 0, 0, 0 }; for (int i = 0; i < room.getDoorways().Count; i++) { p2D door = room.getDoorways()[i]; locations[i] = maze[door.getX(), door.getY()]; } return(locations); }
//Sees if there's space for a corridor private bool corridorFree(p2D coord, int direction, string from) { p2D translated = coord; //Needs to translate so that it doesn't start at the door itself, but one step further //Otherwise it will say false anyway if (true || from.Equals("room")) { translated = p2D.translateDirectional2(coord, 1, direction); } return(rectangleFree(translated, direction, 1, corridorLength - loopsAllowedInt)); }
public override bool Equals(System.Object other) { if (other == null) { return(false); } p2D that = (p2D)other; if (that == null) { return(false); } return(that.X == this.X && that.Y == this.Y); }
public static int myIndexOf(List <p2D> list, p2D point) { int i = 0; foreach (p2D item in list) { if (point.Equals(item)) { return(i); } i++; } return(-1); }
} //buildRoom //Builds a corridor private void buildCorridor(p2D start, int direction) { //The start and end coordinates are saved p2D end = new p2D(0, 0); int x = start.getX(); int y = start.getY(); switch (direction) { case 1: //East for (int i = x; i <= x + corridorLength; i++) { dungeonMaze[i, y] = 1; end.setP(i, y); } break; case 3: //West for (int i = x; i >= x - corridorLength; i--) { dungeonMaze[i, y] = 1; end.setP(i, y); } break; case 0: //North for (int i = y; i <= y + corridorLength; i++) { dungeonMaze[x, i] = 1; end.setP(x, i); } break; case 2: //South for (int i = y; i >= y - corridorLength; i--) { dungeonMaze[x, i] = 1; end.setP(x, i); } break; default: //System.err.println("BuildCorridor end 0,0 added"); break; } //The start and end are added to the list or doorwayss doorways.Add(end); doorways.Add(start); } //buildCorridor
} //findDirection //Picks a doorway from the current list of doorways and finds its direction private KeyValuePair <p2D, int> pickDoorway() { //Clean up the list - only look at doors that are not interconnected yet List <p2D> chooseFrom = noDupes(doorways); //chooseFrom.Add (new p2D (0, 0)); //doorways.Add (new p2D (0, 0)); //Pick a random number, smaller than the size of the array to choose from int number = Random.Range(0, chooseFrom.Count); //Save the door at the chosen index //if (number < 1) { Debug.Log("empty nodupes list"); } p2D choice = chooseFrom[number]; //Find out its direction int direction = findDirection(choice); return(new KeyValuePair <p2D, int> (choice, direction)); } //pickdoorways
void buildDoors(p2D center, Vector3 convCenter, GameObject thesedoors) { int[] surrounding = null; foreach (Room myroom in puzzleRoomsDG) { if (myroom.getCenter().Equals(center)) { surrounding = myroom.getDirectiondoors(); break; } } // Debug.Log (surrounding[0] + "." + surrounding[1] + "." + surrounding[2] + "." + surrounding[3] + " " + center); for (int i = 0; i < 4; i++) { if (surrounding [i] == 1) { Instantiate(WoodenDoors, convCenter, Quaternion.Euler(0, i * 90, 0), thesedoors.transform); } } }
} //chooseBuild //This function looks at the entourage of a coordinate, and outputs an array //with the maze values at those coordinates in N-E-S-W order public int[] getSurrounding(p2D point) { int x = point.getX(); int y = point.getY(); //If you are within the boundaries of the maze, do the normal thing if (x > 0 && y > 0 && x < width - 1 && y < height - 1) { int[] array = { dungeonMaze [x, y + 1], //North dungeonMaze [x + 1, y], //East dungeonMaze [x, y - 1], //South dungeonMaze [x - 1, y] //West }; return(array); } //As a catchnet - returning all 4 as built coordinates else { return(new int[] { 1, 1, 1, 1 }); } } //getSurrounding
public static bool myContains(List <p2D> list, p2D point) { return(myIndexOf(list, point) != -1); }
public void removeDoorway(p2D door) { this.doorways.Remove(door); }
} //noDupes //Checks available space from selected point private bool lineFree(p2D coord, int direction, int lineLength) { int x = coord.getX(); int y = coord.getY(); int searchLength = lineLength; switch (direction) { case 1: //East //If the coordinate is not within the available space; stop the procedure //This happens for all four cases if (x + searchLength >= width - 2) { return(false); } for (int i = x; i <= x + searchLength; i++) { if (dungeonMaze [i, y] == 1) { return(false); } } break; case 3: //West if (x - searchLength <= 1) { return(false); } for (int i = x; i >= x - searchLength; i--) { if (dungeonMaze[i, y] == 1) { return(false); } } break; case 0: //North if (y + searchLength >= height - 2) { return(false); } for (int i = y; i <= y + searchLength; i++) { if (dungeonMaze[x, i] == 1) { return(false); } } break; case 2: //South if (y - searchLength <= 1) { return(false); } for (int i = y; i >= y - searchLength; i--) { if (dungeonMaze[x, i] == 1) { return(false); } } break; default: //Debug.Log("Linefree didn't receive a correct direction"); break; } return(true); } //lineFree
//Deze functie is nodig voor in Unity, maar niet in Java. //Ik laat hem staan om later te kunnen heractiveren //Build the first room /* * public void Start() { * DungeonGenerator dungeon = new DungeonGenerator(40,25,1,2,3000,6,13,6); * Debug.Log ("done = " + dungeon.getRooms ().Count); * Debug.Log (DungeonGenerator.noDupes(dungeon.doorways).ToString()); * Debug.Log (dungeonMaze); * } */ //Initialize area with no rooms nor corridors public DungeonGenerator(int width, int height, int roomRadius, int maxCorridorLength, int mseconds, int minAmountOfRooms, int maxAmountOfRooms, int chanceOfRoom) { this.width = width; this.height = height; this.dungeonMaze = new int[width, height]; this.doorways = new List <p2D> (); this.rooms = new List <Room> (); this.allRoomCoords = new List <p2D> (); this.roomCenters = new List <p2D> (); this.maxCorridorLength = maxCorridorLength; this.roomRadius = roomRadius; this.minAmountOfRooms = minAmountOfRooms; this.maxAmountOfRooms = maxAmountOfRooms; this.chanceRoom = chanceOfRoom; this.mseconds = mseconds; this.loopsAllowed = false; this.loopsAllowedInt = (loopsAllowed) ? 1:0; this.done = false; //Initializeer het dungeonMaze array met nullen (dicht) en enen (open) langs de rand //De enen zitten langs de rand omdat het algoritme niet kan bouwen waar al gebouwd is //Zo blijft hij bij de randen vandaan for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { if (x == 0 || x == width - 1 || y == 0 || y == height - 1) { dungeonMaze[x, y] = 1; } else { dungeonMaze [x, y] = 0; } } } //Begin met het bouwen van een room in het centrum van het vlak p2D center = new p2D(width / 2, height / 2); buildRoom(center); //Begin met genereren en geef terug in done of het gelukt is binnen de gegeven tijd. generate(); finish(); //This function will tie up the ends of the maze //By adding rooms at the loose ends if possible Room.setMaze(dungeonMaze); foreach (Room room in rooms) { room.goRound(); } this.done = (rooms.Count >= minAmountOfRooms); } //constructor