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

How to put Body inside a different Component? #32

Open
Talor-A opened this issue Jun 9, 2017 · 1 comment
Open

How to put Body inside a different Component? #32

Talor-A opened this issue Jun 9, 2017 · 1 comment

Comments

@Talor-A
Copy link

Talor-A commented Jun 9, 2017

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>
    )
  }

}
@waelmas
Copy link

waelmas commented Sep 15, 2020

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)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants