fruta 0.0.4 → 0.1.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/LICENSE +21 -21
- package/README.md +368 -30
- package/dist/animation/anim.d.ts +13 -0
- package/dist/animation/animate.d.ts +101 -0
- package/dist/audio/audio.d.ts +29 -0
- package/dist/fruta.d.ts +302 -0
- package/dist/fruta.js +19 -0
- package/dist/frutaGl.d.ts +277 -0
- package/dist/game/behaviors.d.ts +38 -0
- package/dist/game/charts.d.ts +127 -0
- package/dist/game/play.d.ts +4 -0
- package/dist/game/project.d.ts +54 -0
- package/dist/input/gamepad.d.ts +38 -0
- package/dist/math/math.d.ts +37 -0
- package/dist/math/pathfind.d.ts +7 -0
- package/dist/math/physics.d.ts +38 -0
- package/dist/math/pool.d.ts +11 -0
- package/dist/math/spatial.d.ts +10 -0
- package/dist/render/create/FontCreator.d.ts +16 -0
- package/dist/render/create/SaveRestore.d.ts +5 -0
- package/dist/render/create/ShapeCreator.d.ts +49 -0
- package/dist/render/create/canvasTarget.d.ts +5 -0
- package/dist/render/shaders.d.ts +29 -0
- package/dist/render/webgl.d.ts +67 -0
- package/dist/renderer.d.ts +42 -0
- package/dist/types.d.ts +9 -0
- package/dist/utils/logStyle.d.ts +1 -0
- package/dist/world/camera.d.ts +24 -0
- package/dist/world/entities.d.ts +45 -0
- package/dist/world/particles.d.ts +42 -0
- package/dist/world/tilemap.d.ts +44 -0
- package/dist/world/timers.d.ts +11 -0
- package/package.json +35 -35
- package/DOCUMENTATION.MD +0 -874
- package/dist/main.js +0 -1
- package/index.html +0 -9
- package/settings.json +0 -6
- package/src/core/create/_fontCreator.js +0 -11
- package/src/core/create/_saveOrRestore.js +0 -22
- package/src/core/create/_shapeCreator.js +0 -20
- package/src/core/create/fontCreatorMixin.js +0 -167
- package/src/core/create/shapeCreatorMixin.js +0 -656
- package/src/core/fruta.js +0 -22
- package/src/core/game/game.js +0 -30
- package/src/core/game/scene.js +0 -29
- package/src/core/game/tick.js +0 -42
- package/src/core/utils/logStyle.js +0 -8
- package/src/core/utils/utils.js +0 -0
- package/src/methods/constants.js +0 -0
- package/src/methods/creator/_scene.js +0 -0
- package/src/methods/creator/creator.js +0 -0
- package/webpack.config.js +0 -47
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import CanvasTarget from './canvasTarget';
|
|
2
|
+
export default class ShapeCreator extends CanvasTarget {
|
|
3
|
+
fillStyleShape(style: string | CanvasGradient | CanvasPattern): this;
|
|
4
|
+
drawRectShape(clear?: [number, number, number, number], fill?: [number, number, number, number], stroke?: [number, number, number, number]): this;
|
|
5
|
+
roundRectShape(x: number, y: number, width: number, height: number, radius: number | number[]): this;
|
|
6
|
+
startShape(): this;
|
|
7
|
+
strokeShape(path?: Path2D): this;
|
|
8
|
+
moveTo(x: number, y: number): this;
|
|
9
|
+
lineTo(x: number, y: number): this;
|
|
10
|
+
fillShape(fillRule?: CanvasFillRule): this;
|
|
11
|
+
arcShape(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean): this;
|
|
12
|
+
quadraticCurveTo(cpx: number, cpy: number, x: number, y: number): this;
|
|
13
|
+
bezierCurveTo(cp1x: number, cp1y: number, cp2x: number, cp2y: number, x: number, y: number): this;
|
|
14
|
+
arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): this;
|
|
15
|
+
path2DShape(path?: Path2D | string): Path2D;
|
|
16
|
+
domMatrixShape(): DOMMatrix;
|
|
17
|
+
addPathShape(callerPath: Path2D, path: Path2D, transform?: DOMMatrix2DInit): Path2D;
|
|
18
|
+
ellipseShape(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise?: boolean): this;
|
|
19
|
+
createLinearGradient(x0: number, y0: number, x1: number, y1: number): CanvasGradient;
|
|
20
|
+
createRadialGradient(x0: number, y0: number, r0: number, x1: number, y1: number, r1: number): CanvasGradient;
|
|
21
|
+
addColorStop(gradient: CanvasGradient, stops: Array<{
|
|
22
|
+
color: string;
|
|
23
|
+
}>): this;
|
|
24
|
+
createPattern(image: CanvasImageSource, repetition?: string | null): CanvasPattern | null;
|
|
25
|
+
lineCapShape(style: CanvasLineCap): this;
|
|
26
|
+
lineJoinShape(style: CanvasLineJoin): this;
|
|
27
|
+
lineWidthShape(width: number): this;
|
|
28
|
+
miterLimitShape(limit: number): this;
|
|
29
|
+
shadowBlurOfShape(size: number): this;
|
|
30
|
+
shadowColorOfShape(style: string): this;
|
|
31
|
+
shadowOffSetXY(x: number, y: number): this;
|
|
32
|
+
strokeStyle(style: string | CanvasGradient | CanvasPattern): this;
|
|
33
|
+
scaleShape(x: number, y: number): this;
|
|
34
|
+
rotateShape(angle: number): this;
|
|
35
|
+
translateShape(x: number, y: number): this;
|
|
36
|
+
transformShape(a: number, b: number, c: number, d: number, e: number, f: number): this;
|
|
37
|
+
setTransformShape(a: number, b: number, c: number, d: number, e: number, f: number): this;
|
|
38
|
+
globalAlpha(alpha: number): this;
|
|
39
|
+
globalCompositeOperation(composition: GlobalCompositeOperation): this;
|
|
40
|
+
clipShape(): this;
|
|
41
|
+
shadowColor(color: string): this;
|
|
42
|
+
createImage(config: {
|
|
43
|
+
src: string;
|
|
44
|
+
img: number[];
|
|
45
|
+
}): this;
|
|
46
|
+
createImageData(sw: number, sh: number): ImageData;
|
|
47
|
+
getImgData(sx: number, sy: number, sw: number, sh: number): ImageData;
|
|
48
|
+
putImageData(imageData: ImageData, dx: number, dy: number): this;
|
|
49
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export declare const Shaders: {
|
|
2
|
+
grayscale: string;
|
|
3
|
+
invert: string;
|
|
4
|
+
sepia: string;
|
|
5
|
+
tint: string;
|
|
6
|
+
brightness: string;
|
|
7
|
+
posterize: string;
|
|
8
|
+
threshold: string;
|
|
9
|
+
scanlines: string;
|
|
10
|
+
crt: string;
|
|
11
|
+
vhs: string;
|
|
12
|
+
pixelate: string;
|
|
13
|
+
noise: string;
|
|
14
|
+
glitch: string;
|
|
15
|
+
chromatic: string;
|
|
16
|
+
wave: string;
|
|
17
|
+
fisheye: string;
|
|
18
|
+
mirror: string;
|
|
19
|
+
shockwave: string;
|
|
20
|
+
blur: string;
|
|
21
|
+
sharpen: string;
|
|
22
|
+
bloom: string;
|
|
23
|
+
dream: string;
|
|
24
|
+
edge: string;
|
|
25
|
+
vignette: string;
|
|
26
|
+
nightvision: string;
|
|
27
|
+
};
|
|
28
|
+
export type ShaderName = keyof typeof Shaders;
|
|
29
|
+
export declare const ShaderDefaults: Partial<Record<ShaderName, Record<string, number | number[]>>>;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export interface QuadOptions {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
w: number;
|
|
5
|
+
h: number;
|
|
6
|
+
rotation?: number;
|
|
7
|
+
color?: string | [number, number, number, number];
|
|
8
|
+
alpha?: number;
|
|
9
|
+
u0?: number;
|
|
10
|
+
v0?: number;
|
|
11
|
+
u1?: number;
|
|
12
|
+
v1?: number;
|
|
13
|
+
}
|
|
14
|
+
export declare class WebGLBatch {
|
|
15
|
+
readonly canvas: HTMLCanvasElement;
|
|
16
|
+
private gl;
|
|
17
|
+
private prog;
|
|
18
|
+
private buf;
|
|
19
|
+
private data;
|
|
20
|
+
private count;
|
|
21
|
+
private textures;
|
|
22
|
+
private white;
|
|
23
|
+
private currentTex;
|
|
24
|
+
private loc;
|
|
25
|
+
constructor(canvas: HTMLCanvasElement);
|
|
26
|
+
private makeTexture;
|
|
27
|
+
texture(name: string, source: TexImageSource): void;
|
|
28
|
+
getTexture(name: string): {
|
|
29
|
+
tex: WebGLTexture;
|
|
30
|
+
w: number;
|
|
31
|
+
h: number;
|
|
32
|
+
} | null;
|
|
33
|
+
removeTexture(name: string): void;
|
|
34
|
+
get whiteTexture(): WebGLTexture;
|
|
35
|
+
pushQuad(tex: WebGLTexture, c: [number, number, number, number, number, number, number, number], uv: [number, number, number, number], r: number, g: number, b: number, a: number): void;
|
|
36
|
+
resize(w: number, h: number): void;
|
|
37
|
+
clear(r?: number, g?: number, b?: number, a?: number): void;
|
|
38
|
+
rect(o: QuadOptions): void;
|
|
39
|
+
sprite(name: string, o: QuadOptions): void;
|
|
40
|
+
private quad;
|
|
41
|
+
flush(): void;
|
|
42
|
+
}
|
|
43
|
+
export type Uniforms = Record<string, number | [number, number] | [number, number, number]>;
|
|
44
|
+
export declare class PostFX {
|
|
45
|
+
private readonly canvas;
|
|
46
|
+
private gl;
|
|
47
|
+
private fbo;
|
|
48
|
+
private tex;
|
|
49
|
+
private quad;
|
|
50
|
+
private w;
|
|
51
|
+
private h;
|
|
52
|
+
private programs;
|
|
53
|
+
private current;
|
|
54
|
+
constructor(canvas: HTMLCanvasElement);
|
|
55
|
+
private resize;
|
|
56
|
+
setEffect(fragment: string): void;
|
|
57
|
+
begin(): void;
|
|
58
|
+
end(uniforms: Uniforms, time: number): void;
|
|
59
|
+
}
|
|
60
|
+
export declare class Shader {
|
|
61
|
+
readonly canvas: HTMLCanvasElement;
|
|
62
|
+
private gl;
|
|
63
|
+
private prog;
|
|
64
|
+
private buf;
|
|
65
|
+
constructor(canvas: HTMLCanvasElement, fragment: string);
|
|
66
|
+
draw(time: number, uniforms?: Record<string, number | [number, number]>): void;
|
|
67
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export interface Drawer {
|
|
2
|
+
rect(o: {
|
|
3
|
+
x: number;
|
|
4
|
+
y: number;
|
|
5
|
+
w: number;
|
|
6
|
+
h: number;
|
|
7
|
+
fill?: string;
|
|
8
|
+
rotation?: number;
|
|
9
|
+
radius?: number;
|
|
10
|
+
alpha?: number;
|
|
11
|
+
}): unknown;
|
|
12
|
+
circle(o: {
|
|
13
|
+
x: number;
|
|
14
|
+
y: number;
|
|
15
|
+
r: number;
|
|
16
|
+
fill?: string;
|
|
17
|
+
alpha?: number;
|
|
18
|
+
}): unknown;
|
|
19
|
+
ellipse(o: {
|
|
20
|
+
x: number;
|
|
21
|
+
y: number;
|
|
22
|
+
rx: number;
|
|
23
|
+
ry: number;
|
|
24
|
+
rotation?: number;
|
|
25
|
+
fill?: string;
|
|
26
|
+
alpha?: number;
|
|
27
|
+
}): unknown;
|
|
28
|
+
sprite(name: string, o: {
|
|
29
|
+
x: number;
|
|
30
|
+
y: number;
|
|
31
|
+
w?: number;
|
|
32
|
+
h?: number;
|
|
33
|
+
frame?: number;
|
|
34
|
+
frameW?: number;
|
|
35
|
+
frameH?: number;
|
|
36
|
+
cols?: number;
|
|
37
|
+
rotation?: number;
|
|
38
|
+
flipX?: boolean;
|
|
39
|
+
anchor?: 'topleft' | 'center';
|
|
40
|
+
alpha?: number;
|
|
41
|
+
}): unknown;
|
|
42
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const consoleStyle: (message: string) => void;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare class Camera {
|
|
2
|
+
private readonly canvas;
|
|
3
|
+
private readonly ctx;
|
|
4
|
+
x: number;
|
|
5
|
+
y: number;
|
|
6
|
+
zoom: number;
|
|
7
|
+
private shakeAmt;
|
|
8
|
+
private shakeLeft;
|
|
9
|
+
private shakeDur;
|
|
10
|
+
constructor(canvas: HTMLCanvasElement, ctx: CanvasRenderingContext2D);
|
|
11
|
+
shake(strength: number, duration?: number): void;
|
|
12
|
+
tick(dt: number): void;
|
|
13
|
+
follow(target: {
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
}, smooth?: number): void;
|
|
17
|
+
clamp(minX: number, minY: number, maxX: number, maxY: number): void;
|
|
18
|
+
begin(): void;
|
|
19
|
+
end(): void;
|
|
20
|
+
screenToWorld(px: number, py: number): {
|
|
21
|
+
x: number;
|
|
22
|
+
y: number;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { Drawer } from '../renderer';
|
|
2
|
+
export interface EntitySpec {
|
|
3
|
+
x: number;
|
|
4
|
+
y: number;
|
|
5
|
+
w?: number;
|
|
6
|
+
h?: number;
|
|
7
|
+
vx?: number;
|
|
8
|
+
vy?: number;
|
|
9
|
+
gravity?: number;
|
|
10
|
+
sprite?: string;
|
|
11
|
+
shape?: 'rect' | 'circle';
|
|
12
|
+
color?: string;
|
|
13
|
+
r?: number;
|
|
14
|
+
radius?: number;
|
|
15
|
+
rotation?: number;
|
|
16
|
+
flipX?: boolean;
|
|
17
|
+
frame?: number;
|
|
18
|
+
frameW?: number;
|
|
19
|
+
frameH?: number;
|
|
20
|
+
cols?: number;
|
|
21
|
+
anchor?: 'topleft' | 'center';
|
|
22
|
+
bounds?: 'bounce' | 'wrap';
|
|
23
|
+
update?: (self: Entity, dt: number, time: number) => void;
|
|
24
|
+
[key: string]: unknown;
|
|
25
|
+
}
|
|
26
|
+
export type Entity = EntitySpec & {
|
|
27
|
+
w: number;
|
|
28
|
+
h: number;
|
|
29
|
+
vx: number;
|
|
30
|
+
vy: number;
|
|
31
|
+
alive: boolean;
|
|
32
|
+
remove(): void;
|
|
33
|
+
};
|
|
34
|
+
export declare class Entities {
|
|
35
|
+
private readonly app;
|
|
36
|
+
private list;
|
|
37
|
+
constructor(app: Drawer);
|
|
38
|
+
get count(): number;
|
|
39
|
+
add(spec: EntitySpec): Entity;
|
|
40
|
+
update(dt: number, time: number, bw?: number, bh?: number): void;
|
|
41
|
+
private edges;
|
|
42
|
+
draw(): void;
|
|
43
|
+
all(): Entity[];
|
|
44
|
+
clear(): void;
|
|
45
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export interface BurstOptions {
|
|
2
|
+
x: number;
|
|
3
|
+
y: number;
|
|
4
|
+
count?: number;
|
|
5
|
+
color?: string | string[];
|
|
6
|
+
speed?: number | [number, number];
|
|
7
|
+
spread?: number;
|
|
8
|
+
direction?: number;
|
|
9
|
+
life?: number;
|
|
10
|
+
size?: number;
|
|
11
|
+
gravity?: number;
|
|
12
|
+
fade?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface EmitterOptions extends BurstOptions {
|
|
15
|
+
rate?: number;
|
|
16
|
+
}
|
|
17
|
+
export interface Emitter {
|
|
18
|
+
x: number;
|
|
19
|
+
y: number;
|
|
20
|
+
active: boolean;
|
|
21
|
+
stop(): void;
|
|
22
|
+
}
|
|
23
|
+
export declare class Particles {
|
|
24
|
+
private list;
|
|
25
|
+
private emitters;
|
|
26
|
+
get count(): number;
|
|
27
|
+
get busy(): boolean;
|
|
28
|
+
emit(opts: EmitterOptions): Emitter;
|
|
29
|
+
burst(o: BurstOptions): void;
|
|
30
|
+
update(dt: number): void;
|
|
31
|
+
draw(ctx: CanvasRenderingContext2D): void;
|
|
32
|
+
drawWith(d: {
|
|
33
|
+
circle(o: {
|
|
34
|
+
x: number;
|
|
35
|
+
y: number;
|
|
36
|
+
r: number;
|
|
37
|
+
fill?: string;
|
|
38
|
+
alpha?: number;
|
|
39
|
+
}): unknown;
|
|
40
|
+
}): void;
|
|
41
|
+
clear(): void;
|
|
42
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { Drawer } from '../renderer';
|
|
2
|
+
import { type Cell } from '../math/pathfind';
|
|
3
|
+
export interface TileDef {
|
|
4
|
+
solid?: boolean;
|
|
5
|
+
color?: string;
|
|
6
|
+
sprite?: string;
|
|
7
|
+
frame?: number;
|
|
8
|
+
}
|
|
9
|
+
export interface Body {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
w: number;
|
|
13
|
+
h: number;
|
|
14
|
+
vx: number;
|
|
15
|
+
vy: number;
|
|
16
|
+
onGround?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface TilemapConfig {
|
|
19
|
+
data: string[];
|
|
20
|
+
size: number;
|
|
21
|
+
tiles: Record<string, TileDef>;
|
|
22
|
+
bevel?: boolean;
|
|
23
|
+
}
|
|
24
|
+
export declare class Tilemap {
|
|
25
|
+
private readonly app;
|
|
26
|
+
readonly size: number;
|
|
27
|
+
private grid;
|
|
28
|
+
private defs;
|
|
29
|
+
private bevel;
|
|
30
|
+
constructor(config: TilemapConfig, app: Drawer);
|
|
31
|
+
get cols(): number;
|
|
32
|
+
get rows(): number;
|
|
33
|
+
get width(): number;
|
|
34
|
+
get height(): number;
|
|
35
|
+
at(tx: number, ty: number): string;
|
|
36
|
+
set(tx: number, ty: number, char: string): void;
|
|
37
|
+
isSolid(tx: number, ty: number): boolean;
|
|
38
|
+
path(start: Cell, goal: Cell, opts?: {
|
|
39
|
+
diagonal?: boolean;
|
|
40
|
+
}): Cell[] | null;
|
|
41
|
+
draw(): void;
|
|
42
|
+
move(body: Body, dt: number): void;
|
|
43
|
+
private resolve;
|
|
44
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface TimerHandle {
|
|
2
|
+
cancel(): void;
|
|
3
|
+
}
|
|
4
|
+
export declare class Timers {
|
|
5
|
+
private list;
|
|
6
|
+
get count(): number;
|
|
7
|
+
after(seconds: number, fn: () => void): TimerHandle;
|
|
8
|
+
every(seconds: number, fn: () => void): TimerHandle;
|
|
9
|
+
update(dt: number): void;
|
|
10
|
+
clear(): void;
|
|
11
|
+
}
|
package/package.json
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"type": "git",
|
|
15
|
-
"url": "https://github.com/karttofer/fruitjs"
|
|
16
|
-
},
|
|
17
|
-
"keywords": [
|
|
18
|
-
"WebGL",
|
|
19
|
-
"2d",
|
|
20
|
-
"canvas",
|
|
21
|
-
"HTML5",
|
|
22
|
-
"javascript",
|
|
23
|
-
"game"
|
|
24
|
-
],
|
|
25
|
-
"author": "Jhornan Colina <jhornancolina@gmail.com>",
|
|
26
|
-
"license": "MIT",
|
|
27
|
-
"devDependencies": {
|
|
28
|
-
"@babel/core": "^7.22.1",
|
|
29
|
-
"@babel/preset-env": "^7.22.4",
|
|
30
|
-
"babel-loader": "^9.1.2",
|
|
31
|
-
"html-webpack-plugin": "^5.5.1",
|
|
32
|
-
"prettier": "^2.8.8",
|
|
33
|
-
"webpack": "^5.86.0",
|
|
34
|
-
"webpack-cli": "^5.1.4",
|
|
35
|
-
"webpack-dev-server": "^4.15.0"
|
|
2
|
+
"name": "fruta",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Tiny, semantic 2D graphics & game engine for the web (Canvas2D + WebGL). TypeScript-first, framework-friendly. Physics, pathfinding, pooling, spatial hashing, bézier + hex math.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"main": "./dist/fruta.js",
|
|
8
|
+
"module": "./dist/fruta.js",
|
|
9
|
+
"types": "./dist/fruta.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/fruta.d.ts",
|
|
13
|
+
"import": "./dist/fruta.js"
|
|
36
14
|
}
|
|
37
|
-
}
|
|
15
|
+
},
|
|
16
|
+
"files": ["dist"],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"gensrc": "bun run playground/gensrc.ts",
|
|
19
|
+
"dev": "bun run gensrc && bun ./index.html",
|
|
20
|
+
"build": "rm -rf dist && bun run build:types && bun run build:js",
|
|
21
|
+
"build:types": "tsc",
|
|
22
|
+
"build:js": "bun build ./src/core/fruta.ts --outfile dist/fruta.js --target browser --format esm --minify",
|
|
23
|
+
"test": "bun test",
|
|
24
|
+
"typecheck": "tsc --noEmit",
|
|
25
|
+
"prepublishOnly": "bun run build"
|
|
26
|
+
},
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "https://github.com/karttofer/fruitjs"
|
|
30
|
+
},
|
|
31
|
+
"keywords": ["WebGL", "2d", "canvas", "HTML5", "javascript", "typescript", "game", "graphics"],
|
|
32
|
+
"author": "Jhornan Colina <jhornancolina@gmail.com>",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"typescript": "^5.4.5"
|
|
36
|
+
}
|
|
37
|
+
}
|