phaser-react-ui
v1.15.1
Published
React interface render for Phaser engine
Downloads
49
Maintainers
Readme
⚡ Phaser React UI
Library for render relative game interface using React, connecting it with Phaser through events and context.
Use special hooks for access to game and scenes.
For each scene can be create one interface instance, which is container for all components.
.
Documentation
.
Install
npm i phaser-react-ui
.
Integration
Add interface to scene
const ui = new Interface(scene: Phaser.Scene)
console.log(ui.container) // HTMLDivElement
Interface render
ui.render(
component: React.FC,
props?: object
)
Interface events
scene.events.on(Phaser.Interface.Events.MOUNT, () => {
console.log('component mounted');
})
Toggle interface interactive
ui.setInteractive(state: boolean)
- Default:
true
- You can toggle interactive for certain interface elements by CSS-property
pointer-events
Remove interface from scene
ui.destroy()
- When scene is closed, the interface is destroyed automatically
.
Hooks
Get game instance
useGame(): Phaser.Game
Get scene
- Get scene in which interface was created
useCurrentScene(): Phaser.Scene
- Get scene by key
useScene(key: string): Phaser.Scene
Subscribe to scene update
useSceneUpdate(
scene: Phaser.Scene,
callback: () => void,
depends: any[]
)
Subscribe to event
useEvent(
emitter: Phaser.Events.EventEmitter,
event: string,
callback: () => void,
depends: any[]
)
Position relative to camera
useRelativePosition(params: {
x: number,
y: number,
camera?: Phaser.Cameras.Scene2D.Camera
}): React.MutableRefObject<HTMLElement>
Scale relative to canvas size
useRelativeScale(params: {
target: number,
min?: number,
max?: number,
round?: boolean
}): React.MutableRefObject<HTMLElement>
Get texture source image
useTexture(key: string): HTMLImageElement
Get actual media query result
useMatchMedia(query: string): boolean
Check if platform is mobile
useMobilePlatform(): boolean
Use adaptive click event on target element
useClick(
ref: React.RefObject,
type: 'up' | 'down',
callback: Function,
depends: any[]
)
Use adaptive click event outside target element
useClickOutside(
ref: React.RefObject,
callback: Function,
depends: any[]
)
Use adaptive interaction flow
useInteraction(
ref: React.RefObject,
callback?: Function,
depends?: any[]
): boolean
.
Components
Position relative to camera
<RelativePosition
x={number}
y={number}
camera={Phaser.Cameras.Scene2D.Camera?}
>
...
</RelativePosition>
Scale relative to canvas size
<RelativeScale
target={number}
min={number?}
max={number?}
round={boolean?}
>
...
</RelativeScale>
Render texture image
<Texture name={string} />
.
Utils
Safe rerender utils
ifModifiedObject(
newValue: T,
keys?: (keyof T)[]
): (currentValue: T) => T
ifModifiedArray(
newValue: T[],
keys?: (keyof T)[]
): (currentValue: T[]) => T[]
const Component: React.FC = () => {
const scene = useCurrentScene();
const [data, setData] = useState({});
useSceneUpdate(scene, () => {
const newData = scene.getSomeData();
// Rerender only if newData is different by data
setList(ifModifiedObject(newData))
}, []);
};
.
Example
Create interface component
import { useScene, useSceneUpdate, useEvent } from 'phaser-react-ui';
const PlayerHealth: React.FC = () => {
const world = useScene('world');
const [health, setHealth] = useState(0);
const [isAlive, setAlive] = useState(true);
useSceneUpdate(world, () => {
if (isAlive) {
setHealth(world.player.health);
}
}, [isAlive]);
useEvent(world.player, Phaser.GameObjects.Events.DESTROY, () => {
setAlive(false);
}, []);
return isAlive && (
<div className='info'>
{health} HP
</div>
);
};
Create components container
import { useRelativeScale } from 'phaser-react-ui';
import { PlayerHealth } from './PlayerHealth';
const ScreenUI: React.FC<Props> = () => {
const ref = useRelativeScale<HTMLDivElement>({
target: 1280,
min: 0.6,
max: 1.2,
});
return (
<div ref={ref} className='container'>
<PlayerHealth />
...
</div>
);
};
ScreenUI.displayName = 'ScreenUI';
Add interface to scene
import { Interface } from 'phaser-react-ui';
import { ScreenUI } from './ScreenUI';
class Screen extends Phaser.Scene {
private ui: Interface;
create() {
this.ui = new Interface(this);
this.ui.render(ScreenUI);
}
}