Coder Social home page Coder Social logo

formidablelabs / react-game-kit Goto Github PK

View Code? Open in Web Editor NEW
4.6K 146.0 304.0 2.04 MB

Component library for making games with React & React Native

Home Page: http://reactnext.surge.sh

License: MIT License

JavaScript 100.00%
physics-bodies spritesheet tilemap component-tree game react reactjs physics-engine sprite-animation matter

react-game-kit's Introduction

React Game Kit โ€” Formidable, We build the modern web

Make games with React & React Native!


Maintenance Status

Install

npm install react-game-kit --save

Get Started

react-game-kit provides a set of helper components to make it easier to create games with React and React Native.

You'll want to begin by importing the components you need:

import { Loop, Stage } from 'react-game-kit';

Loop & Stage

Next, in your render method of your top level component, you'll want to put the Loop component at the top level, optionally followed by the Stage component:

render() {
  return (
    <Loop>
      <Stage>
        // Game specific components go here
      </Stage>
    </Loop>
  );
}

The Loop component uses context to pass a subscribable game tick down your component tree. The Stage component does the same with game scale.

World

If you intend on using physics in your game, a good next component would be the World component, which creates and provides a physics engine & world:

render() {
  return (
    <Loop>
      <Stage>
        <World>
          // Game specific components go here
        </World>
      </Stage>
    </Loop>
  );
}

Physics Bodies

Once you have a physics engine/world established, you can use the Body component to define physics bodies inline:

render() {
  return (
    <Loop>
      <Stage>
        <World>
          <Body args={[0,0,75,75]} ref={ (b) => this.body = b.body }>
            // Sprites go here
          </Body>
        </World>
      </Stage>
    </Loop>
  );
}

Using a ref you can obtain a reference to the physics body and modify its properties via the Matter-js API.

Next Steps

Once this general structure is established, what follows usually depends on what kind of game you intend to make. Check out the API documentation below for further clarity regarding use of these components.

React Native

Using this library with React Native is a simple as importing from the native directory:

import { Loop, Stage, ...etc } from 'react-game-kit/native';

Note: AudioPlayer and KeyListener are not implemented on the React Native version.

API

<Loop />

The Loop component acts much like a Redux provider, in that it passes a GameLoop instance down the component tree via this.context.loop.

This allows you to subscribe and unsubscribe to the main game loop anywhere in your component tree. Here is an example of how this would generally look:

class ChildComponent extends React.Component {
  static contextTypes = {
    loop: PropTypes.object,
  };

  componentDidMount() {
    this.context.loop.subscribe(this.update);
  }

  componentWillUnmount() {
    this.context.loop.unsubscribe(this.update);
  }

  update() {
    // tick logic
  };
}

--

<Stage />

height (number) : Base game height. Defaults to 576.

width (number) : Base game width. Defaults to 1024.

The Stage component also leverages context much like Loop, except it passes game scale as this.context.scale. You can use this value to appropriately scale positioning and dimension values within your game. Again, you would have to specify scale: PropTypes.number in your component's contextTypes to receive this value.

--

<World />

gravity (object) : World gravity object.

Defaults:

gravity={{
  x: 0,
  y: 1,
  scale: 0.001,
}}

onCollision (func) : World collision callback.

onInit (func) : World init callback.

onUpdate (func) : World update callback.

The World component is used as the first step in setting up game physics. It passes a matter-js Engine instance down via context as this.context.engine. Generally speaking, when getting or settings physics properties you'll want to do this after the physics world is updated in the main tick cycle. You can hook into this using the onUpdate prop, or in child components use Matter.Events.on(this.context.engine, 'afterUpdate', this.update); to subscribe to the engine updates.

The onInit callback is a great place to do your initial world setup, things like creating static bodies for walls and the floor.

--

<Body />

args (array) : Initial body creation arguments. Depends on the shape prop, which maps to Matter.Bodies body creation methods detailed here: Matter.Bodies Documentation

All other props on the body component map directly to Matter-js Body properties.

