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.
Files changed (138) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +115 -0
  3. package/dist/src/assets-manager/AssetsManager.context.d.ts +15 -0
  4. package/dist/src/assets-manager/AssetsManager.context.js +6 -0
  5. package/dist/src/assets-manager/AssetsManager.d.ts +2 -0
  6. package/dist/src/assets-manager/AssetsManager.js +43 -0
  7. package/dist/src/assets-manager/index.d.ts +3 -0
  8. package/dist/src/assets-manager/index.js +3 -0
  9. package/dist/src/assets-manager/useAssetManager.d.ts +1 -0
  10. package/dist/src/assets-manager/useAssetManager.js +5 -0
  11. package/dist/src/camera/Camera.context.d.ts +13 -0
  12. package/dist/src/camera/Camera.context.js +2 -0
  13. package/dist/src/camera/Camera.d.ts +7 -0
  14. package/dist/src/camera/Camera.js +99 -0
  15. package/dist/src/camera/index.d.ts +2 -0
  16. package/dist/src/camera/index.js +2 -0
  17. package/dist/src/game-context/Game.context.d.ts +39 -0
  18. package/dist/src/game-context/Game.context.js +85 -0
  19. package/dist/src/game-context/index.d.ts +1 -0
  20. package/dist/src/game-context/index.js +1 -0
  21. package/dist/src/game-objects/GameObjectPhysicalObjectConfig.d.ts +4 -0
  22. package/dist/src/game-objects/GameObjectPhysicalObjectConfig.js +1 -0
  23. package/dist/src/game-objects/index.d.ts +2 -0
  24. package/dist/src/game-objects/index.js +2 -0
  25. package/dist/src/game-objects/usePhysicalObject.d.ts +7 -0
  26. package/dist/src/game-objects/usePhysicalObject.js +17 -0
  27. package/dist/src/game-objects/usePhysicalObjectFromConfig.d.ts +6 -0
  28. package/dist/src/game-objects/usePhysicalObjectFromConfig.js +13 -0
  29. package/dist/src/game-objects/useWalls.d.ts +11 -0
  30. package/dist/src/game-objects/useWalls.js +59 -0
  31. package/dist/src/hooks/index.d.ts +12 -0
  32. package/dist/src/hooks/index.js +12 -0
  33. package/dist/src/hooks/useAnimatedSprite.d.ts +10 -0
  34. package/dist/src/hooks/useAnimatedSprite.js +41 -0
  35. package/dist/src/hooks/useCamera.d.ts +1 -0
  36. package/dist/src/hooks/useCamera.js +5 -0
  37. package/dist/src/hooks/useCollisionDetection.d.ts +9 -0
  38. package/dist/src/hooks/useCollisionDetection.js +21 -0
  39. package/dist/src/hooks/useGame.d.ts +1 -0
  40. package/dist/src/hooks/useGame.js +5 -0
  41. package/dist/src/hooks/useGlobalEventHandler.d.ts +5 -0
  42. package/dist/src/hooks/useGlobalEventHandler.js +15 -0
  43. package/dist/src/hooks/useLayerContext.d.ts +1 -0
  44. package/dist/src/hooks/useLayerContext.js +5 -0
  45. package/dist/src/hooks/useObject.d.ts +6 -0
  46. package/dist/src/hooks/useObject.js +54 -0
  47. package/dist/src/hooks/useSprite.d.ts +6 -0
  48. package/dist/src/hooks/useSprite.js +21 -0
  49. package/dist/src/hooks/useStage.d.ts +1 -0
  50. package/dist/src/hooks/useStage.js +5 -0
  51. package/dist/src/hooks/useTexture.d.ts +9 -0
  52. package/dist/src/hooks/useTexture.js +14 -0
  53. package/dist/src/hooks/useTickerCallback.d.ts +5 -0
  54. package/dist/src/hooks/useTickerCallback.js +14 -0
  55. package/dist/src/hooks/useTilingSprite.d.ts +6 -0
  56. package/dist/src/hooks/useTilingSprite.js +26 -0
  57. package/dist/src/hooks/useWorld.d.ts +1 -0
  58. package/dist/src/hooks/useWorld.js +5 -0
  59. package/dist/src/index.d.ts +10 -0
  60. package/dist/src/index.js +10 -0
  61. package/dist/src/layer/Layer.context.d.ts +6 -0
  62. package/dist/src/layer/Layer.context.js +2 -0
  63. package/dist/src/layer/Layer.d.ts +6 -0
  64. package/dist/src/layer/Layer.js +34 -0
  65. package/dist/src/layer/index.d.ts +1 -0
  66. package/dist/src/layer/index.js +1 -0
  67. package/dist/src/physics/MatterPhysics.context.d.ts +8 -0
  68. package/dist/src/physics/MatterPhysics.context.js +74 -0
  69. package/dist/src/physics/index.d.ts +4 -0
  70. package/dist/src/physics/index.js +4 -0
  71. package/dist/src/physics/types.d.ts +24 -0
  72. package/dist/src/physics/types.js +1 -0
  73. package/dist/src/physics/useCollisionEventHandler.d.ts +7 -0
  74. package/dist/src/physics/useCollisionEventHandler.js +15 -0
  75. package/dist/src/physics/usePhysicsEngineEventHandler.d.ts +8 -0
  76. package/dist/src/physics/usePhysicsEngineEventHandler.js +15 -0
  77. package/dist/src/physics/usePhysicsTickerCallback.d.ts +7 -0
  78. package/dist/src/physics/usePhysicsTickerCallback.js +15 -0
  79. package/dist/src/stage/Stage.context.d.ts +6 -0
  80. package/dist/src/stage/Stage.context.js +2 -0
  81. package/dist/src/stage/Stage.d.ts +2 -0
  82. package/dist/src/stage/Stage.js +29 -0
  83. package/dist/src/stage/index.d.ts +1 -0
  84. package/dist/src/stage/index.js +1 -0
  85. package/dist/src/types.d.ts +7 -0
  86. package/dist/src/types.js +7 -0
  87. package/dist/src/world/World.context.d.ts +10 -0
  88. package/dist/src/world/World.context.js +2 -0
  89. package/dist/src/world/World.d.ts +11 -0
  90. package/dist/src/world/World.js +66 -0
  91. package/dist/src/world/index.d.ts +2 -0
  92. package/dist/src/world/index.js +2 -0
  93. package/package.json +52 -0
  94. package/src/assets-manager/AssetsManager.context.tsx +23 -0
  95. package/src/assets-manager/AssetsManager.tsx +54 -0
  96. package/src/assets-manager/index.ts +3 -0
  97. package/src/assets-manager/useAssetManager.ts +7 -0
  98. package/src/camera/Camera.context.tsx +17 -0
  99. package/src/camera/Camera.tsx +153 -0
  100. package/src/camera/index.ts +2 -0
  101. package/src/game-context/Game.context.tsx +133 -0
  102. package/src/game-context/index.ts +1 -0
  103. package/src/game-objects/GameObjectPhysicalObjectConfig.ts +18 -0
  104. package/src/game-objects/index.ts +2 -0
  105. package/src/game-objects/usePhysicalObject.ts +24 -0
  106. package/src/game-objects/usePhysicalObjectFromConfig.ts +22 -0
  107. package/src/game-objects/useWalls.ts +93 -0
  108. package/src/hooks/index.ts +12 -0
  109. package/src/hooks/useAnimatedSprite.ts +65 -0
  110. package/src/hooks/useCamera.ts +6 -0
  111. package/src/hooks/useCollisionDetection.ts +35 -0
  112. package/src/hooks/useGame.ts +6 -0
  113. package/src/hooks/useGlobalEventHandler.ts +27 -0
  114. package/src/hooks/useLayerContext.ts +6 -0
  115. package/src/hooks/useObject.ts +81 -0
  116. package/src/hooks/useSprite.ts +33 -0
  117. package/src/hooks/useStage.ts +7 -0
  118. package/src/hooks/useTexture.ts +22 -0
  119. package/src/hooks/useTickerCallback.ts +25 -0
  120. package/src/hooks/useTilingSprite.ts +39 -0
  121. package/src/hooks/useWorld.ts +7 -0
  122. package/src/index.ts +10 -0
  123. package/src/layer/Layer.context.tsx +9 -0
  124. package/src/layer/Layer.tsx +57 -0
  125. package/src/layer/index.ts +1 -0
  126. package/src/physics/MatterPhysics.context.tsx +100 -0
  127. package/src/physics/index.ts +4 -0
  128. package/src/physics/types.ts +27 -0
  129. package/src/physics/useCollisionEventHandler.ts +26 -0
  130. package/src/physics/usePhysicsEngineEventHandler.ts +30 -0
  131. package/src/physics/usePhysicsTickerCallback.ts +25 -0
  132. package/src/stage/Stage.context.tsx +9 -0
  133. package/src/stage/Stage.tsx +50 -0
  134. package/src/stage/index.ts +1 -0
  135. package/src/types.ts +8 -0
  136. package/src/world/World.context.tsx +13 -0
  137. package/src/world/World.tsx +93 -0
  138. 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,5 @@
