skip to Main Content

I am newly started using matter-js and react-native-game-engine and trying to figure out why class definition is used. I observed such questions in stack but couldn’t find the exactly similar answer. I am confused to migrate this part especially: this.entities = this.setupWorld();. My whole class definition is as follows:

import Matter from "matter-js";
import { GameEngine } from "react-native-game-engine";

export default class GameApp extends Component {
    constructor(props){
        super(props);

        this.state = {
            running: true,
            score: 0,
        };

        this.gameEngine = null;

        this.entities = this.setupWorld();
    }

    setupWorld = () => {
        let engine = Matter.Engine.create({ enableSleeping: false });
        let world = engine.world;
        world.gravity.y = 0.0;

        let bird = Matter.Bodies.rectangle( Constants.MAX_WIDTH / 2, Constants.MAX_HEIGHT / 2, Constants.BIRD_WIDTH, Constants.BIRD_HEIGHT);

        let floor1 = Matter.Bodies.rectangle(
            Constants.MAX_WIDTH / 2,
            Constants.MAX_HEIGHT - 25,
            Constants.MAX_WIDTH + 4,
            50,
            { isStatic: true }
        );

        let floor2 = Matter.Bodies.rectangle(
            Constants.MAX_WIDTH + (Constants.MAX_WIDTH / 2),
            Constants.MAX_HEIGHT - 25,
            Constants.MAX_WIDTH + 4,
            50,
            { isStatic: true }
        );


        Matter.World.add(world, [bird, floor1, floor2]);
        Matter.Events.on(engine, 'collisionStart', (event) => {
            var pairs = event.pairs;

            this.gameEngine.dispatch({ type: "game-over"});

        });

        return {
            physics: { engine: engine, world: world },
            floor1: { body: floor1, renderer: Floor },
            floor2: { body: floor2, renderer: Floor },
            bird: { body: bird, pose: 1, renderer: Bird},
        }
    }

    onEvent = (e) => {
        if (e.type === "game-over"){
            //Alert.alert("Game Over");
            this.setState({
                running: false
            });
        } else if (e.type === "score") {
            this.setState({
                score: this.state.score + 1
            })
        }
    }

    reset = () => {
        resetPipes();
        this.gameEngine.swap(this.setupWorld());
        this.setState({
            running: true,
            score: 0
        });
    }

    render() {
        return (
            <View ...
         )
    }
}

My outcome is something like this but there is problem about passing props I think:

