@litecanvas/utils 0.3.2 → 0.5.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/README.md +2 -0
- package/dist/actor.js +156 -0
- package/dist/actor.min.js +1 -0
- package/dist/all.js +317 -1
- package/dist/all.min.js +2 -1
- package/dist/grid.js +202 -0
- package/dist/grid.min.js +2 -0
- package/dist/vector.js +1 -1
- package/dist/vector.min.js +1 -1
- package/package.json +1 -1
- package/src/actor/README.md +140 -0
- package/src/actor/_web.js +3 -0
- package/src/actor/index.js +135 -0
- package/src/collision/README.md +2 -0
- package/src/grid/README.md +47 -0
- package/src/grid/_web.js +3 -0
- package/src/grid/index.js +205 -57
- package/src/index.js +2 -0
- package/src/vector/index.js +1 -1
package/dist/grid.js
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
(() => {
|
|
2
|
+
// src/grid/index.js
|
|
3
|
+
var Grid = class _Grid {
|
|
4
|
+
/** @type {number} The grid width */
|
|
5
|
+
_w;
|
|
6
|
+
/** @type {number} The grid height */
|
|
7
|
+
_h;
|
|
8
|
+
/** @type {any[]} The grid cells */
|
|
9
|
+
_c;
|
|
10
|
+
/**
|
|
11
|
+
* @static
|
|
12
|
+
* @param {number} width
|
|
13
|
+
* @param {number} height
|
|
14
|
+
* @param {any[]} values
|
|
15
|
+
*/
|
|
16
|
+
static fromArray(width, height, values) {
|
|
17
|
+
const grid = new _Grid(width, height);
|
|
18
|
+
for (let i = 0; i < values.length; i++) {
|
|
19
|
+
grid._c[i] = values[i];
|
|
20
|
+
}
|
|
21
|
+
return grid;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* @param {number} width The grid width
|
|
25
|
+
* @param {number} height The grid height
|
|
26
|
+
*/
|
|
27
|
+
constructor(width, height) {
|
|
28
|
+
this.width = width;
|
|
29
|
+
this.height = height;
|
|
30
|
+
this.clear();
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Delete all cell values.
|
|
34
|
+
*/
|
|
35
|
+
clear() {
|
|
36
|
+
this._c = Array(this._w * this._h);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* @param {number} value
|
|
40
|
+
*/
|
|
41
|
+
set width(value) {
|
|
42
|
+
this._w = Math.max(1, ~~value);
|
|
43
|
+
}
|
|
44
|
+
get width() {
|
|
45
|
+
return this._w;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* @param {number} value
|
|
49
|
+
*/
|
|
50
|
+
set height(value) {
|
|
51
|
+
this._h = Math.max(1, ~~value);
|
|
52
|
+
}
|
|
53
|
+
get height() {
|
|
54
|
+
return this._h;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The the value of a grid's cell.
|
|
58
|
+
*
|
|
59
|
+
* @param {number} x
|
|
60
|
+
* @param {number} y
|
|
61
|
+
* @param {any} value
|
|
62
|
+
*/
|
|
63
|
+
set(x, y, value) {
|
|
64
|
+
this._c[this.pointToIndex(x, y)] = value;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Returns the value of a grid's cell.
|
|
68
|
+
*
|
|
69
|
+
* @param {number} x
|
|
70
|
+
* @param {number} y
|
|
71
|
+
* @returns {any}
|
|
72
|
+
*/
|
|
73
|
+
get(x, y) {
|
|
74
|
+
return this._c[this.pointToIndex(x, y)];
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Returns true if the which cell has any value not equal to `null` or `undefined`.
|
|
78
|
+
*
|
|
79
|
+
* @param {number} x
|
|
80
|
+
* @param {number} y
|
|
81
|
+
* @returns {boolean}
|
|
82
|
+
*/
|
|
83
|
+
has(x, y) {
|
|
84
|
+
return this.get(x, y) != null;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Returns the total of cells.
|
|
88
|
+
*
|
|
89
|
+
* @returns {number}
|
|
90
|
+
*/
|
|
91
|
+
get length() {
|
|
92
|
+
return this._w * this._h;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Convert a grid point (X, Y) to a index.
|
|
96
|
+
*
|
|
97
|
+
* @param {number} x
|
|
98
|
+
* @param {number} y
|
|
99
|
+
* @returns {number} The index
|
|
100
|
+
*/
|
|
101
|
+
pointToIndex(x, y) {
|
|
102
|
+
return this.clampX(~~x) + this.clampY(~~y) * this._w;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Convert index to a grid point X.
|
|
106
|
+
*
|
|
107
|
+
* @param {number} index
|
|
108
|
+
* @returns {number}
|
|
109
|
+
*/
|
|
110
|
+
indexToPointX(index) {
|
|
111
|
+
return index % this._w;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Convert index to a grid point Y.
|
|
115
|
+
*
|
|
116
|
+
* @param {number} index
|
|
117
|
+
* @returns {number}
|
|
118
|
+
*/
|
|
119
|
+
indexToPointY(index) {
|
|
120
|
+
return Math.floor(index / this._w);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Loops over all grid cells.
|
|
124
|
+
*
|
|
125
|
+
* @callback GridForEachCallback
|
|
126
|
+
* @param {number} x
|
|
127
|
+
* @param {number} y
|
|
128
|
+
* @param {any} value
|
|
129
|
+
* @param {Grid} grid
|
|
130
|
+
* @returns {boolean?} returns `false` to stop/break the loop
|
|
131
|
+
*
|
|
132
|
+
* @param {GridForEachCallback} handler
|
|
133
|
+
* @param {boolean} [reverse=false]
|
|
134
|
+
*/
|
|
135
|
+
forEach(handler, reverse = false) {
|
|
136
|
+
let i = reverse ? this.length - 1 : 0, limit = reverse ? -1 : this.length, step = reverse ? -1 : 1;
|
|
137
|
+
while (i !== limit) {
|
|
138
|
+
const x = this.indexToPointX(i), y = this.indexToPointY(i), cellValue = this._c[i];
|
|
139
|
+
if (false === handler(x, y, cellValue, this)) break;
|
|
140
|
+
i += step;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* @param {*} value
|
|
145
|
+
*/
|
|
146
|
+
fill(value) {
|
|
147
|
+
this.forEach((x, y) => {
|
|
148
|
+
this.set(x, y, value);
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* @returns {Grid} the cloned grid
|
|
153
|
+
*/
|
|
154
|
+
clone() {
|
|
155
|
+
return _Grid.fromArray(this._w, this._h, this._c);
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* @param {number} y
|
|
159
|
+
* @returns {number}
|
|
160
|
+
*/
|
|
161
|
+
clampX(x) {
|
|
162
|
+
return _clamp(x, 0, this._w - 1);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* @param {number} y
|
|
166
|
+
* @returns {number}
|
|
167
|
+
*/
|
|
168
|
+
clampY(y) {
|
|
169
|
+
return _clamp(y, 0, this._h - 1);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Returns the cell values in a single array.
|
|
173
|
+
*
|
|
174
|
+
* @returns {any[]}
|
|
175
|
+
*/
|
|
176
|
+
toArray() {
|
|
177
|
+
return this._c.slice(0);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* @param {string} separator
|
|
181
|
+
* @param {boolean} format
|
|
182
|
+
* @returns {string}
|
|
183
|
+
*/
|
|
184
|
+
toString(separator = " ", format = true) {
|
|
185
|
+
if (!format) return this._c.join(separator);
|
|
186
|
+
const rows = [];
|
|
187
|
+
this.forEach((x, y, value) => {
|
|
188
|
+
rows[y] = rows[y] || "";
|
|
189
|
+
rows[y] += value + separator;
|
|
190
|
+
});
|
|
191
|
+
return rows.join("\n");
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
function _clamp(value, min, max) {
|
|
195
|
+
if (value < min) return min;
|
|
196
|
+
if (value > max) return max;
|
|
197
|
+
return value;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// src/grid/_web.js
|
|
201
|
+
globalThis.utils = Object.assign(globalThis.utils || {}, { Grid });
|
|
202
|
+
})();
|
package/dist/grid.min.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
(()=>{var e=class s{_w;_h;_c;static fromArray(t,i,h){let n=new s(t,i);for(let r=0;r<h.length;r++)n._c[r]=h[r];return n}constructor(t,i){this.width=t,this.height=i,this.clear()}clear(){this._c=Array(this._w*this._h)}set width(t){this._w=Math.max(1,~~t)}get width(){return this._w}set height(t){this._h=Math.max(1,~~t)}get height(){return this._h}set(t,i,h){this._c[this.pointToIndex(t,i)]=h}get(t,i){return this._c[this.pointToIndex(t,i)]}has(t,i){return this.get(t,i)!=null}get length(){return this._w*this._h}pointToIndex(t,i){return this.clampX(~~t)+this.clampY(~~i)*this._w}indexToPointX(t){return t%this._w}indexToPointY(t){return Math.floor(t/this._w)}forEach(t,i=!1){let h=i?this.length-1:0,n=i?-1:this.length,r=i?-1:1;for(;h!==n;){let o=this.indexToPointX(h),c=this.indexToPointY(h),_=this._c[h];if(t(o,c,_,this)===!1)break;h+=r}}fill(t){this.forEach((i,h)=>{this.set(i,h,t)})}clone(){return s.fromArray(this._w,this._h,this._c)}clampX(t){return l(t,0,this._w-1)}clampY(t){return l(t,0,this._h-1)}toArray(){return this._c.slice(0)}toString(t=" ",i=!0){if(!i)return this._c.join(t);let h=[];return this.forEach((n,r,o)=>{h[r]=h[r]||"",h[r]+=o+t}),h.join(`
|
|
2
|
+
`)}};function l(s,t,i){return s<t?t:s>i?i:s}globalThis.utils=Object.assign(globalThis.utils||{},{Grid:e});})();
|
package/dist/vector.js
CHANGED
package/dist/vector.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var M=Object.defineProperty;var g=(t,o)=>{for(var s in o)M(t,s,{get:o[s],enumerable:!0})};var i={};g(i,{DOWN:()=>G,LEFT:()=>H,ONE:()=>w,RIGHT:()=>F,UP:()=>D,Vector:()=>n,ZERO:()=>j,isvector:()=>r,vec:()=>c,vecadd:()=>l,vecconfig:()=>
|
|
1
|
+
(()=>{var M=Object.defineProperty;var g=(t,o)=>{for(var s in o)M(t,s,{get:o[s],enumerable:!0})};var i={};g(i,{DOWN:()=>G,LEFT:()=>H,ONE:()=>w,RIGHT:()=>F,UP:()=>D,Vector:()=>n,ZERO:()=>j,isvector:()=>r,vec:()=>c,vecadd:()=>l,vecconfig:()=>y,veccopy:()=>m,veccross:()=>R,vecdir:()=>N,vecdist:()=>E,vecdist2:()=>I,vecdiv:()=>x,vecdot:()=>P,veceq:()=>a,veclerp:()=>U,veclimit:()=>O,vecmag:()=>u,vecmag2:()=>f,vecmult:()=>p,vecnorm:()=>T,vecrand:()=>$,vecrot:()=>q,vecset:()=>d,vecsub:()=>h});var n=class{x;y;constructor(o=0,s=o){this.x=o,this.y=s}toString(){return`Vector (${this.x}, ${this.y})`}},c=(t=0,o=t)=>new n(t,o),a=(t,o,s=o)=>r(o)?a(t,o.x,o.y):t.x===o&&t.y===s,m=t=>c(t.x,t.y),d=(t,o,s=o)=>{r(o)?d(t,o.x,o.y):(t.x=o,t.y=s)},l=(t,o,s=o)=>{r(o)?l(t,o.x,o.y):(t.x+=o,t.y+=s)},h=(t,o,s=o)=>{r(o)?h(t,o.x,o.y):(t.x-=o,t.y-=s)},p=(t,o,s=o)=>{r(o)?p(t,o.x,o.y):(t.x*=o,t.y*=s)},x=(t,o,s=o)=>{r(o)?x(t,o.x,o.y):(t.x/=o,t.y/=s)},q=(t,o)=>{let s=Math.cos(o),e=Math.sin(o);t.x=s*t.x-e*t.y,t.y=e*t.x+s*t.y},u=t=>Math.sqrt(t.x*t.x+t.y*t.y),f=t=>t.x*t.x+t.y*t.y,T=t=>{let o=u(t);o>0&&x(t,o)},O=(t,o)=>{let s=f(t);s>o*o&&(x(t,Math.sqrt(s)),p(t,o))},E=(t,o)=>{let s=t.x-o.x,e=t.y-o.y;return Math.sqrt(s*s+e*e)},I=(t,o)=>{let s=t.x-o.x,e=t.y-o.y;return s*s+e*e},N=t=>Math.atan2(t.y,t.x),P=(t,o)=>t.x*o.x+t.y*o.y,R=(t,o)=>t.x*o.y-t.y*o.x,U=(t,o,s)=>{t.x+=(o.x-t.x)*s||0,t.y+=(o.y-t.y)*s||0},$=(t=1,o=t)=>{let s=y.random()*2*Math.PI,e=y.random()*(o-t)+t;return c(Math.cos(s)*e,Math.sin(s)*e)},r=t=>t instanceof n,y={random:()=>globalThis.rand?rand():Math.random()},j=c(0,0),w=c(1,1),D=c(0,-1),F=c(1,0),G=c(0,1),H=c(-1,0);globalThis.utils=Object.assign(globalThis.utils||{},i);})();
|
package/package.json
CHANGED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Actor
|
|
2
|
+
|
|
3
|
+
**CDN**: https://unpkg.com/@litecanvas/utils/dist/actor.js
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```js
|
|
8
|
+
import litecanvas from "@litecanvas"
|
|
9
|
+
import { Actor } from "@litecanvas/utils"
|
|
10
|
+
|
|
11
|
+
let player, mySprite
|
|
12
|
+
|
|
13
|
+
litecanvas({
|
|
14
|
+
loop: { init, tapped, draw },
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
// create a sprite image
|
|
18
|
+
mySprite = paint(3, 3, ["303", "030", "303"], { scale: 10 })
|
|
19
|
+
|
|
20
|
+
function init() {
|
|
21
|
+
// create a actor
|
|
22
|
+
player = new Actor(mySprite)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function tapped(tapx, tapy) {
|
|
26
|
+
// update the actor position
|
|
27
|
+
player.x = tapx
|
|
28
|
+
player.y = tapy
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function draw() {
|
|
32
|
+
cls(0)
|
|
33
|
+
|
|
34
|
+
// draw the actor sprite
|
|
35
|
+
player.draw()
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Actor#x / Actor#y
|
|
40
|
+
|
|
41
|
+
Set or get the actor position
|
|
42
|
+
|
|
43
|
+
```js
|
|
44
|
+
player.x = 100
|
|
45
|
+
player.y = 200
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Actor#scale
|
|
49
|
+
|
|
50
|
+
Set or get the actor scale/size
|
|
51
|
+
|
|
52
|
+
```js
|
|
53
|
+
// twice bigger
|
|
54
|
+
player.scale.x = 2
|
|
55
|
+
player.scale.y = 2
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Actor#anchor
|
|
59
|
+
|
|
60
|
+
Set or get the actor anchor (origin). By default, the anchor is a vector `(0, 0)` (meaning anchor Top Left).
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
// position the sprite based on their center
|
|
64
|
+
player.anchor.x = 0.5
|
|
65
|
+
player.anchor.y = 0.5
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
```js
|
|
69
|
+
// alternatively
|
|
70
|
+
import { ANCHOR_CENTER } from "@litecanvas/utils"
|
|
71
|
+
|
|
72
|
+
player.anchor = ANCHOR_CENTER
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
> Note:
|
|
76
|
+
> You can import and use the following constants to help you choose an actor anchor: , `ANCHOR_TOP_LEFT` (default), `ANCHOR_TOP_RIGHT`, `ANCHOR_BOT_LEFT`, `ANCHOR_BOT_RIGHT` or `ANCHOR_CENTER`.
|
|
77
|
+
|
|
78
|
+
## Actor#angle
|
|
79
|
+
|
|
80
|
+
Set or get the actor angle (in radians).
|
|
81
|
+
|
|
82
|
+
```js
|
|
83
|
+
player.angle = HALF_PI / 2 // 45 degrees
|
|
84
|
+
|
|
85
|
+
// or use the litecanvas' `deg2rad()` helper
|
|
86
|
+
player.angle = deg2rad(45)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Actor#opacity
|
|
90
|
+
|
|
91
|
+
Set or get the actor opacity (alpha).
|
|
92
|
+
|
|
93
|
+
```js
|
|
94
|
+
player.opacity = 0.5 // 50% transparent
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Actor#hidden
|
|
98
|
+
|
|
99
|
+
Set or get the actor hidden (`boolean`) state.
|
|
100
|
+
|
|
101
|
+
```js
|
|
102
|
+
player.hidden = true // hides the actor image
|
|
103
|
+
player.hidden = false // display the actor image
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Actor#width
|
|
107
|
+
|
|
108
|
+
Get (not set) the actor current width.
|
|
109
|
+
|
|
110
|
+
```js
|
|
111
|
+
console.log(player.width) // => 30
|
|
112
|
+
|
|
113
|
+
player.scale.x = 1.5
|
|
114
|
+
|
|
115
|
+
console.log(player.width) // => 45
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Actor#height
|
|
119
|
+
|
|
120
|
+
Get (not set) the actor current height.
|
|
121
|
+
|
|
122
|
+
```js
|
|
123
|
+
console.log(player.height) // => 30
|
|
124
|
+
|
|
125
|
+
player.scale.x = 2
|
|
126
|
+
|
|
127
|
+
console.log(player.height) // => 60
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Actor#sprite
|
|
131
|
+
|
|
132
|
+
Set or get the actor sprite image. Useful to make animations.
|
|
133
|
+
|
|
134
|
+
```js
|
|
135
|
+
player.sprite = anotherSprite
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
> The actor sprite must be a `Image`, `HTMLCanvas` or `OffscreenCanvas`.
|
|
139
|
+
>
|
|
140
|
+
> Remember, you can create a image using the litecanvas' `paint()` built-in helper or [load a image](https://github.com/litecanvas/plugin-asset-loader?tab=readme-ov-file#loading-images) with plugins.
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { Vector, vec, veccopy } from "../vector/index.js"
|
|
2
|
+
import "litecanvas"
|
|
3
|
+
|
|
4
|
+
export const ANCHOR_CENTER = vec(0.5, 0.5)
|
|
5
|
+
export const ANCHOR_TOP_LEFT = vec(0, 0)
|
|
6
|
+
export const ANCHOR_TOP_RIGHT = vec(1, 0)
|
|
7
|
+
export const ANCHOR_BOT_LEFT = vec(0, 1)
|
|
8
|
+
export const ANCHOR_BOT_RIGHT = vec(1, 1)
|
|
9
|
+
|
|
10
|
+
export class Actor {
|
|
11
|
+
/** @type {Image|HTMLCanvasElement|OffscreenCanvas} */
|
|
12
|
+
sprite
|
|
13
|
+
|
|
14
|
+
/** @type {Vector} The actor position */
|
|
15
|
+
_p
|
|
16
|
+
|
|
17
|
+
/** @type {Vector} The actor anchor (origin) */
|
|
18
|
+
_o
|
|
19
|
+
|
|
20
|
+
/** @type {Vector} The actor scale */
|
|
21
|
+
_s
|
|
22
|
+
|
|
23
|
+
/** @type {number} The actor angle (in radians) */
|
|
24
|
+
angle = 0
|
|
25
|
+
|
|
26
|
+
/** @type {number} The actor opacity */
|
|
27
|
+
opacity = 1
|
|
28
|
+
|
|
29
|
+
/** @type {boolean} If `true` the actor will not be drawn. */
|
|
30
|
+
hidden = false
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* @param {Image|HTMLCanvasElement|OffscreenCanvas} sprite
|
|
34
|
+
* @param {Vector} position
|
|
35
|
+
*/
|
|
36
|
+
constructor(sprite, position) {
|
|
37
|
+
this.sprite = sprite
|
|
38
|
+
this._p = position || vec(0)
|
|
39
|
+
this._o = veccopy(ANCHOR_TOP_LEFT)
|
|
40
|
+
this._s = vec(1, 1)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @param {number}
|
|
45
|
+
*/
|
|
46
|
+
set x(value) {
|
|
47
|
+
this._p.x = value
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @returns {number}
|
|
52
|
+
*/
|
|
53
|
+
get x() {
|
|
54
|
+
return this._p.x
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* @param {number}
|
|
59
|
+
*/
|
|
60
|
+
set y(value) {
|
|
61
|
+
this._p.y = value
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @returns {number}
|
|
66
|
+
*/
|
|
67
|
+
get y() {
|
|
68
|
+
return this._p.y
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* @param {Vector}
|
|
73
|
+
*/
|
|
74
|
+
set anchor(vec) {
|
|
75
|
+
this._o.x = vec.x
|
|
76
|
+
this._o.y = vec.y
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @returns {Vector}
|
|
81
|
+
*/
|
|
82
|
+
get anchor() {
|
|
83
|
+
return this._o
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @returns {number}
|
|
88
|
+
*/
|
|
89
|
+
get width() {
|
|
90
|
+
return this.sprite.width * this._s.y
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @returns {number}
|
|
95
|
+
*/
|
|
96
|
+
get height() {
|
|
97
|
+
return this.sprite.height * this._s.y
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* @retuns {Vector}
|
|
102
|
+
*/
|
|
103
|
+
get scale() {
|
|
104
|
+
return this._s
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Update the transformation matrix, sets the opacity and draw the actor sprite image.
|
|
109
|
+
*
|
|
110
|
+
* @param {LitecanvasInstance} [litecanvas]
|
|
111
|
+
*/
|
|
112
|
+
draw(litecanvas = globalThis) {
|
|
113
|
+
if (this.hidden || this.opacity <= 0) return
|
|
114
|
+
|
|
115
|
+
litecanvas.push()
|
|
116
|
+
|
|
117
|
+
this.transform(litecanvas)
|
|
118
|
+
|
|
119
|
+
const anchorX = this.sprite.width * this.anchor.x
|
|
120
|
+
const anchorY = this.sprite.height * this.anchor.y
|
|
121
|
+
litecanvas.image(-anchorX, -anchorY, this.sprite)
|
|
122
|
+
|
|
123
|
+
litecanvas.pop()
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* @param {LitecanvasInstance} litecanvas
|
|
128
|
+
*/
|
|
129
|
+
transform(litecanvas) {
|
|
130
|
+
litecanvas.translate(this._p.x, this._p.y)
|
|
131
|
+
litecanvas.rotate(this.angle)
|
|
132
|
+
litecanvas.scale(this._s.x, this._s.y)
|
|
133
|
+
litecanvas.alpha(this.opacity)
|
|
134
|
+
}
|
|
135
|
+
}
|
package/src/collision/README.md
CHANGED
|
@@ -40,6 +40,8 @@ function draw() {
|
|
|
40
40
|
|
|
41
41
|
Syntax: `resolve(x1, y1, w1, h1, x2, y2, w2, h2): { direction: string, x: number, y: number }`
|
|
42
42
|
|
|
43
|
+
> Note: possible values for `direction` is `"top"`, `"botton"`, `"left"`, `"right"` or `""` (empty string, if no collision).
|
|
44
|
+
|
|
43
45
|
```js
|
|
44
46
|
import litecanvas from "litecanvas"
|
|
45
47
|
import { resolve } from "@litecanvas/utils"
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Grid
|
|
2
|
+
|
|
3
|
+
**CDN**: https://unpkg.com/@litecanvas/utils/dist/grid.js
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
Lets build an arena with [ASCII graphics](https://en.wikipedia.org/wiki/ASCII_art) like in classic roguelikes.
|
|
8
|
+
|
|
9
|
+
```js
|
|
10
|
+
import { Grid } from "@litecanvas/utils"
|
|
11
|
+
|
|
12
|
+
// make a grid 13x13
|
|
13
|
+
let grid = new Grid(13, 13)
|
|
14
|
+
|
|
15
|
+
// fill the entire grid with "."
|
|
16
|
+
grid.fill(".")
|
|
17
|
+
|
|
18
|
+
// put a '@' in the middle
|
|
19
|
+
grid.set(grid.width / 2, grid.height / 2, "@")
|
|
20
|
+
|
|
21
|
+
// put '#' around the grid
|
|
22
|
+
grid.forEach((x, y, cellValue) => {
|
|
23
|
+
if (x === 0 || y === 0 || x === grid.width - 1 || y === grid.height - 1) {
|
|
24
|
+
grid.set(x, y, "#")
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
document.body.innerHTML = "<pre>" + grid.toString() + "</pre>"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The result:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
# # # # # # # # # # # # #
|
|
35
|
+
# . . . . . . . . . . . #
|
|
36
|
+
# . . . . . . . . . . . #
|
|
37
|
+
# . . . . . . . . . . . #
|
|
38
|
+
# . . . . . . . . . . . #
|
|
39
|
+
# . . . . . . . . . . . #
|
|
40
|
+
# . . . . . @ . . . . . #
|
|
41
|
+
# . . . . . . . . . . . #
|
|
42
|
+
# . . . . . . . . . . . #
|
|
43
|
+
# . . . . . . . . . . . #
|
|
44
|
+
# . . . . . . . . . . . #
|
|
45
|
+
# . . . . . . . . . . . #
|
|
46
|
+
# # # # # # # # # # # # #
|
|
47
|
+
```
|
package/src/grid/_web.js
ADDED