react-game-kit
react-game-kit copied to clipboard
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>
)
}
}
A bit late to the party, but I think this tutorial and this tutorial will give you all the answers you need. (Had a similar question and found them so thought they might help someone)