export default GameApp = () =>  {
    const [running, setRunning] = useState(true)
    const [score, setScore] = useState(0)
    let gameEngine = null
    let entities = null

    useEffect(()=>{
        entities = setupWorld()
    },[])

    const setupWorld = () => {
        let engine = Matter.Engine.create({ enableSleeping: false });
        let world = engine.world;
        world.gravity.y = 0.0;

        let bird = Matter.Bodies.rectangle( Constants.MAX_WIDTH / 2, Constants.MAX_HEIGHT / 2, Constants.BIRD_WIDTH, Constants.BIRD_HEIGHT);

        let floor1 = Matter.Bodies.rectangle(
            Constants.MAX_WIDTH / 2,
            Constants.MAX_HEIGHT - 25,
            Constants.MAX_WIDTH + 4,
            50,
            { isStatic: true }
        );

        let floor2 = Matter.Bodies.rectangle(
            Constants.MAX_WIDTH + (Constants.MAX_WIDTH / 2),
            Constants.MAX_HEIGHT - 25,
            Constants.MAX_WIDTH + 4,
            50,
            { isStatic: true }
        );


        Matter.World.add(world, [bird, floor1, floor2]);
        Matter.Events.on(engine, 'collisionStart', (event) => {
            var pairs = event.pairs;

            gameEngine.dispatch({ type: "game-over"});

        });

        return {
            physics: { engine: engine, world: world },
            floor1: { body: floor1, renderer: Floor },
            floor2: { body: floor2, renderer: Floor },
            bird: { body: bird, pose: 1, renderer: Bird},
        }
    }

    const onEvent = (e) => {
        if (e.type === "game-over"){
            setRunning(false)
        } else if (e.type === "score") {
            setScore(score+1)
        }
    }

    const reset = () => {
        resetPipes();
        gameEngine.swap(setupWorld());
        setRunning(true)
        setScore(0)
    }

        return (
            <View style={style
    ...

    )
    }

There is an error coming in this usage:

const Physics = (entities, { touches, time, dispatch }) => {
    let engine = entities.physics.engine;  // Cannot read property 'engine' of undefined 
let world = entities.physics.world;
let bird = entities.bird.body;

I tried passing them like this below but same error (cannot read ‘engine’ of undefined in Physics.js):

export default GameApp = (props) =>  {
    const [running, setRunning] = useState(true)
    const [score, setScore] = useState(0)
    let {gameEngine, entities} = props

Meanwhile, I am using this GameApp component as a screen in App.js like this:

function App() {
  ...
  return (
   <GameApp/>
  )
}

The reason why I am trying to migrate is to use the hooks.

2

Answers


  1. With functionnal component props are pass as first argument of your FC.

    You function should get GameApp function like that:

    export default GameApp = (props) =>  {
    const [running, setRunning] = useState(true)
    const [score, setScore] = useState(0)
    let gameEngine = null
    let entities = null
    
    useEffect(()=>{
        entities = setupWorld()
    },[])
    
    const setupWorld = () => {
        let engine = Matter.Engine.create({ enableSleeping: false });
        let world = engine.world;
        world.gravity.y = 0.0;
    
        let bird = Matter.Bodies.rectangle( Constants.MAX_WIDTH / 2, Constants.MAX_HEIGHT / 2, Constants.BIRD_WIDTH, Constants.BIRD_HEIGHT);
    
        let floor1 = Matter.Bodies.rectangle(
            Constants.MAX_WIDTH / 2,
            Constants.MAX_HEIGHT - 25,
            Constants.MAX_WIDTH + 4,
            50,
            { isStatic: true }
        );
    
        let floor2 = Matter.Bodies.rectangle(
            Constants.MAX_WIDTH + (Constants.MAX_WIDTH / 2),
            Constants.MAX_HEIGHT - 25,
            Constants.MAX_WIDTH + 4,
            50,
            { isStatic: true }
        );
    
    
        Matter.World.add(world, [bird, floor1, floor2]);
        Matter.Events.on(engine, 'collisionStart', (event) => {
            var pairs = event.pairs;
    
            gameEngine.dispatch({ type: "game-over"});
    
        });
    
        return {
            physics: { engine: engine, world: world },
            floor1: { body: floor1, renderer: Floor },
            floor2: { body: floor2, renderer: Floor },
            bird: { body: bird, pose: 1, renderer: Bird},
        }
    }
    
    const onEvent = (e) => {
        if (e.type === "game-over"){
            setRunning(false)
        } else if (e.type === "score") {
            setScore(score+1)
        }
    }
    
    const reset = () => {
        resetPipes();
        gameEngine.swap(setupWorld());
        setRunning(true)
        setScore(0)
    }
    
        return (
            <View style={style
    ...
    
    )
    }
    
    Login or Signup to reply.
  2. Javascript

    With Javascript, you do not need to type the properties, you can past them ambiguously. Also, here you can see we deconstruct the properties.

    export const FunctionalComponent = ({something, foo, bar}) =>{ ... }
    
    /** Usages **/
    <FunctionalComponent something={true} foo="hello" bar={[{id: 1, text: "some data"}]}/>
    

    Typescript

    Generally, it’s best practice to not do implicit anys which is what javascript does. The example below provides an interface to the props, so it’s hard-typed.

    interface Props {
       something: boolean,
       foo: string,
       bar: {id: number, text: string}[],
       optionalThing?: string,
    }
    
    export const FunctionalComponent: React.FC<Props> = (props: Props) => { ... }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search