How To Build A Game Using React Native

How To Build A Game Using React Native

No surprise here, but nowadays Mobile Games are sitting top in the digital world. So I've tried to get inspiration for building a game but, what's the exciting fact of this game? Yes! you saw it right it is made using React Native.

Undoubtedly, this game would not let you leave your phones. When considering the design for this game and in order to welcome players with the aforementioned sense of surprise, I decided to give the physical materials a more realistic look than before.

Just wanna check out the code? Help yourself ☟

The hard thing about building Games is to synchronize all the logic you want to apply in order to make things move, for example in my case I want to use gravity. React Native does not provide any feature for providing gravity so for that case I came up with the idea of using Matter.js.

What is Matter.js? Matter.js is a 2D physics engine that will help us to add physics to React Native. But matter.js alone won't cut it so we have to use react-native-game-engine which will help us to easily setup matter.js with React Native.

So, Let's start by creating a new app :

npx react-native init GameApp

Now we have to add react-native-game-engine and Matter.js :

npm install matter-js react-native-game-engine --save

It is always a good practice to start writing code in a proper folder structure in order to save time in refactoring the code. You can follow any folder structure you like to use, I will be following the below folder structure :

asdas.png

Now it's time to finally start some coding… We need to create a world and add a plane to this world.

App.js ☟

src/entities/index.js☟

src/components/Plane.js☟

12.gif

Now let's just add some physics, so that gravity can do its magic…✨

By default Matter provides a world with a gravity of 1.0, but to acquire more smoothness we will set it to 0.25. Now we will use the updated functionality of matter.js which will update the latest value of all the entities present in its world and it will be wrapped in RNGE systems props which call the passed set of functions in a period cycle.

Update App.js ☟

import Systems from './src/systems';
<GameEngine
    ref={(ref) => { this.gameEngine = ref; }}
    style={styles.gameContainer}
    running={this.state.running}
    systems={Systems}
    entities={this.entities}>
</GameEngine>

src/systems/index.js ☟

import Physics from './physics';
export default [Physics];

src/systems/physics.js ☟

13.gif

Now it's time to make this plane fly….🚀

Matter.js provides a couple of functions through which we can work this around. The one which we are going to use is setVelocity which can be called when the screen is touched and this is where RNGE plays its role by providing us with a touch event.

src/systems/plane.js ☟

Update src/systems/index.js :

import Physics from './physics';
import Plane from './plane';
export default [Physics, Plane];

14.gif

Now it's time to add a floor and a ceiling so that we can detect when a collision is made otherwise our plane will never stop falling…

src/components/Floor.js☟

src/components/Ceiling.js☟

Update src/entities/index.js☟

import Floor from '../components/Floor';
import Ceiling from '../components/Ceiling';
Floor: Floor(world,'white',{x: width / 2, y: height - 50},{height: 100, width: width}),
Ceiling: Ceiling(world,'white',{x: width / 2, y: 0},{height: 100, width: width}),

15.gif

In matter.js by applying isStatic we can make the floor and ceiling a static body that can never change position or angle and is completely fixed. With the help of this, we can now prevent the plane from falling down or going above our game area.

Now it's time to make our game more interesting by adding obstacles and increase the difficulty level.

src/components/Obstacle.js☟

src/utils/random.js☟

We will use Math.random for producing different sizes for every obstacle.

src/utils/constants.js☟

const Constants = {
TOP_PIPE_WIDTH: 250,
BOTTOM_PIPE_WIDTH: 100,
};
export default Constants;

Update src/entities/index.js☟

import Obstacle from '../components/Obstacle';
import {getRandom,topObstacleHeight,topObstacleHeight} from '../utils/random';
import Constants from 'src/utils/constants';

Obstacle1: Obstacle(world,'top',{x: width * 2 - Constants.TOP_PIPE_WIDTH / 2, y: getRandom(100, 400)},{height: topObstacleHeight, width: Constants.TOP_PIPE_WIDTH}),
Obstacle2: Obstacle(world,'bottom',{x: width - Constants.BOTTOM_PIPE_WIDTH / 2,y: getRandom(400, 700)},{height: bottomObstacleHeight, width: Constants.BOTTOM_PIPE_WIDTH}),

16.gif

But creating obstacles is not enough, we need to move these obstacles and create never-ending obstacles. To achieve this goal we need to use matter.js.

src/systems/obstacle.js ☟

Update src/systems/index.js :

import Physics from './physics';

import Plane from './plane';

import Obstacle from './obstacle';

export default [Physics, Plane, Obstacle];

Matter.js has a feature of translate through which we can change the position by a given vector relative to its current position, without imparting any velocity. Due to this, we get an illusion of moving obstacles.

If the x-axis position of an obstacle body becomes negative of its width then it means it has left the screen. At that time we can set the position of that body to 2 times its original position and so on this cycle will repeat making it a never-ending loop.

17.gif

Last we want to check when a collision is made so that we can stop the game and announce the score. Matter.Events.on help to pass a callback function whenever a particular event occurs. We can easily add a collision event with the help of this method.

Update src/systems/.js :

Matter.Events.on(engine, 'collisionStart', (event) => {
    dispatch({ type: "game-over"});         
});

Update App.js :

onEvent = e => {
if (e.type === 'gameOver') {
   Alert.alert('Game Over');
   this.setState({running: false,});
 } 
};

<GameEngine
    ref={(ref) => { this.gameEngine = ref; }}
    style={styles.gameContainer}
    onEvent={this.onEvent}
    running={this.state.running}
    systems={Systems}
    entities={this.entities}>
</GameEngine>

18.gif

Yayyyyy!!! We found a new game to get addicted to…

19.png