-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathBSP.js
More file actions
164 lines (145 loc) · 6.41 KB
/
BSP.js
File metadata and controls
164 lines (145 loc) · 6.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
function createHall(lChild, rChild, hallways) {
// Connects two rooms with hallways in a straight line or a pair of lines.
// Gets two random points, one in each room
var point1 = [randint(lChild.left , lChild.right),
randint(lChild.top, lChild.bottom)];
var point2 = [randint(rChild.left , rChild.right),
randint(rChild.top , rChild.bottom)];
// The difference between the positions of both points
w = point2[0] - point1[0];
h = point2[1] - point1[1];
if(w < 0) {
// point2 is at the left of point1
if(h < 0) {
// point2 is bellow point1
if(Math.random() < 0.5) {
hallways.push( new Rect(point2[0], point1[1], Math.abs(w), 1) );
hallways.push( new Rect(point2[0], point2[1], 1, Math.abs(h)) );
} else {
hallways.push( new Rect(point2[0], point2[1], Math.abs(w), 1) );
hallways.push( new Rect(point1[0], point2[1], 1, Math.abs(h)) );
}
} else if (h > 0) {
// point2 is above point 1
if(Math.random() < 0.5) {
hallways.push( new Rect(point2[0], point1[1], Math.abs(w), 1) );
hallways.push( new Rect(point2[0], point1[1], 1, Math.abs(h)) );
} else {
// The +1 here fixes a bug where the corridors would not connect
hallways.push( new Rect(point2[0], point2[1], Math.abs(w), 1) );
hallways.push( new Rect(point1[0], point1[1], 1, Math.abs(h)+1) );
}
} else {
// points are vertically aligned
hallways.push( new Rect(point2[0], point2[1], Math.abs(w), 1) );
}
} else if (w > 0) {
// point2 is on the right of point1
if(h < 0) {
// point2 is bellow point1
if(Math.random() < 0.5) {
hallways.push( new Rect(point1[0], point2[1], Math.abs(w), 1) );
hallways.push( new Rect(point1[0], point2[1], 1, Math.abs(h)) );
} else {
// The +1 here fixes a bug where the corridors would not connect
hallways.push( new Rect(point1[0], point1[1], Math.abs(w) +1, 1) );
hallways.push( new Rect(point2[0], point2[1], 1, Math.abs(h)) );
}
} else if (h > 0) {
// point2 is above point 1
if(Math.random() < 0.5) {
hallways.push( new Rect(point1[0], point1[1], Math.abs(w), 1) );
hallways.push( new Rect(point2[0], point1[1], 1, Math.abs(h)) );
} else {
hallways.push( new Rect(point1[0], point2[1], Math.abs(w), 1) );
hallways.push( new Rect(point1[0], point1[1], 1, Math.abs(h)) );
}
} else {
// points are vertically aligned
hallways.push( new Rect(point1[0], point1[1], Math.abs(w), 1) );
}
} else {
// points are horizontally aligned
if (h < 0) {
// point2 is above point 1
hallways.push( new Rect(point2[0], point2[1], 1, Math.abs(h)) );
} else if (h > 0) {
hallways.push( new Rect(point1[0], point1[1], 1, Math.abs(h)) );
}
}
}
class Leaf extends Rect{
constructor(x, y, width, height) {
super(x, y, width, height);
this.lChild = null;
this.rChild = null;
this.room = null;
}
split(minLeafSize=6) {
if(this.lChild && this.rChild) { return false; }
var splitH;
if(this.width > this.height && this.width / this.height >= 1.25) {
// If height is 25% greater than width, split horizontally
splitH = false;
} else if (this.height > this.width && this.height / this.width >= 1.25) {
// If width is 25% greater than height, split vertically
splitH = true;
} else {
// Otherwise, chose a random direction
splitH = Math.random() > 0.5;
}
// maximum dimension (height or width)
var maxDimension = (splitH ? this.height : this.width)
maxDimension -= minLeafSize;
// Checks if the area is too small to split.
if(maxDimension <= minLeafSize) { return false; }
// point to split based on the chosen direction
var cut = randint(minLeafSize, maxDimension);
if(splitH) {
this.lChild = new Leaf(this.x, this.y, this.width, cut);
this.rChild = new Leaf(this.x, this.y + cut,
this.width, this.height - cut);
} else {
this.lChild = new Leaf(this.x, this.y, cut, this.height);
this.rChild = new Leaf(this.x + cut, this.y,
this.width - cut, this.height);
}
return true;
}
createRooms(hallways, rooms) {
// Create rooms and hallways for this leaf and all children.
// hallways must be an array to store the hallways
if(this.lChild || this.rChild) {
if(this.lChild) { this.lChild.createRooms(hallways, rooms); }
if(this.rChild) { this.rChild.createRooms(hallways, rooms); }
if(this.lChild && this.rChild) {
createHall(this.lChild.findRoom(), this.rChild.findRoom(), hallways); }
} else {
// This leaf has no children, let's make a room on it.
var roomSize = [ randint(3, this.width - 2), randint(3, this.height - 2) ];
// Place the room with an offset (so adjacent rooms do not touch)
var roomPos = [ randint(1, this.width - roomSize[0] - 1),
randint(1, this.height - roomSize[1] - 1) ];
this.room = new Rect(this.x + roomPos[0], this.y + roomPos[1],
roomSize[0], roomSize[1]);
rooms.push(this.room);
}
}
findRoom() {
// Iterates over the children of this leaf until a room is found
if(this.room) { return this.room;
} else {
var lRoom = null,
rRoom = null;
if(this.lChild) { lRoom = this.lChild.findRoom(); }
if(this.rChild) { rRoom = this.rChild.findRoom(); }
if(!lRoom && !rRoom) {
return null;
}
else if (!rRoom) { return lRoom; }
else if (!lRoom) { return rRoom; }
else if (Math.random() > 0.5) { return lRoom; }
else { return rRoom; }
}
}
}