1
+ import { useContext } from "react";
2
+ import { CameraContext } from "../camera";
3
+ export const useCamera = () => {
4
+ return useContext(CameraContext);
5
+ };
@@ -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,5 @@
1
+ import { useContext } from "react";
2
+ import { GameContext } from "../game-context";
3
+ export const useGame = () => {
4
+ return useContext(GameContext);
5
+ };
@@ -0,0 +1,5 @@
1
+ export declare const useGlobalEventHandler: <K extends keyof DocumentEventMap>({ isEnabled, event, callback }: {
2
+ isEnabled?: boolean;
3
+ event: K;
4
+ callback: (e: DocumentEventMap[K]) => unknown;
5
+ }) => void;
@@ -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,5 @@
1
+ import { useContext } from "react";
2
+ import { LayerContext } from "../layer/Layer.context";
3
+ export const useLayerContext = () => {
4
+ return useContext(LayerContext);
5
+ };
@@ -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,6 @@
1
+ import { Sprite, SpriteOptions } from "pixi.js";
2
+ type UseSpriteOptions = Omit<SpriteOptions, "texture"> & {
3
+ texture: string;
4
+ };
5
+ export declare const useSprite: ({ texture, ...options }: UseSpriteOptions) => Sprite | null;
6
+ export {};
@@ -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,5 @@
1
+ import { useContext } from "react";
2
+ import { StageContext } from "../stage/Stage.context";
3
+ export const useStage = () => {
4
+ return useContext(StageContext);
5
+ };
@@ -0,0 +1,9 @@
1
+ import { Texture } from "pixi.js";
2
+ export declare const useTextures: ({ keys }: {
3
+ keys?: string[];
4
+ }) => {
5
+ textures: Texture<import("pixi.js").TextureSource<any>>[];
6
+ isFetched: boolean;
7
+ isFetching: boolean;
8
+ isError: boolean;
9
+ };
@@ -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,5 @@
1
+ import { TickerCallback } from "pixi.js";
2
+ export declare const useTickerCallback: <T = unknown>({ isEnabled, callback }: {
3
+ isEnabled?: boolean;
4
+ callback: TickerCallback<T>;
5
+ }) => void;
@@ -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,5 @@
1
+ import { useContext } from "react";
2
+ import { WorldContext } from "../world/World.context";
3
+ export const useWorld = () => {
4
+ return useContext(WorldContext);
5
+ };
@@ -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,6 @@
1
+ import { Container } from "pixi.js";
2
+ export type LayerContextValue = {
3
+ addObject: (body: Container) => void;
4
+ removeObject: (body: Container) => void;
5
+ };
6
+ export declare const LayerContext: import("react").Context<LayerContextValue>;
@@ -0,0 +1,2 @@
1
+ import { createContext } from "react";
2
+ export const LayerContext = createContext({});
@@ -0,0 +1,6 @@
1
+ import React, { PropsWithChildren } from "react";
2
+ import { ContainerOptions } from "pixi.js";
3
+ export type LayerOptions = {
4
+ options?: Omit<ContainerOptions, "parent">;
5
+ };
6
+ export declare const Layer: React.FC<PropsWithChildren & LayerOptions>;
@@ -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,4 @@
1
+ export * from "./MatterPhysics.context";
2
+ export * from "./useCollisionEventHandler";
3
+ export * from "./usePhysicsTickerCallback";
4
+ export * from "./usePhysicsEngineEventHandler";
@@ -0,0 +1,4 @@
1
+ export * from "./MatterPhysics.context";
2
+ export * from "./useCollisionEventHandler";
3
+ export * from "./usePhysicsTickerCallback";
4
+ export * from "./usePhysicsEngineEventHandler";
@@ -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
+ };
@@ -0,0 +1,6 @@
1
+ import { Container } from "pixi.js";
2
+ export type StageContextValue = {
3
+ addObject: (body: Container) => void;
4
+ removeObject: (body: Container) => void;
5
+ };
6
+ export declare const StageContext: import("react").Context<StageContextValue>;
@@ -0,0 +1,2 @@
1
+ import { createContext } from "react";
2
+ export const StageContext = createContext({});
@@ -0,0 +1,2 @@
1
+ import React, { PropsWithChildren } from "react";
2
+ export declare const Stage: React.FC<PropsWithChildren>;