# expo-phaser

> Build awesome 2D games with Phaser.js and Expo

Latest version **0.0.1-alpha.0** (published 2018-02-15) · MIT license · 0 weekly downloads

## Install

```sh
npm install expo-phaser
pnpm add expo-phaser
yarn add expo-phaser
bun add expo-phaser
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.0.1-alpha.0 |
| Published | 2018-02-15 |
| First published | 2018-02-15 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 2 |
| Unpacked size | 17.9 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 242 |
| Author | Evan Bacon |
| Maintainers | evanbacon |
| Keywords | react, native, react-native, phaser-ce, phaser, expo, exponent, game, gl, graphics, opengl, 2d, pixi, pixi.js, sprite, flash |

## Links

- npm: https://www.npmjs.com/package/expo-phaser
- Repository: https://github.com/expo/expo-phaser
- Homepage: https://github.com/expo/expo-phaser#readme
- Issues: https://github.com/expo/expo-phaser/issues
- npm.io page: https://npm.io/package/expo-phaser

## Dependencies (2)

- [phaser-ce](https://npm.io/package/phaser-ce.md) ^2.9.4
- [@expo/browser-polyfill](https://npm.io/package/@expo/browser-polyfill.md) ^0.0.0-alpha.4

## Alternatives

- [mobx-react](https://npm.io/package/mobx-react.md) — 2.8M weekly downloads
- [rc-tree](https://npm.io/package/rc-tree.md) — 2.6M weekly downloads
- [@react-oauth/google](https://npm.io/package/@react-oauth/google.md) — 1.3M weekly downloads
- [@wagmi/connectors](https://npm.io/package/@wagmi/connectors.md) — 877.0K weekly downloads
- [vee-validate](https://npm.io/package/vee-validate.md) — 836.4K weekly downloads

## Recent versions

- 0.0.1-alpha.0 (latest) — 2018-02-15
- 0.0.0 — 2018-02-15

## README

[![NPM](https://nodei.co/npm/expo-phaser.png)](https://nodei.co/npm/expo-phaser/)

# expo-phaser

Tools for using Phaser-ce to build native 2D games in Expo 👾

### Installation

```bash
yarn add expo-phaser
```

### Usage

Import the library into your JavaScript file:

```js
import ExpoPhaser from 'expo-phaser';
```

## Functions

### `ExpoPhaser.game({ context: WebGLRenderingContext, ...extras })`

Given a `context` from an
[`Expo.GLView`](https://docs.expo.io/versions/latest/sdk/gl-view.html), return a
[`Phaser.Game`](https://phaser.io/docs/2.6.2/Phaser.Game.html)
that draws into it.

#### Props

| Property    |         Type          | Description                                                                 |         Default Value         |
| ----------- | :-------------------: | --------------------------------------------------------------------------- | :---------------------------: |
| context     | WebGLRenderingContext | Required: context that the `Phaser.Game` will render to                     |            `null`             |
| width       |        number?        | Optional: height of the `Phaser.Game`                                       | `context.drawingBufferWidth`  |
| height      |        number?        | Optional: width of the `Phaser.Game`                                        | `context.drawingBufferHeight` |
| title       |        string?        | Optional: title of the `Phaser.Game`                                        |     `"expo-phaser-game"`      |
| preventLoop |       boolean?        | Optional: Prevents the app from calling `context.endFrameEXP()` every frame |            `false`            |

#### Returns

| Property |                              Type                              | Description                                      |
| -------- | :------------------------------------------------------------: | ------------------------------------------------ |
| game     | [`Phaser.Game`](https://phaser.io/docs/2.6.2/Phaser.Game.html) | The Phaser-ce game used for rendering game logic |

#### Example

```js
const game = ExpoPhaser.game({ context });
```

## What does it do?

Under the hood, ExpoPhaser is maintaining global instances of a few libraries.

* [Custom Phaser Pixi.js](https://github.com/photonstorm/phaser-ce/tree/master/src/pixi)
* [Custom Phaser p2.js](https://github.com/photonstorm/phaser-ce/blob/master/build/custom/p2.js)
* [Phaser-ce (Community Edition)](https://github.com/photonstorm/phaser-ce)

```js
window.PIXI = require('phaser-ce/build/custom/pixi');
window.p2 = require('phaser-ce/build/custom/p2');
window.Phaser = require('phaser-ce/build/phaser');
```

Other libs can be included but are not required. For instance you can import the custom Creature lib the same way.
We also [override the `PIXI.WebGLRenderer.updateTexture`](https://github.com/expo/expo-phaser/tree/master/lib/Phaser.js) to make it compatible with Expo.

Finally when a new instance of `Expo.Game` is created, we set the `document.readyState` to `'complete'` and save the global instance of `context`

```js
global.__context = context;
global.document.readyState = 'complete';
```

Then we create a standard render loop and call `context.endFrameEXP()` to flush the frame queue and render our context through `EXGL`.

```js
const render = () => {
  requestAnimationFrame(render);
  context.endFrameEXP();
};
```

## Example

It's important to note that you must preload all of your assets before starting the app, as the `Phaser.State.preload` method cannot be asynchronous.
Creating a game in Expo is very simple with `ExpoPhaser`, we preload our assets, create a view, initialize our game, then add our assets.

**We create an `Expo.GLView` to render our game to.**

```jsx
return (
  <Expo.GLView
    style={{ flex: 1 }}
    onContextCreate={context => startGame({ context })}
  />
);
```

**Then we create our `Phaser.Game` instance and assign it a playable state. We can then choose to start said state.**

```js
function startGame({ context }) {
  const game = ExpoPhaser.game({ context });

  game.state.add('Playable', {
    preload: function() {
      /// This function cannot be async, preload all assets before getting here.
      game.load.image(
        'man',
        Expo.Asset.fromModule(Assets['man.json']).localUri,
      );
    },
    create: function() {},
    update: function() {},
  });

  game.state.start('Playable');
}
```

**Preloading**

In React Native all assets must be static resources, because of this we must create a reference to all the assets we may use, then download them and get their local URI.
Expo has a convenient way of saving reference. We preload an `Expo.Asset` then if we create the same instance later we can simple call `asset.localUri`.

In a standard Phaser app we would load an asset like this:

```js
game.load.image('man', './assets/man.png');
```

In expo we would load it like this:

```js
const preloadedExpoAsset = Expo.Asset.fromModule(require('./assets/man.png'))
await preloadedExpoAsset.downloadAsync();