The Body component is used to define physics bodies. You will generally want to use ref to obtain a reference to the body, at which point you can call Matter-js methods on it, as well as listen to and react to its physic properties in the world update callback.

--

<Sprite />

offset (array) : Sprite sheet x,y offset.

onPlayStateChanged (func) : Sprite play state changed callback.

repeat (bool) : Determines whether sprite animation should loop.

scale (number) : Scale value for sprite image.

src (string) : src path for sprite sheet.

state (number) : Vertical position in sprite sheet.

steps (array) : Number of animation steps for current row (state).

ticksPerFrame (number) : Number of loop ticks per animation frame.

tileHeight (number) : Height of spritesheet tile.

tileWidth (number) : Width of spritesheet tile.

The Sprite component lets you define sprite animations using sprite sheets. When creating a sprite sheet, define sprite tile dimensions that will be provided via the tileHeight & tileWidth props. Next, each animation state is represented by a row, with steps of the animation represented as columns.

--

<TileMap />

columns (number) : number of columns in tile map.

layers (array) : Array of arrays that contain tile indexes.

renderTile (func) : Overrideable tile rendering function.

rows (number) : Number of rows in tile map.

scale (number) : Tile map scale.

src (string) : Tilemap image src path.

tileSize (number) : Tilemap tile size.

width (number) : Tilemap width.

height (number) : Tilemap height.

The TileMap component lets you define tile maps from a tile atlas. Your tilemap is made of up rows and columns. Each layer is then drawn using those numbers as reference. So for example, if you had 4 rows and 4 columns, with 1 layer, your layers prop would look like:

layers={[
  [
    0, 0, 0, 0,
    1, 0, 1, 1,
    0, 0, 1, 0,
    1, 0, 0, 0,
  ]
]}

--

License

MIT License

Maintenance Status

Archived: This project is no longer maintained by Formidable. We are no longer responding to issues or pull requests unless they relate to security concerns. We encourage interested developers to fork this project and make it their own!

react-game-kit's People

Contributors

almostintuitive avatar boygirl avatar brkyldz avatar carloskelly13 avatar cpresler avatar dijonkitchen avatar eschaefer avatar jeffreyatw avatar jesstelford avatar jfdnc avatar kenwheeler avatar kwelch avatar lukefanning avatar ryan-roemer avatar stefvhuynh avatar tomis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-game-kit's Issues

Components should forward classNames

Use case:

.someClass{
   position:absolute;
   // whatever
}
<Loop className="someClass" style>

Expected:

<div class="someClass"></div>

Actual:

<div style="width:100%;height:100%"></div>

Currently, only style is supported.

Preloading Images

I'm experimenting with this game kit know, using Expo. I am looking for possible boundaries of this framework. For example how does the framework handle a couple of sprites?

I noticed that when several different sprites appear on the screen (> 10), the start of the animations takes a long time. Compiling a screen takes a lot of time, and the sprites will not appear all together on the screen from the first frame.

Can this be solved by preloading the images?

Please let me know what you think!

CRA 2.0 Issues

Using the latest version of react-game-kit and create-react-app I can't get a <Stage /> to appear with greater dimensions than 445 x 0, which shows nothing. ๐Ÿค”

Please let me know how to get it to work or if it's not compatible with CRA 2.0.

Multiplayer games?

Hi. I am new to game dev and want to explore the crazy world of making a multiplayer game.

I've been looking at like pixi, phaser Game Maker etc.

I just came across this project and it seems like it would fit into our existing app very nicely since it's a react native app we are making.

However, has anyone tried introducing multiplayer into it yet? Any ideas how that would work? We arn't making very complex games. Think stuff like tic tac toe for now.

Keypress in demo fires twice for Firefox

https://github.com/FormidableLabs/react-game-kit/blob/master/demo/slides/index.js#L36-L37
Adds both keyup and keypress listeners.
In Chrome/Edge, the arrow keys only fire keyup.
But in Firefox, both events get fired and it results in a double key press.
I don't know if it a matter of just removing the keypress handler? Or keeping both and handling it with some logic on the browser type? I am not a front end guy, and googling hasn't led me to a definitive solution, so if you have thoughts, I am sure you all handle this kind of stuff all the time. I am happy to submit a PR if you suggest a solution.

