@litecanvas/utils 0.10.1 → 0.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/actor.js +20 -4
- package/dist/actor.min.js +1 -1
- package/dist/all.js +117 -18
- package/dist/all.min.js +2 -2
- package/dist/camera.js +97 -14
- package/dist/camera.min.js +1 -1
- package/package.json +1 -1
- package/src/actor/index.js +22 -5
- package/src/camera/README.md +24 -4
- package/src/camera/index.js +115 -17
package/dist/actor.js
CHANGED
|
@@ -122,7 +122,7 @@
|
|
|
122
122
|
* @returns {number}
|
|
123
123
|
*/
|
|
124
124
|
get width() {
|
|
125
|
-
return this.sprite.width * this._s.
|
|
125
|
+
return this.sprite.width * this._s.x;
|
|
126
126
|
}
|
|
127
127
|
/**
|
|
128
128
|
* @returns {number}
|
|
@@ -130,6 +130,16 @@
|
|
|
130
130
|
get height() {
|
|
131
131
|
return this.sprite.height * this._s.y;
|
|
132
132
|
}
|
|
133
|
+
/**
|
|
134
|
+
* @returns {number[]}
|
|
135
|
+
*/
|
|
136
|
+
getBounds(scaled = true) {
|
|
137
|
+
const w = this.sprite.width * (scaled ? this._s.x : 1);
|
|
138
|
+
const h = this.sprite.height * (scaled ? this._s.y : 1);
|
|
139
|
+
const x = this.pos.x - w * this.anchor.x;
|
|
140
|
+
const y = this.pos.y - h * this.anchor.y;
|
|
141
|
+
return [x, y, w, h];
|
|
142
|
+
}
|
|
133
143
|
/**
|
|
134
144
|
* @retuns {Vector}
|
|
135
145
|
*/
|
|
@@ -145,9 +155,7 @@
|
|
|
145
155
|
if (this.hidden || this.opacity <= 0) return;
|
|
146
156
|
litecanvas.push();
|
|
147
157
|
this.transform(litecanvas);
|
|
148
|
-
|
|
149
|
-
const anchorY = this.sprite.height * this.anchor.y;
|
|
150
|
-
litecanvas.image(-anchorX, -anchorY, this.sprite);
|
|
158
|
+
this.drawImage(litecanvas);
|
|
151
159
|
litecanvas.pop();
|
|
152
160
|
}
|
|
153
161
|
/**
|
|
@@ -157,7 +165,15 @@
|
|
|
157
165
|
litecanvas.translate(this.pos.x, this.pos.y);
|
|
158
166
|
litecanvas.rotate(this.angle);
|
|
159
167
|
litecanvas.scale(this._s.x, this._s.y);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* @param {LitecanvasInstance} litecanvas
|
|
171
|
+
*/
|
|
172
|
+
drawImage(litecanvas) {
|
|
173
|
+
const anchorX = this.sprite.width * this.anchor.x;
|
|
174
|
+
const anchorY = this.sprite.height * this.anchor.y;
|
|
160
175
|
litecanvas.alpha(this.opacity);
|
|
176
|
+
litecanvas.image(-anchorX, -anchorY, this.sprite);
|
|
161
177
|
}
|
|
162
178
|
};
|
|
163
179
|
|
package/dist/actor.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var
|
|
1
|
+
(()=>{var h=Object.defineProperty;var u=(e,t)=>{for(var o in t)h(e,o,{get:t[o],enumerable:!0})};globalThis.utils=globalThis.utils||{};globalThis.utils.global=()=>{for(let e in globalThis.utils)e!=="global"&&(globalThis[e]=globalThis.utils[e])};var a={};u(a,{ANCHOR_BOT_LEFT:()=>g,ANCHOR_BOT_RIGHT:()=>y,ANCHOR_CENTER:()=>d,ANCHOR_TOP_LEFT:()=>l,ANCHOR_TOP_RIGHT:()=>x,Actor:()=>i});var n=class{x;y;constructor(t=0,o=t){this.x=t,this.y=o}toString(){return`Vector (${this.x}, ${this.y})`}},s=(e=0,t=e)=>new n(e,t);var c=e=>s(e.x,e.y);var d=s(.5,.5),l=s(0,0),x=s(1,0),g=s(0,1),y=s(1,1),i=class{sprite;pos;_o;_s;angle=0;opacity=1;hidden=!1;constructor(t,o,r=l){this.sprite=t,this.pos=o||s(0),this._o=c(r),this._s=s(1,1)}set x(t){this.pos.x=t}get x(){return this.pos.x}set y(t){this.pos.y=t}get y(){return this.pos.y}set anchor(t){this._o.x=t.x,this._o.y=t.y}get anchor(){return this._o}get width(){return this.sprite.width*this._s.x}get height(){return this.sprite.height*this._s.y}getBounds(t=!0){let o=this.sprite.width*(t?this._s.x:1),r=this.sprite.height*(t?this._s.y:1),f=this.pos.x-o*this.anchor.x,p=this.pos.y-r*this.anchor.y;return[f,p,o,r]}get scale(){return this._s}draw(t=globalThis){this.hidden||this.opacity<=0||(t.push(),this.transform(t),this.drawImage(t),t.pop())}transform(t){t.translate(this.pos.x,this.pos.y),t.rotate(this.angle),t.scale(this._s.x,this._s.y)}drawImage(t){let o=this.sprite.width*this.anchor.x,r=this.sprite.height*this.anchor.y;t.alpha(this.opacity),t.image(-o,-r,this.sprite)}};globalThis.utils=Object.assign(globalThis.utils||{},a);})();
|
package/dist/all.js
CHANGED
|
@@ -119,10 +119,14 @@
|
|
|
119
119
|
var Camera = class {
|
|
120
120
|
/** @type {LitecanvasInstance} */
|
|
121
121
|
_engine = null;
|
|
122
|
-
/** @type {number} */
|
|
122
|
+
/** @type {number} camera center X */
|
|
123
123
|
x = 0;
|
|
124
|
-
/** @type {number} */
|
|
124
|
+
/** @type {number} camera center Y */
|
|
125
125
|
y = 0;
|
|
126
|
+
/** @type {number} offset X */
|
|
127
|
+
ox = 0;
|
|
128
|
+
/** @type {number} offset Y*/
|
|
129
|
+
oy = 0;
|
|
126
130
|
/** @type {number} */
|
|
127
131
|
width = 0;
|
|
128
132
|
/** @type {number} */
|
|
@@ -139,27 +143,35 @@
|
|
|
139
143
|
/**
|
|
140
144
|
* @param {LitecanvasInstance} engine
|
|
141
145
|
*/
|
|
142
|
-
constructor(engine = null) {
|
|
143
|
-
|
|
144
|
-
this.
|
|
145
|
-
this.
|
|
146
|
+
constructor(engine = null, ox = 0, oy = 0, width = null, height = null) {
|
|
147
|
+
this._engine = engine || globalThis;
|
|
148
|
+
this.ox = ox;
|
|
149
|
+
this.oy = oy;
|
|
150
|
+
this.resize(
|
|
151
|
+
width || this._engine.WIDTH - ox,
|
|
152
|
+
height || this._engine.HEIGHT - oy
|
|
153
|
+
);
|
|
146
154
|
this.x = this.width / 2;
|
|
147
155
|
this.y = this.height / 2;
|
|
148
156
|
}
|
|
149
157
|
resize(width, height) {
|
|
150
158
|
this.width = width;
|
|
151
159
|
this.height = height;
|
|
160
|
+
this._engine.emit("camera-resized", this);
|
|
152
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* @param {boolean} [clip] default: `false`
|
|
164
|
+
*/
|
|
153
165
|
start(clip = false) {
|
|
154
|
-
const centerX = this.width / 2, centerY = this.height / 2;
|
|
155
166
|
this._engine.push();
|
|
167
|
+
if (clip) {
|
|
168
|
+
this._engine.cliprect(this.ox, this.oy, this.width, this.height);
|
|
169
|
+
}
|
|
170
|
+
const centerX = this.ox + this.width / 2, centerY = this.oy + this.height / 2;
|
|
156
171
|
this._engine.translate(centerX, centerY);
|
|
157
172
|
this._engine.scale(this.scale);
|
|
158
173
|
this._engine.rotate(this.rotation);
|
|
159
174
|
this._engine.translate(-this.x + this._shake.x, -this.y + this._shake.y);
|
|
160
|
-
if (clip) {
|
|
161
|
-
this._engine.cliprect(this.x, this.y, this.width, this.height);
|
|
162
|
-
}
|
|
163
175
|
}
|
|
164
176
|
end() {
|
|
165
177
|
this._engine.pop();
|
|
@@ -180,27 +192,95 @@
|
|
|
180
192
|
this.x += dx;
|
|
181
193
|
this.y += dy;
|
|
182
194
|
}
|
|
195
|
+
/**
|
|
196
|
+
* @param {number} value
|
|
197
|
+
*/
|
|
183
198
|
zoom(value) {
|
|
184
199
|
this.scale *= value;
|
|
185
200
|
}
|
|
201
|
+
/**
|
|
202
|
+
* @param {number} value
|
|
203
|
+
*/
|
|
186
204
|
zoomTo(value) {
|
|
187
205
|
this.scale = value;
|
|
188
206
|
}
|
|
207
|
+
/**
|
|
208
|
+
* @param {number} radians
|
|
209
|
+
*/
|
|
189
210
|
rotate(radians) {
|
|
190
211
|
this.rotation += radians;
|
|
191
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* @param {number} radians
|
|
215
|
+
*/
|
|
192
216
|
rotateTo(radians) {
|
|
193
217
|
this.rotation = radians;
|
|
194
218
|
}
|
|
195
|
-
|
|
219
|
+
/**
|
|
220
|
+
* @param {number} x
|
|
221
|
+
* @param {number} y
|
|
222
|
+
* @param {{x: number, y: number}} [output]
|
|
223
|
+
* @returns {{x: number, y: number}}
|
|
224
|
+
*/
|
|
225
|
+
getWorldPoint(x, y, output = {}) {
|
|
196
226
|
const c = Math.cos(-this.rotation), s = Math.sin(-this.rotation);
|
|
197
|
-
x = (x - this.width / 2) / this.scale;
|
|
198
|
-
y = (y - this.height / 2) / this.scale;
|
|
199
|
-
output = output || {};
|
|
227
|
+
x = (x - this.width / 2 - this.ox) / this.scale;
|
|
228
|
+
y = (y - this.height / 2 - this.oy) / this.scale;
|
|
200
229
|
output.x = c * x - s * y + this.x;
|
|
201
230
|
output.y = s * x + c * y + this.y;
|
|
202
231
|
return output;
|
|
203
232
|
}
|
|
233
|
+
/**
|
|
234
|
+
* @param {number} x
|
|
235
|
+
* @param {number} y
|
|
236
|
+
* @param {{x: number, y: number}} [output]
|
|
237
|
+
* @returns {{x: number, y: number}}
|
|
238
|
+
*/
|
|
239
|
+
getCameraPoint(x, y, output = {}) {
|
|
240
|
+
const c = Math.cos(-this.rotation), s = Math.sin(-this.rotation);
|
|
241
|
+
x = x - this.x;
|
|
242
|
+
y = y - this.y;
|
|
243
|
+
x = c * x - s * y;
|
|
244
|
+
y = s * x + c * y;
|
|
245
|
+
output.x = x * this.scale + this.width / 2 + this.ox;
|
|
246
|
+
output.y = y * this.scale + this.height / 2 + this.oy;
|
|
247
|
+
return output;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* @returns {number[]}
|
|
251
|
+
*/
|
|
252
|
+
getBounds() {
|
|
253
|
+
return [this.ox, this.oy, this.width, this.height];
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Check if a rect is inside of the camera.
|
|
257
|
+
*
|
|
258
|
+
* @param {number} x
|
|
259
|
+
* @param {number} y
|
|
260
|
+
* @param {number} width
|
|
261
|
+
* @param {number} height
|
|
262
|
+
* @returns {boolean}
|
|
263
|
+
*/
|
|
264
|
+
viewing(x, y, width, height) {
|
|
265
|
+
const cameraX = this.width / 2 - this.x;
|
|
266
|
+
const cameraY = this.height / 2 - this.y;
|
|
267
|
+
const cameraWidth = this.width / this.scale;
|
|
268
|
+
const cameraHeight = this.height / this.scale;
|
|
269
|
+
return this._engine.colrect(
|
|
270
|
+
x,
|
|
271
|
+
y,
|
|
272
|
+
width,
|
|
273
|
+
height,
|
|
274
|
+
cameraX,
|
|
275
|
+
cameraY,
|
|
276
|
+
cameraWidth,
|
|
277
|
+
cameraHeight
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* @param {number} amplitude
|
|
282
|
+
* @param {number} duration in seconds
|
|
283
|
+
*/
|
|
204
284
|
shake(amplitude = 1, duration = 0.3) {
|
|
205
285
|
if (this.shaking) return;
|
|
206
286
|
this._shake.removeListener = this._engine.listen("update", (dt) => {
|
|
@@ -219,6 +299,9 @@
|
|
|
219
299
|
this._shake.x = this._shake.y = 0;
|
|
220
300
|
}
|
|
221
301
|
}
|
|
302
|
+
/**
|
|
303
|
+
* @returns {boolean}
|
|
304
|
+
*/
|
|
222
305
|
get shaking() {
|
|
223
306
|
return this._shake.removeListener !== null;
|
|
224
307
|
}
|
|
@@ -630,7 +713,7 @@
|
|
|
630
713
|
* @returns {number}
|
|
631
714
|
*/
|
|
632
715
|
get width() {
|
|
633
|
-
return this.sprite.width * this._s.
|
|
716
|
+
return this.sprite.width * this._s.x;
|
|
634
717
|
}
|
|
635
718
|
/**
|
|
636
719
|
* @returns {number}
|
|
@@ -638,6 +721,16 @@
|
|
|
638
721
|
get height() {
|
|
639
722
|
return this.sprite.height * this._s.y;
|
|
640
723
|
}
|
|
724
|
+
/**
|
|
725
|
+
* @returns {number[]}
|
|
726
|
+
*/
|
|
727
|
+
getBounds(scaled = true) {
|
|
728
|
+
const w = this.sprite.width * (scaled ? this._s.x : 1);
|
|
729
|
+
const h = this.sprite.height * (scaled ? this._s.y : 1);
|
|
730
|
+
const x = this.pos.x - w * this.anchor.x;
|
|
731
|
+
const y = this.pos.y - h * this.anchor.y;
|
|
732
|
+
return [x, y, w, h];
|
|
733
|
+
}
|
|
641
734
|
/**
|
|
642
735
|
* @retuns {Vector}
|
|
643
736
|
*/
|
|
@@ -653,9 +746,7 @@
|
|
|
653
746
|
if (this.hidden || this.opacity <= 0) return;
|
|
654
747
|
litecanvas.push();
|
|
655
748
|
this.transform(litecanvas);
|
|
656
|
-
|
|
657
|
-
const anchorY = this.sprite.height * this.anchor.y;
|
|
658
|
-
litecanvas.image(-anchorX, -anchorY, this.sprite);
|
|
749
|
+
this.drawImage(litecanvas);
|
|
659
750
|
litecanvas.pop();
|
|
660
751
|
}
|
|
661
752
|
/**
|
|
@@ -665,7 +756,15 @@
|
|
|
665
756
|
litecanvas.translate(this.pos.x, this.pos.y);
|
|
666
757
|
litecanvas.rotate(this.angle);
|
|
667
758
|
litecanvas.scale(this._s.x, this._s.y);
|
|
759
|
+
}
|
|
760
|
+
/**
|
|
761
|
+
* @param {LitecanvasInstance} litecanvas
|
|
762
|
+
*/
|
|
763
|
+
drawImage(litecanvas) {
|
|
764
|
+
const anchorX = this.sprite.width * this.anchor.x;
|
|
765
|
+
const anchorY = this.sprite.height * this.anchor.y;
|
|
668
766
|
litecanvas.alpha(this.opacity);
|
|
767
|
+
litecanvas.image(-anchorX, -anchorY, this.sprite);
|
|
669
768
|
}
|
|
670
769
|
};
|
|
671
770
|
|
package/dist/all.min.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(()=>{var v=Object.defineProperty;var
|
|
2
|
-
`)}},w=class e extends
|
|
1
|
+
(()=>{var v=Object.defineProperty;var B=(e,t)=>{for(var s in t)v(e,s,{get:t[s],enumerable:!0})};globalThis.utils=globalThis.utils||{};globalThis.utils.global=()=>{for(let e in globalThis.utils)e!=="global"&&(globalThis[e]=globalThis.utils[e])};var M={};B(M,{ANCHOR_BOT_LEFT:()=>nt,ANCHOR_BOT_RIGHT:()=>at,ANCHOR_CENTER:()=>ot,ANCHOR_TOP_LEFT:()=>L,ANCHOR_TOP_RIGHT:()=>rt,Actor:()=>b,Camera:()=>p,DOWN:()=>st,Grid:()=>x,LEFT:()=>it,ONE:()=>Q,RIGHT:()=>et,TypedGrid:()=>w,UP:()=>tt,Vector:()=>u,ZERO:()=>K,diff:()=>A,fract:()=>D,intersection:()=>g,isvector:()=>l,resolve:()=>C,vec:()=>n,vecadd:()=>S,vecconfig:()=>H,veccopy:()=>E,veccross:()=>U,vecdir:()=>N,vecdist:()=>$,vecdist2:()=>q,vecdiv:()=>_,vecdot:()=>V,veceq:()=>X,veclerp:()=>Z,veclimit:()=>j,vecmag:()=>R,vecmag2:()=>W,vecmult:()=>I,vecnorm:()=>G,vecrand:()=>J,vecrot:()=>F,vecset:()=>z,vecsub:()=>Y,wave:()=>O});var A=(e,t)=>Math.abs(t-e)||0;var D=e=>e%1||0;var O=(e,t,s,i=Math.sin)=>e+(i(s)+1)/2*(t-e);var g=(e,t,s,i,r,o,a,h)=>{let c=Math.max(e,r),P=Math.min(e+s,r+a)-c,d=Math.max(t,o),m=Math.min(t+i,o+h)-d;return[c,d,P,m]};var C=(e,t,s,i,r,o,a,h)=>{let[c,P,d,m]=g(e,t,s,i,r,o,a,h),f="",y=e,T=t;return d<m?e<r?(f="right",y=r-s):(f="left",y=r+a):t<o?(f="bottom",T=o-i):(f="top",T=o+h),{direction:f,x:y,y:T}};var p=class{_engine=null;x=0;y=0;ox=0;oy=0;width=0;height=0;rotation=0;scale=1;_shake={x:0,y:0,removeListener:null};constructor(t=null,s=0,i=0,r=null,o=null){this._engine=t||globalThis,this.ox=s,this.oy=i,this.resize(r||this._engine.WIDTH-s,o||this._engine.HEIGHT-i),this.x=this.width/2,this.y=this.height/2}resize(t,s){this.width=t,this.height=s,this._engine.emit("camera-resized",this)}start(t=!1){this._engine.push(),t&&this._engine.cliprect(this.ox,this.oy,this.width,this.height);let s=this.ox+this.width/2,i=this.oy+this.height/2;this._engine.translate(s,i),this._engine.scale(this.scale),this._engine.rotate(this.rotation),this._engine.translate(-this.x+this._shake.x,-this.y+this._shake.y)}end(){this._engine.pop()}lookAt(t,s){this.x=t,this.y=s}move(t,s){this.x+=t,this.y+=s}zoom(t){this.scale*=t}zoomTo(t){this.scale=t}rotate(t){this.rotation+=t}rotateTo(t){this.rotation=t}getWorldPoint(t,s,i={}){let r=Math.cos(-this.rotation),o=Math.sin(-this.rotation);return t=(t-this.width/2-this.ox)/this.scale,s=(s-this.height/2-this.oy)/this.scale,i.x=r*t-o*s+this.x,i.y=o*t+r*s+this.y,i}getCameraPoint(t,s,i={}){let r=Math.cos(-this.rotation),o=Math.sin(-this.rotation);return t=t-this.x,s=s-this.y,t=r*t-o*s,s=o*t+r*s,i.x=t*this.scale+this.width/2+this.ox,i.y=s*this.scale+this.height/2+this.oy,i}getBounds(){return[this.ox,this.oy,this.width,this.height]}viewing(t,s,i,r){let o=this.width/2-this.x,a=this.height/2-this.y,h=this.width/this.scale,c=this.height/this.scale;return this._engine.colrect(t,s,i,r,o,a,h,c)}shake(t=1,s=.3){this.shaking||(this._shake.removeListener=this._engine.listen("update",i=>{this._shake.x=this._engine.randi(-t,t),this._shake.y=this._engine.randi(-t,t),s-=i,s<=0&&this.unshake()}))}unshake(){this.shaking&&(this._shake.removeListener(),this._shake.removeListener=null,this._shake.x=this._shake.y=0)}get shaking(){return this._shake.removeListener!==null}};var x=class e{_w;_h;_c;constructor(t,s,i=[]){this._w=Math.max(1,~~t),this._h=Math.max(1,~~s),this._c=i}clear(){this.forEach((t,s)=>this.set(t,s,void 0))}get width(){return this._w}get height(){return this._h}set(t,s,i){this._c[this.pointToIndex(t,s)]=i}get(t,s){return this._c[this.pointToIndex(t,s)]}has(t,s){return this.get(t,s)!=null}get length(){return this._w*this._h}pointToIndex(t,s){return this.clampX(~~t)+this.clampY(~~s)*this._w}indexToPointX(t){return t%this._w}indexToPointY(t){return Math.floor(t/this._w)}forEach(t,s=!1){let i=s?this.length-1:0,r=s?-1:this.length,o=s?-1:1;for(;i!==r;){let a=this.indexToPointX(i),h=this.indexToPointY(i),c=this._c[i];if(t(a,h,c,this)===!1)break;i+=o}}fill(t){this.forEach((s,i)=>{this.set(s,i,t)})}clone(){return e.fromArray(this._w,this._h,this._c)}clampX(t){return k(t,0,this._w-1)}clampY(t){return k(t,0,this._h-1)}toArray(){return this._c.slice()}toString(t=" ",s=!0){if(!s)return this._c.join(t);let i=[];return this.forEach((r,o,a)=>{i[o]=i[o]||"",i[o]+=a+t}),i.join(`
|
|
2
|
+
`)}},w=class e extends x{constructor(t,s,i=Uint8Array){super(t,s,null),this._c=new i(this._w*this._h)}has(t,s){return this.get(t,s)!==0}clone(){let t=new e(this._w,this._h,this._c.constructor);return this.forEach((s,i,r)=>{t.set(s,i,r)}),t}};function k(e,t,s){return e<t?t:e>s?s:e}var u=class{x;y;constructor(t=0,s=t){this.x=t,this.y=s}toString(){return`Vector (${this.x}, ${this.y})`}},n=(e=0,t=e)=>new u(e,t),X=(e,t,s=t)=>l(t)?X(e,t.x,t.y):e.x===t&&e.y===s,E=e=>n(e.x,e.y),z=(e,t,s=t)=>{l(t)?z(e,t.x,t.y):(e.x=t,e.y=s)},S=(e,t,s=t)=>{l(t)?S(e,t.x,t.y):(e.x+=t,e.y+=s)},Y=(e,t,s=t)=>{l(t)?Y(e,t.x,t.y):(e.x-=t,e.y-=s)},I=(e,t,s=t)=>{l(t)?I(e,t.x,t.y):(e.x*=t,e.y*=s)},_=(e,t,s=t)=>{l(t)?_(e,t.x,t.y):(e.x/=t,e.y/=s)},F=(e,t)=>{let s=Math.cos(t),i=Math.sin(t);e.x=s*e.x-i*e.y,e.y=i*e.x+s*e.y},R=e=>Math.sqrt(e.x*e.x+e.y*e.y),W=e=>e.x*e.x+e.y*e.y,G=e=>{let t=R(e);t>0&&_(e,t)},j=(e,t)=>{let s=W(e);s>t*t&&(_(e,Math.sqrt(s)),I(e,t))},$=(e,t)=>{let s=e.x-t.x,i=e.y-t.y;return Math.sqrt(s*s+i*i)},q=(e,t)=>{let s=e.x-t.x,i=e.y-t.y;return s*s+i*i},N=e=>Math.atan2(e.y,e.x),V=(e,t)=>e.x*t.x+e.y*t.y,U=(e,t)=>e.x*t.y-e.y*t.x,Z=(e,t,s)=>{e.x+=(t.x-e.x)*s||0,e.y+=(t.y-e.y)*s||0},J=(e=1,t=e)=>{let s=H.random()*2*Math.PI,i=H.random()*(t-e)+e;return n(Math.cos(s)*i,Math.sin(s)*i)},l=e=>e instanceof u,H={random:()=>globalThis.rand?rand():Math.random()},K=n(0,0),Q=n(1,1),tt=n(0,-1),et=n(1,0),st=n(0,1),it=n(-1,0);var ot=n(.5,.5),L=n(0,0),rt=n(1,0),nt=n(0,1),at=n(1,1),b=class{sprite;pos;_o;_s;angle=0;opacity=1;hidden=!1;constructor(t,s,i=L){this.sprite=t,this.pos=s||n(0),this._o=E(i),this._s=n(1,1)}set x(t){this.pos.x=t}get x(){return this.pos.x}set y(t){this.pos.y=t}get y(){return this.pos.y}set anchor(t){this._o.x=t.x,this._o.y=t.y}get anchor(){return this._o}get width(){return this.sprite.width*this._s.x}get height(){return this.sprite.height*this._s.y}getBounds(t=!0){let s=this.sprite.width*(t?this._s.x:1),i=this.sprite.height*(t?this._s.y:1),r=this.pos.x-s*this.anchor.x,o=this.pos.y-i*this.anchor.y;return[r,o,s,i]}get scale(){return this._s}draw(t=globalThis){this.hidden||this.opacity<=0||(t.push(),this.transform(t),this.drawImage(t),t.pop())}transform(t){t.translate(this.pos.x,this.pos.y),t.rotate(this.angle),t.scale(this._s.x,this._s.y)}drawImage(t){let s=this.sprite.width*this.anchor.x,i=this.sprite.height*this.anchor.y;t.alpha(this.opacity),t.image(-s,-i,this.sprite)}};globalThis.utils=Object.assign(globalThis.utils||{},M);})();
|
package/dist/camera.js
CHANGED
|
@@ -12,10 +12,14 @@
|
|
|
12
12
|
var Camera = class {
|
|
13
13
|
/** @type {LitecanvasInstance} */
|
|
14
14
|
_engine = null;
|
|
15
|
-
/** @type {number} */
|
|
15
|
+
/** @type {number} camera center X */
|
|
16
16
|
x = 0;
|
|
17
|
-
/** @type {number} */
|
|
17
|
+
/** @type {number} camera center Y */
|
|
18
18
|
y = 0;
|
|
19
|
+
/** @type {number} offset X */
|
|
20
|
+
ox = 0;
|
|
21
|
+
/** @type {number} offset Y*/
|
|
22
|
+
oy = 0;
|
|
19
23
|
/** @type {number} */
|
|
20
24
|
width = 0;
|
|
21
25
|
/** @type {number} */
|
|
@@ -32,27 +36,35 @@
|
|
|
32
36
|
/**
|
|
33
37
|
* @param {LitecanvasInstance} engine
|
|
34
38
|
*/
|
|
35
|
-
constructor(engine = null) {
|
|
36
|
-
|
|
37
|
-
this.
|
|
38
|
-
this.
|
|
39
|
+
constructor(engine = null, ox = 0, oy = 0, width = null, height = null) {
|
|
40
|
+
this._engine = engine || globalThis;
|
|
41
|
+
this.ox = ox;
|
|
42
|
+
this.oy = oy;
|
|
43
|
+
this.resize(
|
|
44
|
+
width || this._engine.WIDTH - ox,
|
|
45
|
+
height || this._engine.HEIGHT - oy
|
|
46
|
+
);
|
|
39
47
|
this.x = this.width / 2;
|
|
40
48
|
this.y = this.height / 2;
|
|
41
49
|
}
|
|
42
50
|
resize(width, height) {
|
|
43
51
|
this.width = width;
|
|
44
52
|
this.height = height;
|
|
53
|
+
this._engine.emit("camera-resized", this);
|
|
45
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* @param {boolean} [clip] default: `false`
|
|
57
|
+
*/
|
|
46
58
|
start(clip = false) {
|
|
47
|
-
const centerX = this.width / 2, centerY = this.height / 2;
|
|
48
59
|
this._engine.push();
|
|
60
|
+
if (clip) {
|
|
61
|
+
this._engine.cliprect(this.ox, this.oy, this.width, this.height);
|
|
62
|
+
}
|
|
63
|
+
const centerX = this.ox + this.width / 2, centerY = this.oy + this.height / 2;
|
|
49
64
|
this._engine.translate(centerX, centerY);
|
|
50
65
|
this._engine.scale(this.scale);
|
|
51
66
|
this._engine.rotate(this.rotation);
|
|
52
67
|
this._engine.translate(-this.x + this._shake.x, -this.y + this._shake.y);
|
|
53
|
-
if (clip) {
|
|
54
|
-
this._engine.cliprect(this.x, this.y, this.width, this.height);
|
|
55
|
-
}
|
|
56
68
|
}
|
|
57
69
|
end() {
|
|
58
70
|
this._engine.pop();
|
|
@@ -73,27 +85,95 @@
|
|
|
73
85
|
this.x += dx;
|
|
74
86
|
this.y += dy;
|
|
75
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* @param {number} value
|
|
90
|
+
*/
|
|
76
91
|
zoom(value) {
|
|
77
92
|
this.scale *= value;
|
|
78
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* @param {number} value
|
|
96
|
+
*/
|
|
79
97
|
zoomTo(value) {
|
|
80
98
|
this.scale = value;
|
|
81
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* @param {number} radians
|
|
102
|
+
*/
|
|
82
103
|
rotate(radians) {
|
|
83
104
|
this.rotation += radians;
|
|
84
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* @param {number} radians
|
|
108
|
+
*/
|
|
85
109
|
rotateTo(radians) {
|
|
86
110
|
this.rotation = radians;
|
|
87
111
|
}
|
|
88
|
-
|
|
112
|
+
/**
|
|
113
|
+
* @param {number} x
|
|
114
|
+
* @param {number} y
|
|
115
|
+
* @param {{x: number, y: number}} [output]
|
|
116
|
+
* @returns {{x: number, y: number}}
|
|
117
|
+
*/
|
|
118
|
+
getWorldPoint(x, y, output = {}) {
|
|
89
119
|
const c = Math.cos(-this.rotation), s = Math.sin(-this.rotation);
|
|
90
|
-
x = (x - this.width / 2) / this.scale;
|
|
91
|
-
y = (y - this.height / 2) / this.scale;
|
|
92
|
-
output = output || {};
|
|
120
|
+
x = (x - this.width / 2 - this.ox) / this.scale;
|
|
121
|
+
y = (y - this.height / 2 - this.oy) / this.scale;
|
|
93
122
|
output.x = c * x - s * y + this.x;
|
|
94
123
|
output.y = s * x + c * y + this.y;
|
|
95
124
|
return output;
|
|
96
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* @param {number} x
|
|
128
|
+
* @param {number} y
|
|
129
|
+
* @param {{x: number, y: number}} [output]
|
|
130
|
+
* @returns {{x: number, y: number}}
|
|
131
|
+
*/
|
|
132
|
+
getCameraPoint(x, y, output = {}) {
|
|
133
|
+
const c = Math.cos(-this.rotation), s = Math.sin(-this.rotation);
|
|
134
|
+
x = x - this.x;
|
|
135
|
+
y = y - this.y;
|
|
136
|
+
x = c * x - s * y;
|
|
137
|
+
y = s * x + c * y;
|
|
138
|
+
output.x = x * this.scale + this.width / 2 + this.ox;
|
|
139
|
+
output.y = y * this.scale + this.height / 2 + this.oy;
|
|
140
|
+
return output;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* @returns {number[]}
|
|
144
|
+
*/
|
|
145
|
+
getBounds() {
|
|
146
|
+
return [this.ox, this.oy, this.width, this.height];
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Check if a rect is inside of the camera.
|
|
150
|
+
*
|
|
151
|
+
* @param {number} x
|
|
152
|
+
* @param {number} y
|
|
153
|
+
* @param {number} width
|
|
154
|
+
* @param {number} height
|
|
155
|
+
* @returns {boolean}
|
|
156
|
+
*/
|
|
157
|
+
viewing(x, y, width, height) {
|
|
158
|
+
const cameraX = this.width / 2 - this.x;
|
|
159
|
+
const cameraY = this.height / 2 - this.y;
|
|
160
|
+
const cameraWidth = this.width / this.scale;
|
|
161
|
+
const cameraHeight = this.height / this.scale;
|
|
162
|
+
return this._engine.colrect(
|
|
163
|
+
x,
|
|
164
|
+
y,
|
|
165
|
+
width,
|
|
166
|
+
height,
|
|
167
|
+
cameraX,
|
|
168
|
+
cameraY,
|
|
169
|
+
cameraWidth,
|
|
170
|
+
cameraHeight
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* @param {number} amplitude
|
|
175
|
+
* @param {number} duration in seconds
|
|
176
|
+
*/
|
|
97
177
|
shake(amplitude = 1, duration = 0.3) {
|
|
98
178
|
if (this.shaking) return;
|
|
99
179
|
this._shake.removeListener = this._engine.listen("update", (dt) => {
|
|
@@ -112,6 +192,9 @@
|
|
|
112
192
|
this._shake.x = this._shake.y = 0;
|
|
113
193
|
}
|
|
114
194
|
}
|
|
195
|
+
/**
|
|
196
|
+
* @returns {boolean}
|
|
197
|
+
*/
|
|
115
198
|
get shaking() {
|
|
116
199
|
return this._shake.removeListener !== null;
|
|
117
200
|
}
|
package/dist/camera.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{globalThis.utils=globalThis.utils||{};globalThis.utils.global=()=>{for(let
|
|
1
|
+
(()=>{globalThis.utils=globalThis.utils||{};globalThis.utils.global=()=>{for(let o in globalThis.utils)o!=="global"&&(globalThis[o]=globalThis.utils[o])};var n=class{_engine=null;x=0;y=0;ox=0;oy=0;width=0;height=0;rotation=0;scale=1;_shake={x:0,y:0,removeListener:null};constructor(i=null,t=0,s=0,h=null,e=null){this._engine=i||globalThis,this.ox=t,this.oy=s,this.resize(h||this._engine.WIDTH-t,e||this._engine.HEIGHT-s),this.x=this.width/2,this.y=this.height/2}resize(i,t){this.width=i,this.height=t,this._engine.emit("camera-resized",this)}start(i=!1){this._engine.push(),i&&this._engine.cliprect(this.ox,this.oy,this.width,this.height);let t=this.ox+this.width/2,s=this.oy+this.height/2;this._engine.translate(t,s),this._engine.scale(this.scale),this._engine.rotate(this.rotation),this._engine.translate(-this.x+this._shake.x,-this.y+this._shake.y)}end(){this._engine.pop()}lookAt(i,t){this.x=i,this.y=t}move(i,t){this.x+=i,this.y+=t}zoom(i){this.scale*=i}zoomTo(i){this.scale=i}rotate(i){this.rotation+=i}rotateTo(i){this.rotation=i}getWorldPoint(i,t,s={}){let h=Math.cos(-this.rotation),e=Math.sin(-this.rotation);return i=(i-this.width/2-this.ox)/this.scale,t=(t-this.height/2-this.oy)/this.scale,s.x=h*i-e*t+this.x,s.y=e*i+h*t+this.y,s}getCameraPoint(i,t,s={}){let h=Math.cos(-this.rotation),e=Math.sin(-this.rotation);return i=i-this.x,t=t-this.y,i=h*i-e*t,t=e*i+h*t,s.x=i*this.scale+this.width/2+this.ox,s.y=t*this.scale+this.height/2+this.oy,s}getBounds(){return[this.ox,this.oy,this.width,this.height]}viewing(i,t,s,h){let e=this.width/2-this.x,a=this.height/2-this.y,l=this.width/this.scale,r=this.height/this.scale;return this._engine.colrect(i,t,s,h,e,a,l,r)}shake(i=1,t=.3){this.shaking||(this._shake.removeListener=this._engine.listen("update",s=>{this._shake.x=this._engine.randi(-i,i),this._shake.y=this._engine.randi(-i,i),t-=s,t<=0&&this.unshake()}))}unshake(){this.shaking&&(this._shake.removeListener(),this._shake.removeListener=null,this._shake.x=this._shake.y=0)}get shaking(){return this._shake.removeListener!==null}};globalThis.utils=Object.assign(globalThis.utils||{},{Camera:n});})();
|
package/package.json
CHANGED
package/src/actor/index.js
CHANGED
|
@@ -88,7 +88,7 @@ export class Actor {
|
|
|
88
88
|
* @returns {number}
|
|
89
89
|
*/
|
|
90
90
|
get width() {
|
|
91
|
-
return this.sprite.width * this._s.
|
|
91
|
+
return this.sprite.width * this._s.x
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
/**
|
|
@@ -98,6 +98,17 @@ export class Actor {
|
|
|
98
98
|
return this.sprite.height * this._s.y
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
+
/**
|
|
102
|
+
* @returns {number[]}
|
|
103
|
+
*/
|
|
104
|
+
getBounds(scaled = true) {
|
|
105
|
+
const w = this.sprite.width * (scaled ? this._s.x : 1)
|
|
106
|
+
const h = this.sprite.height * (scaled ? this._s.y : 1)
|
|
107
|
+
const x = this.pos.x - w * this.anchor.x
|
|
108
|
+
const y = this.pos.y - h * this.anchor.y
|
|
109
|
+
return [x, y, w, h]
|
|
110
|
+
}
|
|
111
|
+
|
|
101
112
|
/**
|
|
102
113
|
* @retuns {Vector}
|
|
103
114
|
*/
|
|
@@ -116,10 +127,7 @@ export class Actor {
|
|
|
116
127
|
litecanvas.push()
|
|
117
128
|
|
|
118
129
|
this.transform(litecanvas)
|
|
119
|
-
|
|
120
|
-
const anchorX = this.sprite.width * this.anchor.x
|
|
121
|
-
const anchorY = this.sprite.height * this.anchor.y
|
|
122
|
-
litecanvas.image(-anchorX, -anchorY, this.sprite)
|
|
130
|
+
this.drawImage(litecanvas)
|
|
123
131
|
|
|
124
132
|
litecanvas.pop()
|
|
125
133
|
}
|
|
@@ -131,6 +139,15 @@ export class Actor {
|
|
|
131
139
|
litecanvas.translate(this.pos.x, this.pos.y)
|
|
132
140
|
litecanvas.rotate(this.angle)
|
|
133
141
|
litecanvas.scale(this._s.x, this._s.y)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* @param {LitecanvasInstance} litecanvas
|
|
146
|
+
*/
|
|
147
|
+
drawImage(litecanvas) {
|
|
148
|
+
const anchorX = this.sprite.width * this.anchor.x
|
|
149
|
+
const anchorY = this.sprite.height * this.anchor.y
|
|
134
150
|
litecanvas.alpha(this.opacity)
|
|
151
|
+
litecanvas.image(-anchorX, -anchorY, this.sprite)
|
|
135
152
|
}
|
|
136
153
|
}
|
package/src/camera/README.md
CHANGED
|
@@ -27,8 +27,10 @@ function draw() {
|
|
|
27
27
|
|
|
28
28
|
## Properties
|
|
29
29
|
|
|
30
|
-
- `x` the camera X
|
|
31
|
-
- `y` the camera Y
|
|
30
|
+
- `x` the camera position-X
|
|
31
|
+
- `y` the camera position-Y
|
|
32
|
+
- `ox` the camera offset-X
|
|
33
|
+
- `oy` the camera offset-Y
|
|
32
34
|
- `shaking` it's `true` when the camera is shaking
|
|
33
35
|
- `scale` the camera zoom
|
|
34
36
|
- `rotation` the camera rotation
|
|
@@ -37,6 +39,14 @@ function draw() {
|
|
|
37
39
|
|
|
38
40
|
## Methods
|
|
39
41
|
|
|
42
|
+
### start(clip: boolean = true)
|
|
43
|
+
|
|
44
|
+
Apply the camera transformations (move, zoom and rotate). You must call this method before draw anything inside of the camera.
|
|
45
|
+
|
|
46
|
+
### stop()
|
|
47
|
+
|
|
48
|
+
Stop looking through the camera. You must call this method after draw anything inside of the camera.
|
|
49
|
+
|
|
40
50
|
### lookAt(x: number, y: number)
|
|
41
51
|
|
|
42
52
|
Sets the camera X and Y
|
|
@@ -96,7 +106,7 @@ function update(dt) {
|
|
|
96
106
|
}
|
|
97
107
|
```
|
|
98
108
|
|
|
99
|
-
### shake(
|
|
109
|
+
### shake(duration: number = 0.3, amplitude: number = 1)
|
|
100
110
|
|
|
101
111
|
Shakes the camera view
|
|
102
112
|
|
|
@@ -113,10 +123,20 @@ Makes the camera stop shaking immediately
|
|
|
113
123
|
|
|
114
124
|
### getWorldPoint(x: number, y: number, output?: {x: number, y: number}): {x: number, y: number}
|
|
115
125
|
|
|
116
|
-
This method is used to convert a point (X, Y)
|
|
126
|
+
This method is used to convert a camera point (X, Y) to world point.
|
|
117
127
|
|
|
118
128
|
```
|
|
129
|
+
// convert a mouse/touch to world position
|
|
119
130
|
function tapped(x, y) {
|
|
120
131
|
const fixedTap = camera.getWorldPoint(x, y)
|
|
121
132
|
}
|
|
122
133
|
```
|
|
134
|
+
|
|
135
|
+
### getCameraPoint(x: number, y: number, output?: {x: number, y: number}): {x: number, y: number}
|
|
136
|
+
|
|
137
|
+
This method is used to convert a world point (X, Y) to camera point.
|
|
138
|
+
|
|
139
|
+
### getBounds(): number[]
|
|
140
|
+
|
|
141
|
+
Returns an array containing the position-X, position-Y, the width, and the height of the camera.
|
|
142
|
+
Useful to see if an object is visible on the screen.
|
package/src/camera/index.js
CHANGED
|
@@ -2,10 +2,17 @@ export default class Camera {
|
|
|
2
2
|
/** @type {LitecanvasInstance} */
|
|
3
3
|
_engine = null
|
|
4
4
|
|
|
5
|
-
/** @type {number} */
|
|
5
|
+
/** @type {number} camera center X */
|
|
6
6
|
x = 0
|
|
7
|
-
/** @type {number} */
|
|
7
|
+
/** @type {number} camera center Y */
|
|
8
8
|
y = 0
|
|
9
|
+
|
|
10
|
+
/** @type {number} offset X */
|
|
11
|
+
ox = 0
|
|
12
|
+
|
|
13
|
+
/** @type {number} offset Y*/
|
|
14
|
+
oy = 0
|
|
15
|
+
|
|
9
16
|
/** @type {number} */
|
|
10
17
|
width = 0
|
|
11
18
|
/** @type {number} */
|
|
@@ -25,10 +32,17 @@ export default class Camera {
|
|
|
25
32
|
/**
|
|
26
33
|
* @param {LitecanvasInstance} engine
|
|
27
34
|
*/
|
|
28
|
-
constructor(engine = null) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
this.
|
|
35
|
+
constructor(engine = null, ox = 0, oy = 0, width = null, height = null) {
|
|
36
|
+
this._engine = engine || globalThis
|
|
37
|
+
|
|
38
|
+
this.ox = ox
|
|
39
|
+
this.oy = oy
|
|
40
|
+
|
|
41
|
+
this.resize(
|
|
42
|
+
width || this._engine.WIDTH - ox,
|
|
43
|
+
height || this._engine.HEIGHT - oy
|
|
44
|
+
)
|
|
45
|
+
|
|
32
46
|
this.x = this.width / 2
|
|
33
47
|
this.y = this.height / 2
|
|
34
48
|
}
|
|
@@ -36,21 +50,26 @@ export default class Camera {
|
|
|
36
50
|
resize(width, height) {
|
|
37
51
|
this.width = width
|
|
38
52
|
this.height = height
|
|
53
|
+
this._engine.emit("camera-resized", this)
|
|
39
54
|
}
|
|
40
55
|
|
|
56
|
+
/**
|
|
57
|
+
* @param {boolean} [clip] default: `false`
|
|
58
|
+
*/
|
|
41
59
|
start(clip = false) {
|
|
42
|
-
const centerX = this.width / 2,
|
|
43
|
-
centerY = this.height / 2
|
|
44
|
-
|
|
45
60
|
this._engine.push()
|
|
61
|
+
|
|
62
|
+
if (clip) {
|
|
63
|
+
this._engine.cliprect(this.ox, this.oy, this.width, this.height)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const centerX = this.ox + this.width / 2,
|
|
67
|
+
centerY = this.oy + this.height / 2
|
|
68
|
+
|
|
46
69
|
this._engine.translate(centerX, centerY)
|
|
47
70
|
this._engine.scale(this.scale)
|
|
48
71
|
this._engine.rotate(this.rotation)
|
|
49
72
|
this._engine.translate(-this.x + this._shake.x, -this.y + this._shake.y)
|
|
50
|
-
|
|
51
|
-
if (clip) {
|
|
52
|
-
this._engine.cliprect(this.x, this.y, this.width, this.height)
|
|
53
|
-
}
|
|
54
73
|
}
|
|
55
74
|
|
|
56
75
|
end() {
|
|
@@ -75,36 +94,112 @@ export default class Camera {
|
|
|
75
94
|
this.y += dy
|
|
76
95
|
}
|
|
77
96
|
|
|
97
|
+
/**
|
|
98
|
+
* @param {number} value
|
|
99
|
+
*/
|
|
78
100
|
zoom(value) {
|
|
79
101
|
this.scale *= value
|
|
80
102
|
}
|
|
81
103
|
|
|
104
|
+
/**
|
|
105
|
+
* @param {number} value
|
|
106
|
+
*/
|
|
82
107
|
zoomTo(value) {
|
|
83
108
|
this.scale = value
|
|
84
109
|
}
|
|
85
110
|
|
|
111
|
+
/**
|
|
112
|
+
* @param {number} radians
|
|
113
|
+
*/
|
|
86
114
|
rotate(radians) {
|
|
87
115
|
this.rotation += radians
|
|
88
116
|
}
|
|
89
117
|
|
|
118
|
+
/**
|
|
119
|
+
* @param {number} radians
|
|
120
|
+
*/
|
|
90
121
|
rotateTo(radians) {
|
|
91
122
|
this.rotation = radians
|
|
92
123
|
}
|
|
93
124
|
|
|
94
|
-
|
|
125
|
+
/**
|
|
126
|
+
* @param {number} x
|
|
127
|
+
* @param {number} y
|
|
128
|
+
* @param {{x: number, y: number}} [output]
|
|
129
|
+
* @returns {{x: number, y: number}}
|
|
130
|
+
*/
|
|
131
|
+
getWorldPoint(x, y, output = {}) {
|
|
95
132
|
const c = Math.cos(-this.rotation),
|
|
96
133
|
s = Math.sin(-this.rotation)
|
|
97
134
|
|
|
98
|
-
x = (x - this.width / 2) / this.scale
|
|
99
|
-
y = (y - this.height / 2) / this.scale
|
|
135
|
+
x = (x - this.width / 2 - this.ox) / this.scale
|
|
136
|
+
y = (y - this.height / 2 - this.oy) / this.scale
|
|
100
137
|
|
|
101
|
-
output = output || {}
|
|
102
138
|
output.x = c * x - s * y + this.x
|
|
103
139
|
output.y = s * x + c * y + this.y
|
|
104
140
|
|
|
105
141
|
return output
|
|
106
142
|
}
|
|
107
143
|
|
|
144
|
+
/**
|
|
145
|
+
* @param {number} x
|
|
146
|
+
* @param {number} y
|
|
147
|
+
* @param {{x: number, y: number}} [output]
|
|
148
|
+
* @returns {{x: number, y: number}}
|
|
149
|
+
*/
|
|
150
|
+
getCameraPoint(x, y, output = {}) {
|
|
151
|
+
const c = Math.cos(-this.rotation),
|
|
152
|
+
s = Math.sin(-this.rotation)
|
|
153
|
+
|
|
154
|
+
x = x - this.x
|
|
155
|
+
y = y - this.y
|
|
156
|
+
x = c * x - s * y
|
|
157
|
+
y = s * x + c * y
|
|
158
|
+
|
|
159
|
+
output.x = x * this.scale + this.width / 2 + this.ox
|
|
160
|
+
output.y = y * this.scale + this.height / 2 + this.oy
|
|
161
|
+
|
|
162
|
+
return output
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* @returns {number[]}
|
|
167
|
+
*/
|
|
168
|
+
getBounds() {
|
|
169
|
+
return [this.ox, this.oy, this.width, this.height]
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Check if a rect is inside of the camera.
|
|
174
|
+
*
|
|
175
|
+
* @param {number} x
|
|
176
|
+
* @param {number} y
|
|
177
|
+
* @param {number} width
|
|
178
|
+
* @param {number} height
|
|
179
|
+
* @returns {boolean}
|
|
180
|
+
*/
|
|
181
|
+
viewing(x, y, width, height) {
|
|
182
|
+
const cameraX = this.width / 2 - this.x
|
|
183
|
+
const cameraY = this.height / 2 - this.y
|
|
184
|
+
const cameraWidth = this.width / this.scale
|
|
185
|
+
const cameraHeight = this.height / this.scale
|
|
186
|
+
|
|
187
|
+
return this._engine.colrect(
|
|
188
|
+
x,
|
|
189
|
+
y,
|
|
190
|
+
width,
|
|
191
|
+
height,
|
|
192
|
+
cameraX,
|
|
193
|
+
cameraY,
|
|
194
|
+
cameraWidth,
|
|
195
|
+
cameraHeight
|
|
196
|
+
)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* @param {number} amplitude
|
|
201
|
+
* @param {number} duration in seconds
|
|
202
|
+
*/
|
|
108
203
|
shake(amplitude = 1, duration = 0.3) {
|
|
109
204
|
if (this.shaking) return
|
|
110
205
|
|
|
@@ -126,6 +221,9 @@ export default class Camera {
|
|
|
126
221
|
}
|
|
127
222
|
}
|
|
128
223
|
|
|
224
|
+
/**
|
|
225
|
+
* @returns {boolean}
|
|
226
|
+
*/
|
|
129
227
|
get shaking() {
|
|
130
228
|
return this._shake.removeListener !== null
|
|
131
229
|
}
|