bberak / react-native-game-engine

A lightweight Game Engine for React Native ๐Ÿ•นโšก๐ŸŽฎ
MIT License
2.88k stars 172 forks source link

Renderer rotation issue #56

Open lexengineer opened 4 years ago

lexengineer commented 4 years ago

Hello everyone ๐Ÿ‘‹

I am trying to rotate one of my elements on the screen and I do this with Matter.js and react-native-game-engine all together.

I have the following logic:

Count angle for rotation manually => set this angle to the Matter.js body => achieve this newly set angle inside my render via props => trying to rotate my View with transform.

So everything works well until the last step when I am trying to rotate my View. It is not rotating at all, but Matter.js body has newly set angle. I think the issue can be inside rendering logic, but still not sure. Tried a lot of solutions already. Any help is appreciated.

This is my code:

This is my renderer component

const Dolphin = props => {
  const width = props.size[0];
  const height = props.size[1];
  const x = props.body.position.x - width / 2;
  const y = props.body.position.y - height / 2;

  return (
    <View
      style={[
        {
          position: 'absolute',
          width,
          height,
          backgroundColor: props.color,
          transform: [{ rotate: `${parseInt(props.body.angle)}deg` }],
        },
        { left: x, top: y },
      ]}
    >
      <Text color="white">{props.title}</Text>
    </View>
  );
};

This is how I set angle with Matter.js:

onPress={event => {
        event.persist();
        const dolphin = gameEngineRef.current.state.entities.dolphin;
        const pressEventX = event.nativeEvent.locationX;
        const pressEventY = event.nativeEvent.locationY;

        const angle = countAngle(40, 40, pressEventX, pressEventY);

        Matter.Body.setAngle(dolphin.body, angle);
      }}
bberak commented 4 years ago

Hi @oleksiikiselov,

What happens if you hardcode the angle to 45 degrees:

const Dolphin = props => {
  const width = props.size[0];
  const height = props.size[1];
  const x = props.body.position.x - width / 2;
  const y = props.body.position.y - height / 2;

  return (
    <View
      style={[
        {
          position: 'absolute',
          width,
          height,
          backgroundColor: props.color,
          transform: [{ rotate: `45deg` }],
        },
        { left: x, top: y },
      ]}
    >
      <Text color="white">{props.title}</Text>
    </View>
  );
};

Does the Dolphin appear rotated? It would be good to figure out whether the problem lies with MatterJS or there is something funny happening with the React Native styles that is preventing the View from being rotated.

bberak commented 4 years ago

Hi @oleksiikiselov,

I think the issue might then be that React is not re-rendering the the Dolphin because the props havent changed. It is doing a shallow compare (body === body) and therefore determining that an update is not required.

You can try and integrate useState and or useEffect into your Dolphin function so the angle becomes state, or turn the Dolphin function into a class and use shouldComponentUpdate to help React determine if your component needs to be re-rendered.

Hope that helps!

lexengineer commented 4 years ago

Hi @bberak,

Excuse me please, had to delete my previous message. Thank you for the advice, sounds reasonable. Will try to add that and get back to you. Thank you very much.