...

game.load.image('man', preloadedExpoAsset.localUri);
```

### All together

This example shows how to load an animated texture atlas and apply arcade physics to it.

```js
import React from 'react';
import Expo from 'expo';
import ExpoPhaser from 'expo-phaser';

const Assets = {
  'man.png': require('./assets/man.png'),
  'man.json': require('./assets/man.json'),
};

export default class App extends React.Component {
  state = { loading: true };
  async componentWillMount() {
    const downloads = [];
    for (let key of Object.keys(Assets)) {
      const asset = Expo.Asset.fromModule(Assets[key]);
      downloads.push(asset.downloadAsync());
    }
    await Promise.all(downloads);
    this.setState({ loading: false });
  }
  render() {
    if (this.state.loading) {
      return <Expo.AppLoading />;
    }

    return (
      <Expo.GLView
        style={{ flex: 1 }}
        onContextCreate={context => startGame({ context })}
      />
    );
  }
}

function startGame({ context }) {
  const game = ExpoPhaser.game({ context });

  game.state.add('Playable', {
    preload: function() {
      const atlas = Expo.Asset.fromModule(Assets['man.json']).localUri;
      const texture = Expo.Asset.fromModule(Assets['man.png']).localUri;
      game.load.atlasJSONHash('man', texture, atlas);
    },
    create: function() {
      game.stage.backgroundColor = '#4488AA';

      game.physics.startSystem(Phaser.Physics.ARCADE);

      //  Set the world (global) gravity
      game.physics.arcade.gravity.y = 100;

      const man = game.add.sprite(200, 200, 'man');
      game.physics.enable([man], Phaser.Physics.ARCADE);

      //  Here we add a new animation called 'run'
      //  We haven't specified any frames because it's using every frame in the texture atlas

      man.animations.add('run');
      man.body.collideWorldBounds = true;
      man.body.bounce.y = 0.8;
      man.body.gravity.y = 200;

      //  And this starts the animation playing by using its key ("run")
      //  15 is the frame rate (15fps)
      //  true means it will loop when it finishes
      man.animations.play('run', 15, true);
    },
    update: function() {},
  });

  game.state.start('Playable');
}
```

---
_Source: https://npm.io/package/expo-phaser · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
