summaryrefslogtreecommitdiff
path: root/assets/javascripts/rectangles/models/room.js
blob: 4d83d565b31d9bb71411ebd004bee9f3851d1171 (plain)
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
window.room = (function(){

	var room = function(opt){
		this.id = opt.id || clipper.rooms.length
		this.rect = opt.rect
		this.regions = []

		this.height = opt.height || 200
		this.focused = false
		
		this.$walls = $([])
		this.$floor = $([])
		this.$ceiling = $([])
	}
	
	room.prototype.toString = function(){
		return this.rect.toString()
	}

	room.prototype.reset = function(){
		var copy = this.rect.clone()
		copy.id = this.id
		copy.sides = FRONT | BACK | LEFT | RIGHT
		this.regions = [ copy ]

		this.intersects = []
		this.constructed = false
		
		this.$walls = $([])
		this.$floor = $([])
		this.$ceiling = $([])
	}

	room.prototype.clipTo = function(r){
		// for each of this rect's regions split the region if necessary
		var regions = this.regions
		var splits
		for (var i = 0, len = regions.length; i < len; i++) {
			if (regions[i] && regions[i].intersects(r)) {
				splits = regions[i].split(r)
				regions = regions.concat(splits)
				regions[i] = null
			}
		}
		this.regions = regions
	}
	
	room.prototype.collides = function(x,y){
		var collision = 0, wall_collision, contains_x, contains_y
		this.regions.forEach(function(r){
			if (! r.sides) return
			
			wall_collision = 0

			if ((r.sides & FRONT) && y < r.y.a) {
				wall_collision |= FRONT
			}
			if ((r.sides & BACK) && r.y.b < y) {
				wall_collision |= BACK
			}
			if ((r.sides & LEFT) && x < r.x.a) {
				wall_collision |= LEFT
			}
			if ((r.sides & RIGHT) && r.x.b < x) {
				wall_collision |= RIGHT
			}
			if (! wall_collision) return

			contains_y = r.y.contains(y)
			contains_x = r.x.contains(x)
			
			if (contains_x) {
				collision |= wall_collision & FRONT_BACK
			}
			else if (contains_y) {
				collision |= wall_collision & LEFT_RIGHT
			}
			else if (bitcount(wall_collision) > 1) {
 				collision |= wall_collision
			}
		})
		return collision
	}

	return room

})()

function bitcount(v) {
  v = v - ((v >>> 1) & 0x55555555);
  v = (v & 0x33333333) + ((v >>> 2) & 0x33333333);
  return ((v + (v >>> 4) & 0xF0F0F0F) * 0x1010101) >>> 24;
}