-
-
Notifications
You must be signed in to change notification settings - Fork 4
/
camera.js
128 lines (100 loc) · 3.36 KB
/
camera.js
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
/*
*
* Camera
*
* options: {
* map: map,
* follow: player,
* followPoint: { x: game.width / 2, y: game.height / 2 },
* cameraStartPosition: { x: 0, y: 0 },
* viewport: { width: 25, height: 25 }
* }
*
*/
module.exports = Camera;
function Camera(options){
var self = this;
this.map = options.map;
this.game = options.game;
this.following = options.follow;
this.following.camera = this;
this.followPoint = {
x: options.followPoint.x || null,
y: options.followPoint.y || null
};
this.position = options.cameraStartPosition || { x: 0, y: 0 };
this.deadZone = options.deadZone || { x: options.viewport.width / 2, y: options.viewport.height / 2 };
this.viewport = options.viewport;
this.viewportRect = new Rectangle(this.position.x, this.position.y, this.viewport.width, this.viewport.height);
this.worldRect = new Rectangle(this.position.x, this.position.y, this.map.width, this.map.height);
this.game.on('update', function(){
self.update();
})
}
Camera.prototype.update = function(){
var following = this.following;
var followPoint = this.followPoint;
if (following != null){
if (followPoint.x !== null){
if(following.position.x - this.position.x + this.deadZone.x > this.viewport.width){
this.position.x = following.position.x - (this.viewport.width - this.deadZone.x);
}
else if(following.position.x - this.deadZone.x < this.position.x){
this.position.x = following.position.x - this.deadZone.x;
}
}
if (followPoint.y !== null){
if(following.position.y - this.position.y + this.deadZone.y > this.viewport.height){
this.position.y = following.position.y - (this.viewport.height - this.deadZone.y);
}
else if(following.position.y - this.deadZone.y < this.position.y) {
this.position.y = following.position.y - this.deadZone.y;
}
}
}
this.viewportRect.set(this.position.x, this.position.y, this.viewport.width, this.viewport.height);
if(!this.viewportRect.within(this.worldRect)){
if(this.viewportRect.left < this.worldRect.left){
this.position.x = this.worldRect.left;
}
if(this.viewportRect.top < this.worldRect.top){
this.position.y = this.worldRect.top;
}
if(this.viewportRect.right > this.worldRect.right){
this.position.x = this.worldRect.right - this.viewport.width;
}
if(this.viewportRect.bottom > this.worldRect.bottom){
this.position.y = this.worldRect.bottom - this.viewport.height;
}
}
}
function Rectangle(left, top, width, height){
this.left = left || 0;
this.top = top || 0;
this.right = left + width || 0;
this.bottom = top + height || 0;
}
Rectangle.prototype.set = function(left, top, width, height){
this.left = left;
this.top = top;
this.width = width || this.width;
this.height = height || this.height
this.right = this.left + this.width;
this.bottom = this.top + this.height;
}
Rectangle.prototype.within = function(rectangle) {
return (
rectangle.left <= this.left &&
rectangle.right >= this.right &&
rectangle.top <= this.top &&
rectangle.bottom >= this.bottom
);
}
Rectangle.prototype.overlaps = function(rectangle) {
return (
this.left < rectangle.right &&
this.right > rectangle.left &&
this.top < rectangle.bottom &&
this.bottom > rectangle.top
);
}