bberak / react-native-game-engine

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

New version of react and react-native does not work with Matter-js #53

Closed sovanminea closed 4 years ago

sovanminea commented 4 years ago

I follow the instruction and configure with matter js to test gravity but it does not work.

Simulator Screen Shot - iPhone 11 - 2020-05-15 at 09 01 39

dhirb commented 4 years ago

Can you show your code? I'm using Matter with React 16.11.0 and RN0.62.2. Gravity is working for me.

sovanminea commented 4 years ago

Physics.js `import Matter from "matter-js";

const Physics = (entities, { touches, time }) => { let engine = entities.physics.engine; console.log(engine); // Matter.Engine.update(engine, time.delta); Matter.Body.translate(entities['dinosaur'].body, { x: +1, y: +1 }); Matter.Engine.update(engine, time.delta); return entities; };

export default Physics;`

and app here `export default class App extends PureComponent {

constructor(props) {
    super(props);

    this.state = {
        running: true
    };
    this.gameEngine = null;

    this.entities = this.setupWorld();
}

setupWorld = () => {
    // Matter.Common.isElement = () => false;

    let engine = Matter.Engine.create({ enableSleeping: false });
    let world = engine.world;
    world.gravity = { x: 0, y: 2 };

    let dinosaur = Matter.Bodies.rectangle(Constants.MAX_WIDTH * 0.22, Constants.MAX_HEIGHT * 0.50, 50, 50, { isStatic: false, isSleeping: false });
    // let floor = Matter.Bodies.rectangle(0, Constants.MAX_HEIGHT * 0.72, Constants.MAX_WIDTH, 1, { isStatic: true });

    Matter.World.add(world, [dinosaur]);
    return {
        physics: { engine: engine, world: world },
        // floor: { body: floor, size: [Constants.MAX_WIDTH, 1], color: 'blue', renderer: <Floor /> },
        dinosaur: { body: dinosaur, size: [50, 50], color: 'green', renderer: Dinosaur },
    }
}

render() {
    return (
        <View style={styles.container}>
            <GameEngine
                ref={(ref) => { this.gameEngine = ref; }}
                style={styles.gameContainer}
                running={this.state.running}
                systems={[Physics]}
                entities={this.entities}
            >
                <StatusBar hidden={true} />
            </GameEngine>
        </View>
    );
}

}`

dhirb commented 4 years ago

Have you tried to set just the y-gravity? The x-gravity defaults to 0 so you can skip that. world.gravity.y = 2;

Also what does this do in Physics.js? Can you try to comment out this line and see if it works? Matter.Body.translate(entities['dinosaur'].body, { x: +1, y: +1 });

sovanminea commented 4 years ago

@yuenlye still not working. Screen Shot 2020-05-27 at 4 39 14 PM

bberak commented 4 years ago

Hi @sovanminea - can you show us your code for the Dinosaur component?

sovanminea commented 4 years ago

hi @bberak here it is ` export default class Dinosaur extends PureComponent { render() { const width = this.props.size[0]; const height = this.props.size[1]; const x = this.props.body.position.x - width / 2; const y = this.props.body.position.y - height / 2;

    return (
        <View
            style={{
                position: "absolute",
                left: x,
                top: y,
                width: width,
                height: height,
                backgroundColor: this.props.color
            }} />
    );
}

} `

bberak commented 4 years ago

Hmmm that looks okay.. As @yuenlye mentioned - have you tried uncommenting this line:

Matter.Body.translate(entities['dinosaur'].body, { x: +1, y: +1 });

Also, maybe try give the dinosaur body a mass - some physics engines will consider bodies with a mass of zero as static.

As a last resort, you can try create a snack of your app - that will help us debug (but do this last).

bberak commented 4 years ago

Hi @sovanminea,

Could this be a similar issue to: https://github.com/bberak/react-native-game-engine/issues/56#issuecomment-648527634

A quick way to test this would be to extend Dinosaur from React.Component rather than React.PureComponent.

Solid-Metal commented 4 years ago

hey, i use react-native-cli: 2.0.1 react-native: 0.60.5

same problem, its indeed rendering problem i think, since i log the body position and its changing, but whatever i've done it seems its to no avail, is there any example to use the setState for this case?, since i automatically move the object from system rather than controlling it with button or something

dhirb commented 4 years ago

@Solid-Metal Don't really have the exact solution, but you can check out my code skeleton. I used the accelerometer to update the x position of a body.

Or you can try to dispatch an event in system and update the body position in the event handler?

bberak commented 4 years ago

Hey @Solid-Metal,

Can you share your renderer code?

Solid-Metal commented 4 years ago

hey sorry for the late reply, heres my renderer

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

        this.state = {

        }
    }

    render() {
        const x = this.props.position[0];
        const y = this.props.position[1];

        return (
            <View style={[styles.claw, { left: x * this.props.size, top: y * this.props.size }]}>
                <Image source={require('../../assets/images/gamification/crane.png')}/>
            </View>
        );
    }
}

export { Claw };
bberak commented 4 years ago

Hmm @Solid-Metal,

That looks fine - you're extending Component rather than PureComponent, so Claw should rerender on every frame..

Can you try change Claw to a functional component:

function Claw(props) {
        const x = props.position[0];
        const y = props.position[1];

        return (
            <View style={[styles.claw, { left: x * props.size, top: y * props.size }]}>
                <Image source={require('../../assets/images/gamification/crane.png')}/>
            </View>
        );
}

export { Claw };
Solid-Metal commented 4 years ago

hey @bberak just trying it out, and it didnt work, still same problem, the matterjs physics body itself is moving, but not the image, even if i forcefully to moving it out using the position it just updating that renderer but not the physics

is there any chance it cause by the styling here [styles.claw, { left: x * props.size, top: y * props.size }] ?

bberak commented 4 years ago

Hmmm @Solid-Metal,

How come you are multiplying x and y by props.size?

Can you try and add this to your function/render method to see the values:

console.log(x * props.size,  y * props.size)

Also, I've got a similar example in the handbook project that might be useful to compare with: https://github.com/bberak/react-native-game-engine-handbook/blob/master/app/physics/rigid-bodies/renderers.js

Solid-Metal commented 4 years ago

sorry for late reply

yeah, i'm an idiot lol, i didn't pay attention to your handbook renderer function, i forgot to put the transform and rotation to the sprite, it now works well !

bberak commented 4 years ago

Awesome @Solid-Metal - glad you got it working ๐Ÿ‘