How can I remove the dependency on prop-types (as TypeScript provides type-safety already)?

In order to subscribe to the <Loop> component's loop, I need to import prop-types as a module dependency, and add the following field into any class extending React.Component:

static contextTypes = {
    loop: PropTypes.object,
};

However, upon doing this, all other static fields on my TypeScript class (eg. functions and variables) begin to return undefined whenever referenced.

Is it possible to subscribe to the <Loop> component's loop without using prop-types at all, and without warnings being thrown in the console? Or at least is there a way to use the prop-types package without breaking other static functions in TypeScript classes?

Bug: `performance` is undefined on RN (Android)

Hi,

Thanks for this, we love working with it!

We've upgraded to react-native 0.49, thereby forced into upgrading react-game-kit, where we found the following crash:
image

It seems like this commit has resulted in a broken runtime if performance is not polyfilled.
e8b01e2

Sprite: switching repeat not working without changing state

Hi!

When i change repeat from true to false, nothing append, i have to change the current state if i want the Sprite is rerendering without loop on animation.
I just want to cancel current repeat on sprite state if the user stop to press some keys.

Why create static bodies onInit?

In my loop, I'm trying to set up a simple world with a floor, and while I could follow the readme/demo and create it on init, I'm trying to create it as one of the world's children, e.g.:

<World>
  <Body args={[0, 462, 512, 50]} isStatic>
    <Sprite />
  </Body>
</World>

Setting isStatic doesn't seem to work here, though, as it falls upon initialization. Am I doing something wrong here? Does static body creation somehow only work during the onInit hook?

Loop unsubscribe doesn't work as documented

