Skip to content
This repository was archived by the owner on Feb 7, 2024. It is now read-only.

Commit 547ea7a

Browse files
committed
finishing touches for release
1 parent 79678a1 commit 547ea7a

File tree

11 files changed

+265
-30
lines changed

11 files changed

+265
-30
lines changed

README.md

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
<h1 align="center">react-game-kit</h1>
2+
3+
<h4 align="center">
4+
Make games with React & React Native!
5+
</h4>
6+
7+
***
8+
9+
<!-- MarkdownTOC depth=3 autolink=true bracket=round -->
10+
11+
12+
<!-- /MarkdownTOC -->
13+
14+
15+
## Install
16+
17+
`npm install react-game-kit --save`
18+
19+
## Get Started
20+
21+
`react-game-kit` provides a set of helper components to make it easier to create games with React and React Native.
22+
23+
You'll want to begin by importing the components you need:
24+
25+
```js
26+
import { Loop, Stage } from 'react-game-kit';
27+
```
28+
29+
### Loop & Stage
30+
31+
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:
32+
33+
```js
34+
render() {
35+
return (
36+
<Loop>
37+
<Stage>
38+
// Game specific components go here
39+
</Stage>
40+
</Loop>
41+
);
42+
}
43+
```
44+
45+
The `Loop` component uses `context` to pass a subscrible game tick down your component tree. The `Stage` component does the same with game scale.
46+
47+
### World
48+
49+
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:
50+
51+
```js
52+
render() {
53+
return (
54+
<Loop>
55+
<Stage>
56+
<World>
57+
// Game specific components go here
58+
</World>
59+
</Stage>
60+
</Loop>
61+
);
62+
}
63+
```
64+
65+
### Physics Bodies
66+
67+
Once you have a physics engine/world established, you can use the `Body` component to define physics bodies inline:
68+
69+
```js
70+
render() {
71+
return (
72+
<Loop>
73+
<Stage>
74+
<World>
75+
<Body args={[0,0,75,75]} ref={(b) => this.body = b.body; }>
76+
// Sprites go here
77+
</Body>
78+
</World>
79+
</Stage>
80+
</Loop>
81+
);
82+
}
83+
```
84+
85+
Using a ref you can obtain a reference to the physics body and modify its properties via the [Matter-js API](https://github.com/liabru/matter-js).
86+
87+
### Next Steps
88+
89+
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.
90+
91+
## React Native
92+
93+
Using this library with React Native is a simple as importing from the native directory:
94+
95+
```js
96+
import { Loop, Stage, ...etc } from 'react-game-kit/native';
97+
```
98+
99+
> Note: AudioPlayer and KeyListener are not implemented on the React Native version.
100+
101+
## API
102+
103+
#### \<Loop />
104+
105+
The `Loop` component acts much like a Redux provider, in that it passes a GameLoop instance down the component tree via `this.context.loop`.
106+
107+
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:
108+
109+
```js
110+
class ChildComponent extends React.Component {
111+
static contextTypes = {
112+
loop: PropTypes.object,
113+
};
114+
115+
update = () => {
116+
// tick logic
117+
};
118+
119+
componentDidMount() {
120+
this.context.loop.subscribe(this.update);
121+
}
122+
123+
componentWillUnmount() {
124+
this.context.loop.unsubscribe(this.update);
125+
}
126+
}
127+
128+
```
129+
130+
--
131+
132+
#### \<Stage />
133+
134+
**height** (_number_) : Base game height. Defaults to `576`.
135+
136+
**width** (_number_) : Base game width. Defaults to `1024`.
137+
138+
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.
139+
140+
--
141+
142+
#### \<World />
143+
144+
**gravity** (_object_) : World gravity object.
145+
146+
Defaults:
147+
148+
```js
149+
gravity={{
150+
x: 0,
151+
y: 1,
152+
scale: 0.001,
153+
}}
154+
```
155+
156+
**onCollision** (_func_) : World collision callback.
157+
158+
**onInit** (_func_) : World init callback.
159+
160+
**onUpdate** (_func_) : World update callback.
161+
162+
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.
163+
164+
The `onInit` callback is a great place to do your initial world setup, things like creating static bodies for walls and the floor.
165+
166+
--
167+
168+
#### \<Body />
169+
170+
**args** (_array_) : Initial body creation arguments. Depends on the `shape` prop, which maps to Matter.Bodies body creation methods detailed here: [Matter.Bodies Documentation](http://brm.io/matter-js/docs/classes/Bodies.html)
171+
172+
All other props on the body component map directly to [Matter-js Body properties](http://brm.io/matter-js/docs/classes/Body.html).
173+
174+
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.
175+
176+
--
177+
178+
#### \<Sprite />
179+
180+
181+
**offset** (array) : Sprite sheet x,y offset.
182+
183+
**onPlayStateChanged** (func) : Sprite play state changed callback.
184+
185+
**repeat** (bool) : Determines whether sprite animation should loop.
186+
187+
**scale** (number) : Scale value for sprite image.
188+
189+
**src** (string) : src path for sprite sheet.
190+
191+
**state** (number) : Vertical position in sprite sheet.
192+
193+
**steps** (array) : Number of animation steps for current row (state).
194+
195+
**ticksPerFrame** (number) : Number of loop ticks per animation frame.
196+
197+
**tileHeight** (number) : Height of spritesheet tile.
198+
199+
**tileWidth** (number) : Width of spritesheet tile.
200+
201+
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.
202+
203+
--
204+
205+
#### \<TileMap />
206+
207+
**columns** (number) : number of columns in tile map.
208+
209+
**layers** (array) : Array of arrays that contain tile indexes.
210+
211+
**renderTile** (func) : Overrideable tile rendering function.
212+
213+
**rows** (number) : Number of rows in tile map.
214+
215+
**scale** (number) : Tile map scale.
216+
217+
**src** (string) : Tilemap image src path.
218+
219+
**tileSize** (number) : Tilemap tile size.
220+
221+
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:
222+
223+
```js
224+
layers={[
225+
[
226+
0, 0, 0, 0,
227+
1, 0, 1, 1,
228+
0, 0, 1, 0,
229+
1, 0, 0, 0,
230+
]
231+
]}
232+
```
233+
234+
--
235+
236+
237+
238+
## License
239+
240+
[MIT License](http://opensource.org/licenses/MIT)

TODO.md

Lines changed: 0 additions & 5 deletions
This file was deleted.

demo/game/character.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ export default class Character extends Component {
203203
<div style={this.getWrapperStyles()}>
204204
<Body
205205
args={[x, 384, 64, 64]}
206+
inertia={Infinity}
206207
ref={(b) => { this.body = b; }}
207208
>
208209
<Sprite

native.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import Body from './lib/native/components/body.js';
2+
import Loop from './lib/native/components/loop.js';
3+
import Sprite from './lib/native/components/sprite.js';
4+
import Stage from './lib/native/components/stage.js';
5+
import TileMap from './lib/native/components/tile-map.js';
6+
import World from './lib/native/components/world.js';
7+
8+
export {
9+
Body,
10+
Loop,
11+
Sprite,
12+
Stage,
13+
TileMap,
14+
World,
15+
};

package.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"description": "Make games with react",
55
"main": "lib",
66
"files": [
7+
"native.js",
78
"lib",
89
"umd"
910
],
@@ -24,10 +25,6 @@
2425
"dependencies": {
2526
"matter-js": "^0.10.0"
2627
},
27-
"peerDependencies": {
28-
"react": "^15.2.1",
29-
"react-dom": "^15.2.1"
30-
},
3128
"devDependencies": {
3229
"babel-cli": "^6.10.1",
3330
"babel-core": "^6.10.4",

src/components/body.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ export default class Body extends Component {
6161

6262
static defaultProps = {
6363
args: [0, 0, 100, 100],
64-
inertia: Infinity,
6564
restitution: 0,
6665
friction: 1,
6766
frictionStatic: 0,

src/native/components/body.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ export default class Body extends Component {
6161

6262
static defaultProps = {
6363
args: [0, 0, 100, 100],
64-
inertia: Infinity,
6564
restitution: 0,
6665
friction: 1,
6766
frictionStatic: 0,

src/native/components/world.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React, { Component, PropTypes } from 'react';
22

33
import { View } from 'react-native';
44

5-
import { Engine, Events } from 'matter-js';
5+
import Matter, { Engine, Events } from 'matter-js';
66

77
export default class World extends Component {
88

@@ -19,7 +19,11 @@ export default class World extends Component {
1919
};
2020

2121
static defaultProps = {
22-
gravity: [0, -25],
22+
gravity: {
23+
x: 0,
24+
y: 1,
25+
scale: 0.001,
26+
},
2327
onCollision: () => {},
2428
onInit: () => {},
2529
onUpdate: () => {},

src/native/index.js

Lines changed: 0 additions & 15 deletions
This file was deleted.

src/utils/game-loop.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export default class GameLoop {
1616
}
1717
}
1818
stop() {
19-
window.cancelAnimationFrame(this.loop);
19+
window.cancelAnimationFrame(this.loopID);
2020
}
2121
subscribe(callback) {
2222
return this.subscribers.push(callback);

webpack.config.dev.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ module.exports = {
1515
new webpack.NoErrorsPlugin(),
1616
new webpack.DefinePlugin({
1717
'process.env': {
18-
NODE_ENV: JSON.stringify('development'),
18+
NODE_ENV: JSON.stringify('production'),
1919
},
2020
}),
2121
],

0 commit comments

Comments
 (0)