pixi-fusion 1.0.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 -0
- package/README.md +115 -0
- package/dist/src/assets-manager/AssetsManager.context.d.ts +15 -0
- package/dist/src/assets-manager/AssetsManager.context.js +6 -0
- package/dist/src/assets-manager/AssetsManager.d.ts +2 -0
- package/dist/src/assets-manager/AssetsManager.js +43 -0
- package/dist/src/assets-manager/index.d.ts +3 -0
- package/dist/src/assets-manager/index.js +3 -0
- package/dist/src/assets-manager/useAssetManager.d.ts +1 -0
- package/dist/src/assets-manager/useAssetManager.js +5 -0
- package/dist/src/camera/Camera.context.d.ts +13 -0
- package/dist/src/camera/Camera.context.js +2 -0
- package/dist/src/camera/Camera.d.ts +7 -0
- package/dist/src/camera/Camera.js +99 -0
- package/dist/src/camera/index.d.ts +2 -0
- package/dist/src/camera/index.js +2 -0
- package/dist/src/game-context/Game.context.d.ts +39 -0
- package/dist/src/game-context/Game.context.js +85 -0
- package/dist/src/game-context/index.d.ts +1 -0
- package/dist/src/game-context/index.js +1 -0
- package/dist/src/game-objects/GameObjectPhysicalObjectConfig.d.ts +4 -0
- package/dist/src/game-objects/GameObjectPhysicalObjectConfig.js +1 -0
- package/dist/src/game-objects/index.d.ts +2 -0
- package/dist/src/game-objects/index.js +2 -0
- package/dist/src/game-objects/usePhysicalObject.d.ts +7 -0
- package/dist/src/game-objects/usePhysicalObject.js +17 -0
- package/dist/src/game-objects/usePhysicalObjectFromConfig.d.ts +6 -0
- package/dist/src/game-objects/usePhysicalObjectFromConfig.js +13 -0
- package/dist/src/game-objects/useWalls.d.ts +11 -0
- package/dist/src/game-objects/useWalls.js +59 -0
- package/dist/src/hooks/index.d.ts +12 -0
- package/dist/src/hooks/index.js +12 -0
- package/dist/src/hooks/useAnimatedSprite.d.ts +10 -0
- package/dist/src/hooks/useAnimatedSprite.js +41 -0
- package/dist/src/hooks/useCamera.d.ts +1 -0
- package/dist/src/hooks/useCamera.js +5 -0
- package/dist/src/hooks/useCollisionDetection.d.ts +9 -0
- package/dist/src/hooks/useCollisionDetection.js +21 -0
- package/dist/src/hooks/useGame.d.ts +1 -0
- package/dist/src/hooks/useGame.js +5 -0
- package/dist/src/hooks/useGlobalEventHandler.d.ts +5 -0
- package/dist/src/hooks/useGlobalEventHandler.js +15 -0
- package/dist/src/hooks/useLayerContext.d.ts +1 -0
- package/dist/src/hooks/useLayerContext.js +5 -0
- package/dist/src/hooks/useObject.d.ts +6 -0
- package/dist/src/hooks/useObject.js +54 -0
- package/dist/src/hooks/useSprite.d.ts +6 -0
- package/dist/src/hooks/useSprite.js +21 -0
- package/dist/src/hooks/useStage.d.ts +1 -0
- package/dist/src/hooks/useStage.js +5 -0
- package/dist/src/hooks/useTexture.d.ts +9 -0
- package/dist/src/hooks/useTexture.js +14 -0
- package/dist/src/hooks/useTickerCallback.d.ts +5 -0
- package/dist/src/hooks/useTickerCallback.js +14 -0
- package/dist/src/hooks/useTilingSprite.d.ts +6 -0
- package/dist/src/hooks/useTilingSprite.js +26 -0
- package/dist/src/hooks/useWorld.d.ts +1 -0
- package/dist/src/hooks/useWorld.js +5 -0
- package/dist/src/index.d.ts +10 -0
- package/dist/src/index.js +10 -0
- package/dist/src/layer/Layer.context.d.ts +6 -0
- package/dist/src/layer/Layer.context.js +2 -0
- package/dist/src/layer/Layer.d.ts +6 -0
- package/dist/src/layer/Layer.js +34 -0
- package/dist/src/layer/index.d.ts +1 -0
- package/dist/src/layer/index.js +1 -0
- package/dist/src/physics/MatterPhysics.context.d.ts +8 -0
- package/dist/src/physics/MatterPhysics.context.js +74 -0
- package/dist/src/physics/index.d.ts +4 -0
- package/dist/src/physics/index.js +4 -0
- package/dist/src/physics/types.d.ts +24 -0
- package/dist/src/physics/types.js +1 -0
- package/dist/src/physics/useCollisionEventHandler.d.ts +7 -0
- package/dist/src/physics/useCollisionEventHandler.js +15 -0
- package/dist/src/physics/usePhysicsEngineEventHandler.d.ts +8 -0
- package/dist/src/physics/usePhysicsEngineEventHandler.js +15 -0
- package/dist/src/physics/usePhysicsTickerCallback.d.ts +7 -0
- package/dist/src/physics/usePhysicsTickerCallback.js +15 -0
- package/dist/src/stage/Stage.context.d.ts +6 -0
- package/dist/src/stage/Stage.context.js +2 -0
- package/dist/src/stage/Stage.d.ts +2 -0
- package/dist/src/stage/Stage.js +29 -0
- package/dist/src/stage/index.d.ts +1 -0
- package/dist/src/stage/index.js +1 -0
- package/dist/src/types.d.ts +7 -0
- package/dist/src/types.js +7 -0
- package/dist/src/world/World.context.d.ts +10 -0
- package/dist/src/world/World.context.js +2 -0
- package/dist/src/world/World.d.ts +11 -0
- package/dist/src/world/World.js +66 -0
- package/dist/src/world/index.d.ts +2 -0
- package/dist/src/world/index.js +2 -0
- package/package.json +52 -0
- package/src/assets-manager/AssetsManager.context.tsx +23 -0
- package/src/assets-manager/AssetsManager.tsx +54 -0
- package/src/assets-manager/index.ts +3 -0
- package/src/assets-manager/useAssetManager.ts +7 -0
- package/src/camera/Camera.context.tsx +17 -0
- package/src/camera/Camera.tsx +153 -0
- package/src/camera/index.ts +2 -0
- package/src/game-context/Game.context.tsx +133 -0
- package/src/game-context/index.ts +1 -0
- package/src/game-objects/GameObjectPhysicalObjectConfig.ts +18 -0
- package/src/game-objects/index.ts +2 -0
- package/src/game-objects/usePhysicalObject.ts +24 -0
- package/src/game-objects/usePhysicalObjectFromConfig.ts +22 -0
- package/src/game-objects/useWalls.ts +93 -0
- package/src/hooks/index.ts +12 -0
- package/src/hooks/useAnimatedSprite.ts +65 -0
- package/src/hooks/useCamera.ts +6 -0
- package/src/hooks/useCollisionDetection.ts +35 -0
- package/src/hooks/useGame.ts +6 -0
- package/src/hooks/useGlobalEventHandler.ts +27 -0
- package/src/hooks/useLayerContext.ts +6 -0
- package/src/hooks/useObject.ts +81 -0
- package/src/hooks/useSprite.ts +33 -0
- package/src/hooks/useStage.ts +7 -0
- package/src/hooks/useTexture.ts +22 -0
- package/src/hooks/useTickerCallback.ts +25 -0
- package/src/hooks/useTilingSprite.ts +39 -0
- package/src/hooks/useWorld.ts +7 -0
- package/src/index.ts +10 -0
- package/src/layer/Layer.context.tsx +9 -0
- package/src/layer/Layer.tsx +57 -0
- package/src/layer/index.ts +1 -0
- package/src/physics/MatterPhysics.context.tsx +100 -0
- package/src/physics/index.ts +4 -0
- package/src/physics/types.ts +27 -0
- package/src/physics/useCollisionEventHandler.ts +26 -0
- package/src/physics/usePhysicsEngineEventHandler.ts +30 -0
- package/src/physics/usePhysicsTickerCallback.ts +25 -0
- package/src/stage/Stage.context.tsx +9 -0
- package/src/stage/Stage.tsx +50 -0
- package/src/stage/index.ts +1 -0
- package/src/types.ts +8 -0
- package/src/world/World.context.tsx +13 -0
- package/src/world/World.tsx +93 -0
- package/src/world/index.ts +2 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { AnimatedSprite, AnimatedSpriteOptions, SpritesheetData } from "pixi.js";
|
|
2
|
+
type UseAnimatedSpriteOptions = Omit<AnimatedSpriteOptions, "textures" | "texture"> & {
|
|
3
|
+
texture: string;
|
|
4
|
+
animation: string;
|
|
5
|
+
spritesheet: SpritesheetData;
|
|
6
|
+
animationSpeed: number;
|
|
7
|
+
isPlaying: boolean;
|
|
8
|
+
};
|
|
9
|
+
export declare const useAnimatedSprite: ({ texture, spritesheet: spritesheetJSON, animation, animationSpeed, isPlaying, ...options }: UseAnimatedSpriteOptions) => AnimatedSprite | null;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { useEffect, useMemo } from "react";
|
|
2
|
+
import { AnimatedSprite, Spritesheet } from "pixi.js";
|
|
3
|
+
import { useTextures } from "./useTexture";
|
|
4
|
+
import { useObject } from "./useObject";
|
|
5
|
+
export const useAnimatedSprite = ({ texture, spritesheet: spritesheetJSON, animation, animationSpeed = 1, isPlaying, ...options }) => {
|
|
6
|
+
const textureKeys = useMemo(() => {
|
|
7
|
+
return [...(texture ? [texture] : [])];
|
|
8
|
+
}, [texture]);
|
|
9
|
+
const { textures, isFetched } = useTextures({ keys: textureKeys });
|
|
10
|
+
const spritesheet = useMemo(() => {
|
|
11
|
+
if (isFetched) {
|
|
12
|
+
const sheet = new Spritesheet(textures[0], spritesheetJSON);
|
|
13
|
+
sheet.parse();
|
|
14
|
+
return sheet;
|
|
15
|
+
}
|
|
16
|
+
return null;
|
|
17
|
+
}, [spritesheetJSON]);
|
|
18
|
+
const sprite = useMemo(() => {
|
|
19
|
+
if (spritesheet?.animations?.[animation]) {
|
|
20
|
+
return new AnimatedSprite({ textures: spritesheet?.animations?.[animation] });
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
}, [texture, spritesheetJSON, animation]);
|
|
24
|
+
useObject({ object: sprite, ...options });
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
if (sprite) {
|
|
27
|
+
sprite.animationSpeed = animationSpeed;
|
|
28
|
+
}
|
|
29
|
+
}, [animationSpeed, sprite?.uid]);
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
if (sprite) {
|
|
32
|
+
if (isPlaying) {
|
|
33
|
+
sprite.play();
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
sprite.stop();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}, [isPlaying, sprite?.uid]);
|
|
40
|
+
return sprite;
|
|
41
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useCamera: () => import("../camera").CameraContextValue;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Container } from "pixi.js";
|
|
2
|
+
type UseCollisionDetectionOptions = {
|
|
3
|
+
objectA?: Container | null;
|
|
4
|
+
objectB?: Container | null;
|
|
5
|
+
isEnabled: boolean;
|
|
6
|
+
onCollide: () => void;
|
|
7
|
+
};
|
|
8
|
+
export declare const useCollisionDetection: ({ objectA, objectB, onCollide, isEnabled }: UseCollisionDetectionOptions) => void;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useTickerCallback } from "./useTickerCallback";
|
|
2
|
+
import { useCallback } from "react";
|
|
3
|
+
export const useCollisionDetection = ({ objectA, objectB, onCollide, isEnabled }) => {
|
|
4
|
+
const testForAABB = useCallback(() => {
|
|
5
|
+
if (!objectA || !objectB) {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
const bounds1 = objectA.getBounds();
|
|
9
|
+
const bounds2 = objectB.getBounds();
|
|
10
|
+
if (bounds1.x < bounds2.x + bounds2.width &&
|
|
11
|
+
bounds1.x + bounds1.width > bounds2.x &&
|
|
12
|
+
bounds1.y < bounds2.y + bounds2.height &&
|
|
13
|
+
bounds1.y + bounds1.height > bounds2.y) {
|
|
14
|
+
onCollide();
|
|
15
|
+
}
|
|
16
|
+
}, [objectA, objectB, onCollide]);
|
|
17
|
+
useTickerCallback({
|
|
18
|
+
isEnabled: isEnabled,
|
|
19
|
+
callback: testForAABB
|
|
20
|
+
});
|
|
21
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useGame: () => import("../game-context").GameContextValue;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
export const useGlobalEventHandler = ({ isEnabled = true, event, callback }) => {
|
|
3
|
+
useEffect(() => {
|
|
4
|
+
if (!isEnabled) {
|
|
5
|
+
return () => { };
|
|
6
|
+
}
|
|
7
|
+
const internalCallback = (e) => {
|
|
8
|
+
callback(e);
|
|
9
|
+
};
|
|
10
|
+
document.addEventListener(event, internalCallback);
|
|
11
|
+
return () => {
|
|
12
|
+
document.removeEventListener(event, internalCallback);
|
|
13
|
+
};
|
|
14
|
+
}, [isEnabled, event, callback]);
|
|
15
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useLayerContext: () => import("../layer/Layer.context").LayerContextValue;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Sprite, SpriteOptions, TilingSprite } from "pixi.js";
|
|
2
|
+
type UseObjectOptions = Omit<SpriteOptions, "texture"> & {
|
|
3
|
+
object: Sprite | TilingSprite | null;
|
|
4
|
+
};
|
|
5
|
+
export declare const useObject: ({ object, anchor, position, skew, scale, width, angle, alpha, visible }: UseObjectOptions) => void;
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { useLayerContext } from "./useLayerContext";
|
|
2
|
+
import { useEffect } from "react";
|
|
3
|
+
export const useObject = ({ object, anchor, position, skew, scale, width, angle, alpha, visible = true }) => {
|
|
4
|
+
const { addObject, removeObject } = useLayerContext();
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
if (!object) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
addObject(object);
|
|
10
|
+
return () => {
|
|
11
|
+
removeObject(object);
|
|
12
|
+
};
|
|
13
|
+
}, [object?.uid]);
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
if (anchor !== undefined && object) {
|
|
16
|
+
object.anchor = anchor;
|
|
17
|
+
}
|
|
18
|
+
}, [anchor, object?.uid]);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (angle !== undefined && object) {
|
|
21
|
+
object.angle = angle;
|
|
22
|
+
}
|
|
23
|
+
}, [angle, object?.uid]);
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
if (object && position !== undefined) {
|
|
26
|
+
object.position = position;
|
|
27
|
+
}
|
|
28
|
+
}, [position, object?.uid]);
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
if (object && skew !== undefined) {
|
|
31
|
+
object.skew = skew;
|
|
32
|
+
}
|
|
33
|
+
}, [skew, object?.uid]);
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
if (object && alpha !== undefined) {
|
|
36
|
+
object.alpha = alpha;
|
|
37
|
+
}
|
|
38
|
+
}, [alpha, object?.uid]);
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
if (object && scale !== undefined) {
|
|
41
|
+
object.scale = scale;
|
|
42
|
+
}
|
|
43
|
+
}, [scale, object?.uid]);
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
if (object) {
|
|
46
|
+
object.visible = visible;
|
|
47
|
+
}
|
|
48
|
+
}, [visible, object?.uid]);
|
|
49
|
+
useEffect(() => {
|
|
50
|
+
if (object && width !== undefined) {
|
|
51
|
+
object.width = width;
|
|
52
|
+
}
|
|
53
|
+
}, [width, object?.uid]);
|
|
54
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { Sprite } from "pixi.js";
|
|
3
|
+
import { useTextures } from "./useTexture";
|
|
4
|
+
import { useObject } from "./useObject";
|
|
5
|
+
export const useSprite = ({ texture = "", ...options }) => {
|
|
6
|
+
const textureKeys = useMemo(() => {
|
|
7
|
+
return [...(texture ? [texture] : [])];
|
|
8
|
+
}, [texture]);
|
|
9
|
+
const { isFetched } = useTextures({ keys: textureKeys });
|
|
10
|
+
const sprite = useMemo(() => {
|
|
11
|
+
if (!isFetched) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
if (texture) {
|
|
15
|
+
return Sprite.from(texture);
|
|
16
|
+
}
|
|
17
|
+
return new Sprite({});
|
|
18
|
+
}, [texture, frames, isFetched]);
|
|
19
|
+
useObject({ object: sprite, ...options });
|
|
20
|
+
return sprite;
|
|
21
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useStage: () => import("../stage/Stage.context").StageContextValue;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { useAssetManager } from "../assets-manager";
|
|
3
|
+
export const useTextures = ({ keys = [] }) => {
|
|
4
|
+
const { getAsset, isFetched, isFetching, isError } = useAssetManager();
|
|
5
|
+
const textures = useMemo(() => {
|
|
6
|
+
return isFetched ? keys.map((key) => getAsset(key)) : [];
|
|
7
|
+
}, [keys, isFetched, isFetching, isError]);
|
|
8
|
+
return useMemo(() => ({
|
|
9
|
+
textures: textures,
|
|
10
|
+
isFetched,
|
|
11
|
+
isFetching,
|
|
12
|
+
isError
|
|
13
|
+
}), [textures, isFetched, isError, isFetching]);
|
|
14
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import { useWorld } from "../hooks";
|
|
3
|
+
export const useTickerCallback = ({ isEnabled = true, callback }) => {
|
|
4
|
+
const { application, isInitialized } = useWorld();
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
if (!isInitialized || !isEnabled) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
application.ticker.add(callback);
|
|
10
|
+
return () => {
|
|
11
|
+
application.ticker.remove(callback);
|
|
12
|
+
};
|
|
13
|
+
}, [isEnabled, application, isInitialized, callback]);
|
|
14
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { TilingSpriteOptions, TilingSprite } from "pixi.js";
|
|
2
|
+
type UseTilingSpriteOptions = Omit<TilingSpriteOptions, "texture"> & {
|
|
3
|
+
texture: string;
|
|
4
|
+
};
|
|
5
|
+
export declare const useTilingSprite: ({ texture, tilePosition, ...options }: UseTilingSpriteOptions) => TilingSprite | null;
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { useEffect, useMemo } from "react";
|
|
2
|
+
import { TilingSprite } from "pixi.js";
|
|
3
|
+
import { useTextures } from "./useTexture";
|
|
4
|
+
import { useObject } from "./useObject";
|
|
5
|
+
export const useTilingSprite = ({ texture = "", tilePosition, ...options }) => {
|
|
6
|
+
const textureKeys = useMemo(() => {
|
|
7
|
+
return [...(texture ? [texture] : [])];
|
|
8
|
+
}, [texture]);
|
|
9
|
+
const { isFetched } = useTextures({ keys: textureKeys });
|
|
10
|
+
const sprite = useMemo(() => {
|
|
11
|
+
if (!isFetched) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
if (texture) {
|
|
15
|
+
return TilingSprite.from(texture);
|
|
16
|
+
}
|
|
17
|
+
return new TilingSprite({});
|
|
18
|
+
}, [texture, frames]);
|
|
19
|
+
useObject({ object: sprite, ...options });
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (tilePosition && sprite) {
|
|
22
|
+
sprite.tilePosition = tilePosition;
|
|
23
|
+
}
|
|
24
|
+
}, [tilePosition, sprite?.uid]);
|
|
25
|
+
return sprite;
|
|
26
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useWorld: () => import("../world/World.context").WorldContextValue;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from "./game-context";
|
|
2
|
+
export * from "./assets-manager";
|
|
3
|
+
export * from "./world";
|
|
4
|
+
export * from "./camera";
|
|
5
|
+
export * from "./layer";
|
|
6
|
+
export * from "./assets-manager";
|
|
7
|
+
export * from "./game-objects";
|
|
8
|
+
export * from "./physics";
|
|
9
|
+
export * from "./types";
|
|
10
|
+
export * from "./hooks";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from "./game-context";
|
|
2
|
+
export * from "./assets-manager";
|
|
3
|
+
export * from "./world";
|
|
4
|
+
export * from "./camera";
|
|
5
|
+
export * from "./layer";
|
|
6
|
+
export * from "./assets-manager";
|
|
7
|
+
export * from "./game-objects";
|
|
8
|
+
export * from "./physics";
|
|
9
|
+
export * from "./types";
|
|
10
|
+
export * from "./hooks";
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React, { useCallback, useContext, useEffect, useMemo } from "react";
|
|
2
|
+
import { Container } from "pixi.js";
|
|
3
|
+
import { StageContext } from "../stage/Stage.context";
|
|
4
|
+
import { LayerContext } from "./Layer.context";
|
|
5
|
+
export const Layer = ({ options, children }) => {
|
|
6
|
+
const { addObject: addObjectIntoStage, removeObject: removeObjectFromStaeg } = useContext(StageContext);
|
|
7
|
+
const { addObject: addObjectIntoParent, removeObject: removeObjectFromParent } = useContext(LayerContext);
|
|
8
|
+
const container = useMemo(() => {
|
|
9
|
+
return new Container(options);
|
|
10
|
+
}, [options]);
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (addObjectIntoParent) {
|
|
13
|
+
addObjectIntoParent(container);
|
|
14
|
+
return () => {
|
|
15
|
+
removeObjectFromParent(container);
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
addObjectIntoStage(container);
|
|
19
|
+
return () => {
|
|
20
|
+
removeObjectFromStaeg(container);
|
|
21
|
+
};
|
|
22
|
+
}, [container?.uid]);
|
|
23
|
+
const addObject = useCallback((thing) => {
|
|
24
|
+
container.addChild(thing);
|
|
25
|
+
}, [container?.uid]);
|
|
26
|
+
const removeObject = useCallback((thing) => {
|
|
27
|
+
container.removeChild(thing);
|
|
28
|
+
}, [container?.uid]);
|
|
29
|
+
const conextValue = useMemo(() => ({
|
|
30
|
+
addObject,
|
|
31
|
+
removeObject
|
|
32
|
+
}), [container?.uid]);
|
|
33
|
+
return React.createElement(LayerContext.Provider, { value: conextValue }, children);
|
|
34
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./Layer";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./Layer";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React, { PropsWithChildren } from "react";
|
|
2
|
+
import { MatterPhysicsConfig, MatterPhysics } from "./types";
|
|
3
|
+
export type MatterPhysicsContextProviderOptions = {
|
|
4
|
+
isRunning?: boolean;
|
|
5
|
+
config: MatterPhysicsConfig;
|
|
6
|
+
};
|
|
7
|
+
export declare const MatterPhysicsContext: React.Context<MatterPhysics>;
|
|
8
|
+
export declare const MatterPhysicsContextProvider: React.FC<PropsWithChildren & MatterPhysicsContextProviderOptions>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import React, { createContext, useEffect, useMemo, useRef, useState } from "react";
|
|
2
|
+
import { Engine, Runner, World } from "matter-js";
|
|
3
|
+
export const MatterPhysicsContext = createContext({
|
|
4
|
+
config: {
|
|
5
|
+
world: {
|
|
6
|
+
width: 480,
|
|
7
|
+
height: 320
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
engine: Engine.create(),
|
|
11
|
+
runner: Runner.create(),
|
|
12
|
+
run: () => { },
|
|
13
|
+
stop: () => { },
|
|
14
|
+
addBody: () => { },
|
|
15
|
+
removeBody: () => { }
|
|
16
|
+
});
|
|
17
|
+
export const MatterPhysicsContextProvider = ({ isRunning = false, children, config = { world: { width: 480, height: 320 } } }) => {
|
|
18
|
+
const isRunningRef = useRef(false);
|
|
19
|
+
const [localConfig] = useState(config);
|
|
20
|
+
const world = useMemo(() => {
|
|
21
|
+
return World.create({
|
|
22
|
+
bounds: {
|
|
23
|
+
min: { x: 0, y: 0 },
|
|
24
|
+
max: { x: config.world.width, y: config.world.height }
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}, [config.world]);
|
|
28
|
+
const engine = useMemo(() => {
|
|
29
|
+
return Engine.create({
|
|
30
|
+
world
|
|
31
|
+
});
|
|
32
|
+
}, [world]);
|
|
33
|
+
const runner = useMemo(() => Runner.create(), []);
|
|
34
|
+
const addBody = (body) => {
|
|
35
|
+
if (engine?.world) {
|
|
36
|
+
World.add(engine?.world, body);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const removeBody = (body) => {
|
|
40
|
+
if (engine?.world) {
|
|
41
|
+
World.remove(engine?.world, body);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
const run = () => {
|
|
45
|
+
if (!isRunningRef.current) {
|
|
46
|
+
Runner.run(runner, engine);
|
|
47
|
+
isRunningRef.current = true;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
const stop = () => {
|
|
51
|
+
if (isRunningRef.current) {
|
|
52
|
+
Runner.stop(runner);
|
|
53
|
+
isRunningRef.current = false;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
const conextValue = useMemo(() => ({
|
|
57
|
+
config: localConfig,
|
|
58
|
+
runner,
|
|
59
|
+
engine,
|
|
60
|
+
run,
|
|
61
|
+
stop,
|
|
62
|
+
addBody,
|
|
63
|
+
removeBody
|
|
64
|
+
}), [runner, engine, localConfig]);
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
if (isRunning) {
|
|
67
|
+
run();
|
|
68
|
+
}
|
|
69
|
+
return () => {
|
|
70
|
+
stop();
|
|
71
|
+
};
|
|
72
|
+
}, [isRunning]);
|
|
73
|
+
return React.createElement(MatterPhysicsContext.Provider, { value: conextValue }, children);
|
|
74
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import Matter from "matter-js";
|
|
2
|
+
export type MatterPhysicsDebugConvexHullConfig = {
|
|
3
|
+
strokeColor?: string;
|
|
4
|
+
strokeWidth?: number;
|
|
5
|
+
};
|
|
6
|
+
export type MatterPhysicsConfig = {
|
|
7
|
+
world: {
|
|
8
|
+
width: number;
|
|
9
|
+
height: number;
|
|
10
|
+
};
|
|
11
|
+
debug?: {
|
|
12
|
+
convexHull?: MatterPhysicsDebugConvexHullConfig;
|
|
13
|
+
showConvexHull?: boolean;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export type MatterPhysics = {
|
|
17
|
+
readonly config: MatterPhysicsConfig;
|
|
18
|
+
readonly runner: Matter.Runner;
|
|
19
|
+
readonly engine: Matter.Engine;
|
|
20
|
+
run: () => void;
|
|
21
|
+
stop: () => void;
|
|
22
|
+
addBody: (body: Matter.Body | Matter.Composite) => void;
|
|
23
|
+
removeBody: (body: Matter.Body | Matter.Composite) => void;
|
|
24
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ICollisionCallback } from "matter-js";
|
|
2
|
+
export type UseCollisionEventHandlerOptions = {
|
|
3
|
+
isEnabled?: boolean;
|
|
4
|
+
event: "collisionActive" | "collisionEnd" | "collisionStart";
|
|
5
|
+
callback: ICollisionCallback;
|
|
6
|
+
};
|
|
7
|
+
export declare const useCollisionEventHandler: ({ isEnabled, event, callback }: UseCollisionEventHandlerOptions) => void;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useEffect, useContext } from "react";
|
|
2
|
+
import { Events } from "matter-js";
|
|
3
|
+
import { MatterPhysicsContext } from "./MatterPhysics.context";
|
|
4
|
+
export const useCollisionEventHandler = ({ isEnabled = true, event, callback }) => {
|
|
5
|
+
const { engine } = useContext(MatterPhysicsContext);
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
if (!isEnabled) {
|
|
8
|
+
return () => { };
|
|
9
|
+
}
|
|
10
|
+
Events.on(engine, event, callback);
|
|
11
|
+
return () => {
|
|
12
|
+
Events.off(engine, event, callback);
|
|
13
|
+
};
|
|
14
|
+
}, [isEnabled, callback, event]);
|
|
15
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { IEngineCallback } from "matter-js";
|
|
2
|
+
type UsePhysicsEngineEventHandlerOptions = {
|
|
3
|
+
isEnabled?: boolean;
|
|
4
|
+
event: "beforeUpdate" | "afterUpdate";
|
|
5
|
+
callback: IEngineCallback;
|
|
6
|
+
};
|
|
7
|
+
export declare const usePhysicsEngineEventHandler: ({ isEnabled, event, callback }: UsePhysicsEngineEventHandlerOptions) => void;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useEffect, useContext } from "react";
|
|
2
|
+
import { Events } from "matter-js";
|
|
3
|
+
import { MatterPhysicsContext } from "./MatterPhysics.context";
|
|
4
|
+
export const usePhysicsEngineEventHandler = ({ isEnabled = true, event, callback }) => {
|
|
5
|
+
const { engine } = useContext(MatterPhysicsContext);
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
if (!isEnabled) {
|
|
8
|
+
return () => { };
|
|
9
|
+
}
|
|
10
|
+
Events.on(engine, event, callback);
|
|
11
|
+
return () => {
|
|
12
|
+
Events.off(engine, event, callback);
|
|
13
|
+
};
|
|
14
|
+
}, [isEnabled, event, callback]);
|
|
15
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { IRunnerCallback } from "matter-js";
|
|
2
|
+
type UsePhysicsTickerCallbackOptions = {
|
|
3
|
+
isEnabled?: boolean;
|
|
4
|
+
callback: IRunnerCallback;
|
|
5
|
+
};
|
|
6
|
+
export declare const usePhysicsTickerCallback: ({ isEnabled, callback }: UsePhysicsTickerCallbackOptions) => void;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useEffect, useContext } from "react";
|
|
2
|
+
import { Events } from "matter-js";
|
|
3
|
+
import { MatterPhysicsContext } from "./MatterPhysics.context";
|
|
4
|
+
export const usePhysicsTickerCallback = ({ isEnabled = true, callback }) => {
|
|
5
|
+
const { runner } = useContext(MatterPhysicsContext);
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
if (!isEnabled) {
|
|
8
|
+
return () => { };
|
|
9
|
+
}
|
|
10
|
+
Events.on(runner, "tick", callback);
|
|
11
|
+
return () => {
|
|
12
|
+
Events.off(runner, "tick", callback);
|
|
13
|
+
};
|
|
14
|
+
}, [isEnabled, callback]);
|
|
15
|
+
};
|