The documentation says you can unsubscribe an update listener via
``
`
this.context.loop.unsubscribe(this.updateHandler);


But after looking at the source this seems not to work as expected:

unsubscribe(id) {
delete this.subscribers[id - 1];
}

How to put `Body` inside a different Component?

Hi, I've looked through the given example code for react native, and I can't find a way to put a Matter.js Body objects inside its own component and render multiple of them in a single World. Here's the code I have so far. The MoveThing component renders inside the world, but doesn't have physics applied to it. Any help would be appreciated. thanks.

import React, { Component } from 'react'
import { Image, Dimensions, PanResponder, View } from 'react-native'
import {
  Body,
  Loop,
  Stage,
  World,
} from 'react-game-kit/native'
import Text from '../basics/text'
import Matter from 'matter-js'

export default class Game extends Component {

  physicsInit = (engine) => {

    const dimensions = Dimensions.get('window')

    const ground = Matter.Bodies.rectangle(
      dimensions.width / 2, dimensions.height,
      dimensions.width, 50,
      {
        isStatic: true,
      },
    )

    const ceiling = Matter.Bodies.rectangle(
      dimensions.width / 2, 0,
      dimensions.width, 50,
      {
        isStatic: true,
      },
    )

    const leftWall = Matter.Bodies.rectangle(
      0, dimensions.height / 2,
      50, dimensions.height,
      {
        isStatic: true,
      },
    )

    const rightWall = Matter.Bodies.rectangle(
      dimensions.width, dimensions.height / 2,
      50, dimensions.height,
      {
        isStatic: true,
      },
    )

    Matter.World.add(engine.world, [ground, leftWall, rightWall, ceiling])
  }

  constructor (props) {
    super(props)

    this.state = {
      gravity: 1,
    }
  }

  render () {
    const dimensions = Dimensions.get('window')
    return (
      <Loop>
        <Stage
          width={dimensions.width}
          height={dimensions.height}
          style={{ backgroundColor: '#fff' }}
        >
          <World
            onInit={this.physicsInit}
            gravity={{ x: 0, y: this.state.gravity, scale: 0.00 }}
          >
            {Array.apply(null, Array(5)).map((_, i) => i)
              .map(item => <MoveThing/>)
            }
          </World>
        </Stage>
      </Loop>
    )
  }
}
class MoveThing extends Component {
  constructor (props) {
    super(props)
    this.state = {
      ballPosition: {
        x: 0,
        y: 0,
      },
      ballAngle: 0,
    }
  }

  componentWillMount () {
    this._panResponder = PanResponder.create({
      onStartShouldSetPanResponder: (evt, gestureState) => true,
      onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
      onMoveShouldSetPanResponder: (evt, gestureState) => true,
      onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
      onPanResponderGrant: (evt, gestureState) => {
        this.setState({
          gravity: 0,
        })

        Matter.Body.setAngularVelocity(this.body.body, 0)
        Matter.Body.setVelocity(this.body.body, { x: 0, y: 0 })

        this.startPosition = {
          x: this.body.body.position.x,
          y: this.body.body.position.y,
        }
      },
      onPanResponderMove: (evt, gestureState) => {
        Matter.Body.setPosition(this.body.body, {
          x: this.startPosition.x + gestureState.dx,
          y: this.startPosition.y + gestureState.dy,
        })
      },
      onPanResponderRelease: (evt, gestureState) => {
        this.setState({
          gravity: 1,
        })

        Matter.Body.applyForce(this.body.body, {
          x: this.body.body.position.x,
          y: this.body.body.position.y,
        }, {
          x: gestureState.vx,
          y: gestureState.vy,
        })
      },
    })
  }

  getBallStyles () {
    return {
      backgroundColor: '#444',
      alignItems: 'center',
      justifyContent: 'center',
      borderRadius: 75 / 2,
      height: 75,
      width: 75,
      position: 'absolute',
      transform: [
        { translateX: this.state.ballPosition.x },
        { translateY: this.state.ballPosition.y },
        { rotate: (this.state.ballAngle * (180 / Math.PI)) + 'deg' }
      ],
    }
  }

  render () {
    const dimensions = Dimensions.get('window')

    return (
      <Body
        shape="circle"
        args={[0, dimensions.height - 75, 75]}
        density={1}
        friction={1}
        frictionStatic={0}
        restitution={0}
        ref={(b) => { this.body = b }}
      >
      <View
        style={this.getBallStyles()} {...this._panResponder.panHandlers}
      >
        <Text light size={24}>!!!</Text>
      </View>
      </Body>
    )
  }

}

Can't access this.context.engine on World Children

Hello, i'm having some trouble in getting the engine on world children.. Maybe it's probably because i'm a noob, hope u can solve it for me.

I've created a component to be my world its called Space.

export default class Space extends Component {
    physicsInit = (engine) => {
        const ground = Matter.Bodies.rectangle(
            0, 500,
            1024, 64,
            {
                isStatic: true,
            },
        );

        Matter.World.addBody(engine.world, ground);
    }

    render() {
        return(
            <World onInit={this.physicsInit}>
                {this.props.children}
            </World>
        );
    }
}

and a world child

class Ship extends Component {
    constructor(props) {
        super(props);

        console.log(this);
    }

    componentDidMount() {
        Matter.Events.on(this.context.engine, 'afterUpdate', this.update);
    }

    componentWillUnmount() {
        Matter.Events.off(this.context.engine, 'afterUpdate', this.update);
    }

    update = () => {

    }

    render() {
        return (
            <Body
            args={[0, 384, 64, 64, { inertia: Infinity }]}
            ref={(b) => { this.body = b; }}>
                <Sprite
                    repeat={false}
                    src={require("assets/sprites/rocket.gif")}
                    state={0}
                    steps={[0]}
                />
            </Body>
        );
    }
}
export default Ship;

the world child (Ship) shows undefined on this.context, can you help me?

Run into a problem with two or more sprites changing state simultaneously

https://mkoth.github.io/game-kit-example/ - here the example
repository is here - https://github.com/MKoth/game-kit-example
As you can see, after first update of state which happend each 3 sec, for both of sprites, the first spritte loosing fps to 0, while second sprite increasing it.
I guess the problem is with animation subscription in Sprite component, but it can be my bug.
Please, let me know if I'm doing something wrong.
Thank you!

Stage doesn't get the correct w/h

Hello @kenwheeler,

First of all, such a great wrapper around matter-js, I didn't know it before and I found it very useful.
Thanks ๐Ÿ‘

If I have a basic structure like this:

<Loop>
  <Stage width={1024} height={576}>
    <World>
      <Body args={[20, 50, 100]}>
        <Sprite
          repeat
          src='assets/megaman.png'
          ticksPerFrame={1}
          scale={1}
          steps={[1, 2, 3, 4]}
        />
      </Body>
    </World>
  </Stage>
</Loop>

It renders like that:

<div data-reactroot="" data-radium="true" style="height: 100%; width: 100%;">
   <div style="height: 100%; width: 100%;">
    <div style="height: 100%; width: 100%; position: relative;">
     <div style="height: 0px; width: 0px; position: absolute; overflow: hidden; transform: translate(398px, 0px);">
      <div style="position: absolute; top: 0px; left: 0px; height: 100%; width: 100%;">
       <div style="height: 64px; width: 64px; overflow: hidden; position: relative; transform: scale(1); transform-origin: left top 0px; image-rendering: pixelated;">
        <img src="assets/megaman.png" style="position: absolute; transform: translate(-384px, 0px);" />
       </div>
      </div>
     </div>
    </div>
   </div>
  </div>

Problem

The problem that I was running with this is that <Stage /> creates a Container and an extra element as I can see it here, and forces the size of the container being full screen, but the child to be absolute and defined by getScale method.

Work-arround

So I need to reset the position of the innerElement adding style={{ position: 'static' }} into <Stage /> for not be able to overflow with a non-sized div inside.

Posible explaination?

I'm thinking that the "problem" here is that I'm trying to render a Sprite with a Body on top, so they don't have the dimensions yet, so the Stage can't calculate the space correctly?

I couldn't find a proper description about <Stage /> in the docs, could be worth it explaining it? In the case that I'm right.

I would love to help to improve the documentation and try to contribute to this project and see how perform with HTML 2D Games.

Thanks ๐Ÿ˜„

Replacing Loop div element with Fragment

const defaultStyles = {
height: '100%',
width: '100%',
};
const styles = { ...defaultStyles, ...this.props.style };
return (
<div style={styles}>
{this.props.children}
</div>
);
}

Since Loop doesn't say anything about rendering, maybe we could change this div to React.Fragment?
I'm happy to make a PR if it's okay.

Unit Test Mocks

Any plans to provide a guideline for how to mock this library for testing?

I am finding a component I need to test uses the component and its difficult to get it to run under test.

Thanks!

tilemap not updating when passed new array props

Hi! This is an awesome package and we are using it to build a fun little 2d game. It involves a fog of war for the player and are trying to render it as a tileMap over the regular background tileMap that is updated as the logic grid changes. However, passing the tilemap a new array doesn't trigger a re-render!

How to create a component of falling shapes

Hello, I was wondering if you might be able to talk me through using react-game-kit to make an animation similar to this pens content Im intending to make an invoice design app and wanted to convert the invoices's total to match the number of falling shapes.

Performance without canvas?

Hey! This looks super cool, because React is cool and games are cool...but can this really achieve 60fps without the use of canvas? I assume spawning lots of particles will cause some jank?
Thanks.

Have more complex examples

I'm starting out with game development and more specifically with react-game-kit.

It was really easy to have a simple game running, but now that I'm reaching more complex challenges I'm struggling.

Is it possible to have more complex examples? Or a list pointing out to projects built with react-game-kit that can help newbies?

It would be nice to include stuff like:

  • Infinite scrolling background (I don't know how to do this efficiently)
  • Collision Detection handling
  • Performance optimisations
  • Menus
  • Drag and Drop

I am starting for game developing with using react-game-kit

I tried myself. But it is not working. I gonna make image animation first.
I run localhost:3000
I have already created app: okan
So i got react static screen by localhost:3000
I wanna use demo and samples of https://github.com/FormidableLabs/react-game-kit by customizing okan/src/app.js
my first example code is below
import React, { Component } from 'react';
import { Loop, Stage,World, Body, MySprite } from 'react-game-kit';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';

class Game extends Component {
render() {
return (
<Body
args={[0, 384, 64, 64, { inertia: Infinity }]}
ref={(b) => { this.body = b; }}
>


);
}
}

export default Game;

but this is error
TypeError: Cannot read property 'world' of undefined
new Body
C:/Program Files/nodejs/node_modules/react-game-kit/lib/components/body.js:48
45 | options = _objectWithoutProperties(props, ['args', 'children', 'shape']); // eslint-disable-line no-unused-vars
46 |
47 | _this.body = _matterJs.Bodies[shape].apply(_matterJs.Bodies, _toConsumableArray(args).concat([options]));

48 | _matterJs.World.addBody(context.engine.world, _this.body);
49 | return _this;
50 | }
51 |
View compiled
constructClassInstance
C:/Program Files/nodejs/okan/node_modules/react-dom/cjs/react-dom.development.js:6355
6352 | var unmaskedContext = getUnmaskedContext(workInProgress);
6353 | var needsContext = isContextConsumer(workInProgress);
6354 | var context = needsContext ? getMaskedContext(workInProgress, unmaskedContext) : emptyObject;
6355 | var instance = new ctor(props, context);
6356 | adoptClassInstance(workInProgress, instance);
6357 |
6358 | // Cache unmasked context so we can avoid recreating masked context unless necessary.
View compiled
updateClassComponent
C:/Program Files/nodejs/okan/node_modules/react-dom/cjs/react-dom.development.js:7839
7836 | if (current === null) {
........................

It seems like that i don't know method that use tags of react-game-kit package
If react-game-kit tags is working in my app.js, then i want to build for displaying my hosting webserver.
But i don't know well cause i am amateur.
Thanks for your advise.

TileMap prop issues

TileMap asks for a src prop which on the ReadMe says a string, but the code asks for a number. As well as the src prop needs "require={string}" and not just the string.

changing steps or repeat on a sprite doesn't work

Hey Im changing the steps and repeat with key presses on a Sprite. I see the state change in the react dev tools but it does not change the way the sprite behaves.

<Sprite repeat={this.state.repeat}
         scale={0.1}
         offset={[0, 10]}
         state={this.state.facing}
         steps={this.state.steps}
         tileHeight={2400/4}
         tileWidth={1841/4}
         src="./sprites/test2.png" />

Like this, handing state to the sprite.
It works when i make my first key press but not on release

checkKeys = () => {
	const { keys } = this.props;
	let { facing, repeat, steps } = this.state;

	if (keys.isDown(keys.DOWN)) {
		facing = 0;
		repeat = true;
		steps = [3, 3, 3, 3];
	}

	if (keys.isDown(keys.LEFT)) {
		facing = 2;
		steps = [3, 3, 3, 3];
		repeat = true;
	}

	if (keys.isDown(keys.RIGHT)) {
		facing = 1;
		steps = [3, 3, 3, 3];
		repeat = true;
	}

	if (keys.isDown(keys.UP)) {
		facing = 3;
		steps = [3, 3, 3, 3];
		repeat = true;
	}

	if (!keys.isDown(keys.UP) && !keys.isDown(keys.RIGHT) && !keys.isDown(keys.LEFT) && !keys.isDown(keys.DOWN)) {
		steps = [0, 0, 0, 0];
		repeat = false
	}

	this.setState({facing: facing, repeat: repeat, steps: steps});
}

This is my check keys function

Works in chrome 54 breaks in chrome 55

Demo game played fine then I updated chrome and get this err:
Cannot read property 'id' of null

function transformGamepad(threshold, gamepad) {
var gp = {
id: gamepad.id, <(----THIS gamepad is undefined
buttons: {},
axes: {}
};

Physics issue while trying to reproduce AirFriction basic example

I'm trying to reproduce a very simple matter-js example and not sure why but somehow two of my three rectangles keep falling into the floor. I've created two components Rectangle and Wall to represent them on screen.

Not sure if it's a bug or if I'm missing something, but would love any help!

import React, {Component} from 'react';
import {Loop, Stage, World as WorldComponent} from 'react-game-kit';
import Matter, {Bodies, World} from 'matter-js';

import Rectangle from './components/Rectangle';
import Wall from './components/Wall';

export default class App extends Component {
  static defaultProps = {
    width: 800,
    height: 800,
  };
  state = {
    gravity: 1
  }
  render() {
    const {width, height} = this.props;
    const {gravity} = this.state;
    return (
      <Loop>
        <Stage width={width} height={height} style={{ background: '#3a9bdc' }}>
          <WorldComponent gravity={{ x: 0, y: gravity }}>
            <Wall args={[0, 0, 800, 5]} />
            <Wall args={[0, 0, 5, 800]} />
            <Wall args={[800 - 5, 0, 5, 800]} />
            <Wall args={[0, 800 - 5, 800, 5]} />
            <Rectangle args={[200, 100, 60, 60]} frictionAir={0.001} />
            <Rectangle args={[400, 100, 60, 60]} frictionAir={0.05} />
            <Rectangle args={[600, 100, 60, 60]} frictionAir={0.1} />
          </WorldComponent>
        </Stage>
      </Loop>
    )
  }
}

I've set up a reproducible repo on my private GitLab, any chance you could have a quick look to see if it's a bug or if I'm missing something?

Finally, would be great to add more examples to the repo, could land a couple PRs once I'm a bit more ready :).

Sprite Src Issue In RN

I am using React Native and I am making a game with this library. When I made a sprite, it came up with this warning, but the sprite shows up and works completely fine. It is more of an annoyance with the ugly yellow warning
image

-- I have tried
src={'../../images/sampleimage.png'}
and it seems to make the error go away but the image isn't there. Here is my code =>
image

Contributing more examples and basic drawable shapes

I've spent some time playing with react-game-kit and did reproduce several examples from the official matter-js repo. The single demo currently commited in the repo is really nice but makes it quite hard to build basic things like gravity demos.

Would be great to have basic shape elements, like a Rectangle, a Circle that can easily be drawn into the dom.

Using SVGs is quite easy, properly rendering a pure div however is not trivial. I think we should keep all options on the table (even with Canvas on the corner) since it allows more creative usage of the lib.

Maybe we should go for several base classes (SvgRectange, DivRectangle)?

Air friction example (gif makes it slow):
air-friction

import React, {Component} from 'react';
import {Stage, World} from 'react-game-kit';

import Rectangle from './../components/Rectangle';

const BoxA = () => <Rectangle args={[200, 100, 60, 60]} frictionAir={0.001} />
const BoxB = () => <Rectangle args={[400, 100, 60, 60]} frictionAir={0.05} />
const BoxC = () => <Rectangle args={[600, 100, 60, 60]} frictionAir={0.1} />

const Walls = ({width, height}) => (<div>
  <Rectangle args={[400, 0, 800, 50]} isStatic={true} />
  <Rectangle args={[400, 600, 800, 50]} isStatic={true} />
  <Rectangle args={[800, 300, 50, 600]} isStatic={true} />
  <Rectangle args={[0, 300, 50, 600]} isStatic={true} />
</div>);

export default class AirFrictionStage extends Component {
  static defaultProps = {
    width: 800,
    height: 600,
    background: 'rgb(24, 24, 29)'
  };
  render() {
    const {width, height, background} = this.props;
    return (
      <Stage width={width} height={height} style={{background}}>
        <World>
          <BoxA />
          <BoxB />
          <BoxC />
          <Walls />
        </World>
      </Stage>
    )
  }
}

Would you be interested in several PRs adding such components along several matter-js ready-to-go examples for a more batteries-included approach?

Example for React Native?

Any chance someone has created an example in React Native? Since a few things are different, it would really help to have some working example code to help people get started. Thanks!

React Native: <Body><View> = Position disarray

I create a ball to bounce against bodies. I pass the args to the < body > and in the < body > I create a < View > with this style={this.getStyles(bodyFromArray, 'blue')}:

getStyles(body, color) {
    return {
      height: body[3] * PixelRatio.get(),
      width: body[2] * PixelRatio.get(),
      backgroundColor: color,
      position: "absolute",
      transform: [
        { translateX: body[0] * PixelRatio.get() },
        { translateY: body[1] * PixelRatio.get() }
      ]
    };
  }

This also works so far, the ball bounces off the body, but shifted from the drawn view. It seems to me that the Bodies object is moved and bigger.

What can i do?

Code:

<Body
 shape="rectangle"
 density={1}
 label={"body"}
 friction={1}
                   frictionStatic={0}
                    restitution={1}
                    args={[
                      body[0],
                      body[1],
                      body[2],
                      body[3]
                    ]}
                    isStatic={true}
                  >
                    <View style={this.getStyles(body, "black")} />
                  </Body>

Touch interactions

Are there any plans on handling touch interactions? Maybe a Constraint and a TouchConstraint that wraps PanResponder.

I'm thinking it should be possible to do something like this:

class Touch extends Component {
    static contextTypes = {
        loop: PropTypes.object,
    }

    constructor(props) {
        super(props)

        this.state = {x: 0, y: 0, pressed: false}

        this.panResponder = PanResponder.create(/* update state handlers */)
    }

    update = () => {
        // Find bodies at touch position
    }

    componentDidMount() {
        this.context.loop.subscribe(this.update);
    }

    componentWillUnmount() {
        this.context.loop.unsubscribe(this.update);
    }

    render() {
        return (
            <View {...this.panResponder.panHandlers}>
                {children}
            </View>
        )
    }
}

export default Touch

Would be cool to hear your thoughts

Expected a component class, got [object Object].

Hi, I just installed react-game-kit from npm, but when I try to create a simple Loop with a Stage and an Image, the iOS simulator crashes and reports the error: "Expected a component class, got [object Object]."

I've read online that this may come from lowercase named components but I've checked the react-game-kit folder in node_modules and all the component classes are defined with capital letters.

Is there something else I am missing? Thank you. :)

node v5.1.0
npm v3.10.9
react-native-cli v2.0.1
react-native v0.39.2

Return a map of Bodies from an array

I am making a sidescrolling game, and I am rendering multiple enemies in random positions. I am working with the onCollide function so I can easily implement player/enemy collision without messing with pixels and all that jazz. The problem is that when I map an array of random points and for each index, return one custom enemy object, I can't change the reference to the body(The "this.body = b" prop) on each index. This results in each body rendering at the same point and collisions not being logged.
It has to be a body in order to calculate the collisons. I am considering moving to p2 physics for their bodies and keeping sprites and other parts of this library unless I find an efficient solution for this. Thanks in advance

Bodies are positioned relative to their center points

I just put together a simple game to test the library:
https://github.com/JeffreyATW/react-redux-platformer

I noticed that the collision was off when I first placed bodies in the world, and only noticed later that it was because I was treating their coordinates as originating from the upper left, while Matter.js was treating them from their center.

I have to position elements and factor in their widths and heights, which seems like overkill:

{
  transform: `translate(${(targetX - this.width / 2) * scale}px, ${(y - this.height / 2) * scale}px)`
}

I'm currently not using the Sprite class, so I don't know if that would somehow solve the problem, but I'm wondering if there's a simple way of reconciling the differences in origin points. Is there some sort of setting I can pass to Matter.js, or some easier way to store their coordinates that I'm not thinking of?

Drawing API?

Is there an API to draw lines, curves, circles, etc?

Release tooling / documentation

  • Add documentation in CONTRIBUTING.md or README.md as appropriate for all steps. Make sure to document that we require an npm version workflow.
  • Change existing package.json:lint task to be ``package.json:lint-fix`
  • Create a non --fix script task package.json:lint
  • Add package.json:preversion task that does npm run lint
  • Add package.json:clean-build task that does rimraf lib
  • Add package.json:version task that does npm run clean-build && npm run build && npm run umd

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.