@litecanvas/utils 0.10.1 → 0.11.0
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 +114 -18
- package/dist/all.min.js +2 -2
- package/dist/camera.js +94 -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 +112 -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,32 @@
|
|
|
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(width || engine.WIDTH - ox, height || engine.HEIGHT - oy);
|
|
146
151
|
this.x = this.width / 2;
|
|
147
152
|
this.y = this.height / 2;
|
|
148
153
|
}
|
|
149
154
|
resize(width, height) {
|
|
150
155
|
this.width = width;
|
|
151
156
|
this.height = height;
|
|
157
|
+
this._engine.emit("camera-resized", this);
|
|
152
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* @param {boolean} [clip] default: `false`
|
|
161
|
+
*/
|
|
153
162
|
start(clip = false) {
|
|
154
|
-
const centerX = this.width / 2, centerY = this.height / 2;
|
|
155
163
|
this._engine.push();
|
|
164
|
+
if (clip) {
|
|
165
|
+
this._engine.cliprect(this.ox, this.oy, this.width, this.height);
|
|
166
|
+
}
|
|
167
|
+
const centerX = this.ox + this.width / 2, centerY = this.oy + this.height / 2;
|
|
156
168
|
this._engine.translate(centerX, centerY);
|
|
157
169
|
this._engine.scale(this.scale);
|
|
158
170
|
this._engine.rotate(this.rotation);
|
|
159
171
|
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
172
|
}
|
|
164
173
|
end() {
|
|
165
174
|
this._engine.pop();
|
|
@@ -180,27 +189,95 @@
|
|
|
180
189
|
this.x += dx;
|
|
181
190
|
this.y += dy;
|
|
182
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* @param {number} value
|
|
194
|
+
*/
|
|
183
195
|
zoom(value) {
|
|
184
196
|
this.scale *= value;
|
|
185
197
|
}
|
|
198
|
+
/**
|
|
199
|
+
* @param {number} value
|
|
200
|
+
*/
|
|
186
201
|
zoomTo(value) {
|
|
187
202
|
this.scale = value;
|
|
188
203
|
}
|
|
204
|
+
/**
|
|
205
|
+
* @param {number} radians
|
|
206
|
+
*/
|
|
189
207
|
rotate(radians) {
|
|
190
208
|
this.rotation += radians;
|
|
191
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
* @param {number} radians
|
|
212
|
+
*/
|
|
192
213
|
rotateTo(radians) {
|
|
193
214
|
this.rotation = radians;
|
|
194
215
|
}
|
|
195
|
-
|
|
216
|
+
/**
|
|
217
|
+
* @param {number} x
|
|
218
|
+
* @param {number} y
|
|
219
|
+
* @param {{x: number, y: number}} [output]
|
|
220
|
+
* @returns {{x: number, y: number}}
|
|
221
|
+
*/
|
|
222
|
+
getWorldPoint(x, y, output = {}) {
|
|
196
223
|
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 || {};
|
|
224
|
+
x = (x - this.width / 2 - this.ox) / this.scale;
|
|
225
|
+
y = (y - this.height / 2 - this.oy) / this.scale;
|
|
200
226
|
output.x = c * x - s * y + this.x;
|
|
201
227
|
output.y = s * x + c * y + this.y;
|
|
202
228
|
return output;
|
|
203
229
|
}
|
|
230
|
+
/**
|
|
231
|
+
* @param {number} x
|
|
232
|
+
* @param {number} y
|
|
233
|
+
* @param {{x: number, y: number}} [output]
|
|
234
|
+
* @returns {{x: number, y: number}}
|
|
235
|
+
*/
|
|
236
|
+
getCameraPoint(x, y, output = {}) {
|
|
237
|
+
const c = Math.cos(-this.rotation), s = Math.sin(-this.rotation);
|
|
238
|
+
x = x - this.x;
|
|
239
|
+
y = y - this.y;
|
|
240
|
+
x = c * x - s * y;
|
|
241
|
+
y = s * x + c * y;
|
|
242
|
+
output.x = x * this.scale + this.width / 2 + this.ox;
|
|
243
|
+
output.y = y * this.scale + this.height / 2 + this.oy;
|
|
244
|
+
return output;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* @returns {number[]}
|
|
248
|
+
*/
|
|
249
|
+
getBounds() {
|
|
250
|
+
return [this.ox, this.oy, this.width, this.height];
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Check if a rect is inside of the camera.
|
|
254
|
+
*
|
|
255
|
+
* @param {number} x
|
|
256
|
+
* @param {number} y
|
|
257
|
+
* @param {number} width
|
|
258
|
+
* @param {number} height
|
|
259
|
+
* @returns {boolean}
|
|
260
|
+
*/
|
|
261
|
+
viewing(x, y, width, height) {
|
|
262
|
+
const cameraX = this.width / 2 - this.x;
|
|
263
|
+
const cameraY = this.height / 2 - this.y;
|
|
264
|
+
const cameraWidth = this.width / this.scale;
|
|
265
|
+
const cameraHeight = this.height / this.scale;
|
|
266
|
+
return this._engine.colrect(
|
|
267
|
+
x,
|
|
268
|
+
y,
|
|
269
|
+
width,
|
|
270
|
+
height,
|
|
271
|
+
cameraX,
|
|
272
|
+
cameraY,
|
|
273
|
+
cameraWidth,
|
|
274
|
+
cameraHeight
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* @param {number} amplitude
|
|
279
|
+
* @param {number} duration in seconds
|
|
280
|
+
*/
|
|
204
281
|
shake(amplitude = 1, duration = 0.3) {
|
|
205
282
|
if (this.shaking) return;
|
|
206
283
|
this._shake.removeListener = this._engine.listen("update", (dt) => {
|
|
@@ -219,6 +296,9 @@
|
|
|
219
296
|
this._shake.x = this._shake.y = 0;
|
|
220
297
|
}
|
|
221
298
|
}
|
|
299
|
+
/**
|
|
300
|
+
* @returns {boolean}
|
|
301
|
+
*/
|
|
222
302
|
get shaking() {
|
|
223
303
|
return this._shake.removeListener !== null;
|
|
224
304
|
}
|
|
@@ -630,7 +710,7 @@
|
|
|
630
710
|
* @returns {number}
|
|
631
711
|
*/
|
|
632
712
|
get width() {
|
|
633
|
-
return this.sprite.width * this._s.
|
|
713
|
+
return this.sprite.width * this._s.x;
|
|
634
714
|
}
|
|
635
715
|
/**
|
|
636
716
|
* @returns {number}
|
|
@@ -638,6 +718,16 @@
|
|
|
638
718
|
get height() {
|
|
639
719
|
return this.sprite.height * this._s.y;
|
|
640
720
|
}
|
|
721
|
+
/**
|
|
722
|
+
* @returns {number[]}
|
|
723
|
+
*/
|
|
724
|
+
getBounds(scaled = true) {
|
|
725
|
+
const w = this.sprite.width * (scaled ? this._s.x : 1);
|
|
726
|
+
const h = this.sprite.height * (scaled ? this._s.y : 1);
|
|
727
|
+
const x = this.pos.x - w * this.anchor.x;
|
|
728
|
+
const y = this.pos.y - h * this.anchor.y;
|
|
729
|
+
return [x, y, w, h];
|
|
730
|
+
}
|
|
641
731
|
/**
|
|
642
732
|
* @retuns {Vector}
|
|
643
733
|
*/
|
|
@@ -653,9 +743,7 @@
|
|
|
653
743
|
if (this.hidden || this.opacity <= 0) return;
|
|
654
744
|
litecanvas.push();
|
|
655
745
|
this.transform(litecanvas);
|
|
656
|
-
|
|
657
|
-
const anchorY = this.sprite.height * this.anchor.y;
|
|
658
|
-
litecanvas.image(-anchorX, -anchorY, this.sprite);
|
|
746
|
+
this.drawImage(litecanvas);
|
|
659
747
|
litecanvas.pop();
|
|
660
748
|
}
|
|
661
749
|
/**
|
|
@@ -665,7 +753,15 @@
|
|
|
665
753
|
litecanvas.translate(this.pos.x, this.pos.y);
|
|
666
754
|
litecanvas.rotate(this.angle);
|
|
667
755
|
litecanvas.scale(this._s.x, this._s.y);
|
|
756
|
+
}
|
|
757
|
+
/**
|
|
758
|
+
* @param {LitecanvasInstance} litecanvas
|
|
759
|
+
*/
|
|
760
|
+
drawImage(litecanvas) {
|
|
761
|
+
const anchorX = this.sprite.width * this.anchor.x;
|
|
762
|
+
const anchorY = this.sprite.height * this.anchor.y;
|
|
668
763
|
litecanvas.alpha(this.opacity);
|
|
764
|
+
litecanvas.image(-anchorX, -anchorY, this.sprite);
|
|
669
765
|
}
|
|
670
766
|
};
|
|
671
767
|
|
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||t.WIDTH-s,o||t.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,32 @@
|
|
|
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(width || engine.WIDTH - ox, height || engine.HEIGHT - oy);
|
|
39
44
|
this.x = this.width / 2;
|
|
40
45
|
this.y = this.height / 2;
|
|
41
46
|
}
|
|
42
47
|
resize(width, height) {
|
|
43
48
|
this.width = width;
|
|
44
49
|
this.height = height;
|
|
50
|
+
this._engine.emit("camera-resized", this);
|
|
45
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* @param {boolean} [clip] default: `false`
|
|
54
|
+
*/
|
|
46
55
|
start(clip = false) {
|
|
47
|
-
const centerX = this.width / 2, centerY = this.height / 2;
|
|
48
56
|
this._engine.push();
|
|
57
|
+
if (clip) {
|
|
58
|
+
this._engine.cliprect(this.ox, this.oy, this.width, this.height);
|
|
59
|
+
}
|
|
60
|
+
const centerX = this.ox + this.width / 2, centerY = this.oy + this.height / 2;
|
|
49
61
|
this._engine.translate(centerX, centerY);
|
|
50
62
|
this._engine.scale(this.scale);
|
|
51
63
|
this._engine.rotate(this.rotation);
|
|
52
64
|
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
65
|
}
|
|
57
66
|
end() {
|
|
58
67
|
this._engine.pop();
|
|
@@ -73,27 +82,95 @@
|
|
|
73
82
|
this.x += dx;
|
|
74
83
|
this.y += dy;
|
|
75
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* @param {number} value
|
|
87
|
+
*/
|
|
76
88
|
zoom(value) {
|
|
77
89
|
this.scale *= value;
|
|
78
90
|
}
|
|
91
|
+
/**
|
|
92
|
+
* @param {number} value
|
|
93
|
+
*/
|
|
79
94
|
zoomTo(value) {
|
|
80
95
|
this.scale = value;
|
|
81
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* @param {number} radians
|
|
99
|
+
*/
|
|
82
100
|
rotate(radians) {
|
|
83
101
|
this.rotation += radians;
|
|
84
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* @param {number} radians
|
|
105
|
+
*/
|
|
85
106
|
rotateTo(radians) {
|
|
86
107
|
this.rotation = radians;
|
|
87
108
|
}
|
|
88
|
-
|
|
109
|
+
/**
|
|
110
|
+
* @param {number} x
|
|
111
|
+
* @param {number} y
|
|
112
|
+
* @param {{x: number, y: number}} [output]
|
|
113
|
+
* @returns {{x: number, y: number}}
|
|
114
|
+
*/
|
|
115
|
+
getWorldPoint(x, y, output = {}) {
|
|
89
116
|
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 || {};
|
|
117
|
+
x = (x - this.width / 2 - this.ox) / this.scale;
|
|
118
|
+
y = (y - this.height / 2 - this.oy) / this.scale;
|
|
93
119
|
output.x = c * x - s * y + this.x;
|
|
94
120
|
output.y = s * x + c * y + this.y;
|
|
95
121
|
return output;
|
|
96
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* @param {number} x
|
|
125
|
+
* @param {number} y
|
|
126
|
+
* @param {{x: number, y: number}} [output]
|
|
127
|
+
* @returns {{x: number, y: number}}
|
|
128
|
+
*/
|
|
129
|
+
getCameraPoint(x, y, output = {}) {
|
|
130
|
+
const c = Math.cos(-this.rotation), s = Math.sin(-this.rotation);
|
|
131
|
+
x = x - this.x;
|
|
132
|
+
y = y - this.y;
|
|
133
|
+
x = c * x - s * y;
|
|
134
|
+
y = s * x + c * y;
|
|
135
|
+
output.x = x * this.scale + this.width / 2 + this.ox;
|
|
136
|
+
output.y = y * this.scale + this.height / 2 + this.oy;
|
|
137
|
+
return output;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* @returns {number[]}
|
|
141
|
+
*/
|
|
142
|
+
getBounds() {
|
|
143
|
+
return [this.ox, this.oy, this.width, this.height];
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Check if a rect is inside of the camera.
|
|
147
|
+
*
|
|
148
|
+
* @param {number} x
|
|
149
|
+
* @param {number} y
|
|
150
|
+
* @param {number} width
|
|
151
|
+
* @param {number} height
|
|
152
|
+
* @returns {boolean}
|
|
153
|
+
*/
|
|
154
|
+
viewing(x, y, width, height) {
|
|
155
|
+
const cameraX = this.width / 2 - this.x;
|
|
156
|
+
const cameraY = this.height / 2 - this.y;
|
|
157
|
+
const cameraWidth = this.width / this.scale;
|
|
158
|
+
const cameraHeight = this.height / this.scale;
|
|
159
|
+
return this._engine.colrect(
|
|
160
|
+
x,
|
|
161
|
+
y,
|
|
162
|
+
width,
|
|
163
|
+
height,
|
|
164
|
+
cameraX,
|
|
165
|
+
cameraY,
|
|
166
|
+
cameraWidth,
|
|
167
|
+
cameraHeight
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* @param {number} amplitude
|
|
172
|
+
* @param {number} duration in seconds
|
|
173
|
+
*/
|
|
97
174
|
shake(amplitude = 1, duration = 0.3) {
|
|
98
175
|
if (this.shaking) return;
|
|
99
176
|
this._shake.removeListener = this._engine.listen("update", (dt) => {
|
|
@@ -112,6 +189,9 @@
|
|
|
112
189
|
this._shake.x = this._shake.y = 0;
|
|
113
190
|
}
|
|
114
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* @returns {boolean}
|
|
194
|
+
*/
|
|
115
195
|
get shaking() {
|
|
116
196
|
return this._shake.removeListener !== null;
|
|
117
197
|
}
|
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(t=null,i=0,s=0,h=null,e=null){this._engine=t||globalThis,this.ox=i,this.oy=s,this.resize(h||t.WIDTH-i,e||t.HEIGHT-s),this.x=this.width/2,this.y=this.height/2}resize(t,i){this.width=t,this.height=i,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 i=this.ox+this.width/2,s=this.oy+this.height/2;this._engine.translate(i,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(t,i){this.x=t,this.y=i}move(t,i){this.x+=t,this.y+=i}zoom(t){this.scale*=t}zoomTo(t){this.scale=t}rotate(t){this.rotation+=t}rotateTo(t){this.rotation=t}getWorldPoint(t,i,s={}){let h=Math.cos(-this.rotation),e=Math.sin(-this.rotation);return t=(t-this.width/2-this.ox)/this.scale,i=(i-this.height/2-this.oy)/this.scale,s.x=h*t-e*i+this.x,s.y=e*t+h*i+this.y,s}getCameraPoint(t,i,s={}){let h=Math.cos(-this.rotation),e=Math.sin(-this.rotation);return t=t-this.x,i=i-this.y,t=h*t-e*i,i=e*t+h*i,s.x=t*this.scale+this.width/2+this.ox,s.y=i*this.scale+this.height/2+this.oy,s}getBounds(){return[this.ox,this.oy,this.width,this.height]}viewing(t,i,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(t,i,s,h,e,a,l,r)}shake(t=1,i=.3){this.shaking||(this._shake.removeListener=this._engine.listen("update",s=>{this._shake.x=this._engine.randi(-t,t),this._shake.y=this._engine.randi(-t,t),i-=s,i<=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,14 @@ 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(width || engine.WIDTH - ox, height || engine.HEIGHT - oy)
|
|
42
|
+
|
|
32
43
|
this.x = this.width / 2
|
|
33
44
|
this.y = this.height / 2
|
|
34
45
|
}
|
|
@@ -36,21 +47,26 @@ export default class Camera {
|
|
|
36
47
|
resize(width, height) {
|
|
37
48
|
this.width = width
|
|
38
49
|
this.height = height
|
|
50
|
+
this._engine.emit("camera-resized", this)
|
|
39
51
|
}
|
|
40
52
|
|
|
53
|
+
/**
|
|
54
|
+
* @param {boolean} [clip] default: `false`
|
|
55
|
+
*/
|
|
41
56
|
start(clip = false) {
|
|
42
|
-
const centerX = this.width / 2,
|
|
43
|
-
centerY = this.height / 2
|
|
44
|
-
|
|
45
57
|
this._engine.push()
|
|
58
|
+
|
|
59
|
+
if (clip) {
|
|
60
|
+
this._engine.cliprect(this.ox, this.oy, this.width, this.height)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const centerX = this.ox + this.width / 2,
|
|
64
|
+
centerY = this.oy + this.height / 2
|
|
65
|
+
|
|
46
66
|
this._engine.translate(centerX, centerY)
|
|
47
67
|
this._engine.scale(this.scale)
|
|
48
68
|
this._engine.rotate(this.rotation)
|
|
49
69
|
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
70
|
}
|
|
55
71
|
|
|
56
72
|
end() {
|
|
@@ -75,36 +91,112 @@ export default class Camera {
|
|
|
75
91
|
this.y += dy
|
|
76
92
|
}
|
|
77
93
|
|
|
94
|
+
/**
|
|
95
|
+
* @param {number} value
|
|
96
|
+
*/
|
|
78
97
|
zoom(value) {
|
|
79
98
|
this.scale *= value
|
|
80
99
|
}
|
|
81
100
|
|
|
101
|
+
/**
|
|
102
|
+
* @param {number} value
|
|
103
|
+
*/
|
|
82
104
|
zoomTo(value) {
|
|
83
105
|
this.scale = value
|
|
84
106
|
}
|
|
85
107
|
|
|
108
|
+
/**
|
|
109
|
+
* @param {number} radians
|
|
110
|
+
*/
|
|
86
111
|
rotate(radians) {
|
|
87
112
|
this.rotation += radians
|
|
88
113
|
}
|
|
89
114
|
|
|
115
|
+
/**
|
|
116
|
+
* @param {number} radians
|
|
117
|
+
*/
|
|
90
118
|
rotateTo(radians) {
|
|
91
119
|
this.rotation = radians
|
|
92
120
|
}
|
|
93
121
|
|
|
94
|
-
|
|
122
|
+
/**
|
|
123
|
+
* @param {number} x
|
|
124
|
+
* @param {number} y
|
|
125
|
+
* @param {{x: number, y: number}} [output]
|
|
126
|
+
* @returns {{x: number, y: number}}
|
|
127
|
+
*/
|
|
128
|
+
getWorldPoint(x, y, output = {}) {
|
|
95
129
|
const c = Math.cos(-this.rotation),
|
|
96
130
|
s = Math.sin(-this.rotation)
|
|
97
131
|
|
|
98
|
-
x = (x - this.width / 2) / this.scale
|
|
99
|
-
y = (y - this.height / 2) / this.scale
|
|
132
|
+
x = (x - this.width / 2 - this.ox) / this.scale
|
|
133
|
+
y = (y - this.height / 2 - this.oy) / this.scale
|
|
100
134
|
|
|
101
|
-
output = output || {}
|
|
102
135
|
output.x = c * x - s * y + this.x
|
|
103
136
|
output.y = s * x + c * y + this.y
|
|
104
137
|
|
|
105
138
|
return output
|
|
106
139
|
}
|
|
107
140
|
|
|
141
|
+
/**
|
|
142
|
+
* @param {number} x
|
|
143
|
+
* @param {number} y
|
|
144
|
+
* @param {{x: number, y: number}} [output]
|
|
145
|
+
* @returns {{x: number, y: number}}
|
|
146
|
+
*/
|
|
147
|
+
getCameraPoint(x, y, output = {}) {
|
|
148
|
+
const c = Math.cos(-this.rotation),
|
|
149
|
+
s = Math.sin(-this.rotation)
|
|
150
|
+
|
|
151
|
+
x = x - this.x
|
|
152
|
+
y = y - this.y
|
|
153
|
+
x = c * x - s * y
|
|
154
|
+
y = s * x + c * y
|
|
155
|
+
|
|
156
|
+
output.x = x * this.scale + this.width / 2 + this.ox
|
|
157
|
+
output.y = y * this.scale + this.height / 2 + this.oy
|
|
158
|
+
|
|
159
|
+
return output
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* @returns {number[]}
|
|
164
|
+
*/
|
|
165
|
+
getBounds() {
|
|
166
|
+
return [this.ox, this.oy, this.width, this.height]
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Check if a rect is inside of the camera.
|
|
171
|
+
*
|
|
172
|
+
* @param {number} x
|
|
173
|
+
* @param {number} y
|
|
174
|
+
* @param {number} width
|
|
175
|
+
* @param {number} height
|
|
176
|
+
* @returns {boolean}
|
|
177
|
+
*/
|
|
178
|
+
viewing(x, y, width, height) {
|
|
179
|
+
const cameraX = this.width / 2 - this.x
|
|
180
|
+
const cameraY = this.height / 2 - this.y
|
|
181
|
+
const cameraWidth = this.width / this.scale
|
|
182
|
+
const cameraHeight = this.height / this.scale
|
|
183
|
+
|
|
184
|
+
return this._engine.colrect(
|
|
185
|
+
x,
|
|
186
|
+
y,
|
|
187
|
+
width,
|
|
188
|
+
height,
|
|
189
|
+
cameraX,
|
|
190
|
+
cameraY,
|
|
191
|
+
cameraWidth,
|
|
192
|
+
cameraHeight
|
|
193
|
+
)
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* @param {number} amplitude
|
|
198
|
+
* @param {number} duration in seconds
|
|
199
|
+
*/
|
|
108
200
|
shake(amplitude = 1, duration = 0.3) {
|
|
109
201
|
if (this.shaking) return
|
|
110
202
|
|
|
@@ -126,6 +218,9 @@ export default class Camera {
|
|
|
126
218
|
}
|
|
127
219
|
}
|
|
128
220
|
|
|
221
|
+
/**
|
|
222
|
+
* @returns {boolean}
|
|
223
|
+
*/
|
|
129
224
|
get shaking() {
|
|
130
225
|
return this._shake.removeListener !== null
|
|
131
226
|
}
|