
Última atualização: 18/10/2022
React Native é um dos frameworks de desenvolvimento de aplicativos móveis mais populares projetada e desenvolvida pelo Facebook. O Facebook abriu sua base de código em 2015. Permite desenvolver um único código que roda nas duas plataformas que existem: Android e iOS.

Para instalar o jogo no seu celular use este link com o app Expo
Baixe o instalador direto do site site oficial. Após a instalação, você poderá verificar a instalação com o comando:
node -v
Depois de instalar o node, precisamos instalar Expo CLI:
npm install --global expo-cli
Na linha de comando crie uma pasta chamada projetos: e dentro desta pasta execute o comando npx abaixo:
npx create-expo-app jogo
Após o download e instalação das dependências, digite:
cd jogo code .
Depois de abrir o VSCode você verá a estrutura de pastas e arquivos do projeto criado, como mostrado abaixo:

Para executar o app em seu celular temos duas situações:
npx expo start

aVamos usas duas bibliotecas para construir o jogo. Então vamos instalar no nosso projeto. Na linha de comando e dentro da pasta da aplicação, execute o comando:
yarn add react-native-game-engine matter-js
Abra o arquivo App.js e apague todo o código, vamos começar do zero.
import Matter from "matter-js";
import { GameEngine } from "react-native-game-engine";
import { StyleSheet, StatusBar } from "react-native";
const App =() => {
return (
<GameEngine style={styles.container}>
<StatusBar hidden={true} />
</GameEngine>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#6ff",
},
});
export default App;
As entidades são como são os objetos do jogo. Vamos adicionar um entity simples - um retângulo - ao nosso engine. Crie um novo arquivo chamado Box.js.
import { View } from "react-native";
const Box = (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",
left: x,
top: y,
width: width,
height: height,
backgroundColor: props.color || "pink",
}}
/>
);
};
export default Box;
Para exibir o retângulo na tela, vamos voltar ao App.js
import Matter from "matter-js";
import { GameEngine } from "react-native-game-engine";
import { StyleSheet, StatusBar, Dimensions } from "react-native";
import Box from "./Box";
const { width, height } = Dimensions.get("screen");
const boxSize = Math.trunc(Math.max(width, height) * 0.075);
const initialBox = Matter.Bodies.rectangle(width / 2, height / 2, boxSize, boxSize);
const App = () => {
return (
<GameEngine
style={styles.container}
entities={{
initialBox: {
body: initialBox,
size: [boxSize, boxSize],
color: 'red',
renderer: Box
}
}}>
<StatusBar hidden={true} />
</GameEngine>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#6ff",
},
});
export default App;
Você verá a tela assim:

Vamos adicionar mais um objeto ao nosso engine:
const floor = Matter.Bodies.rectangle(width / 2, height - boxSize, width, boxSize, { isStatic: true });
E adicione o objeto floor à propriedade entities do
floor: {
body: floor,
size: [width, boxSize],
color: "green",
renderer: Box,
},
Vamos adicionar gravidade ao nosso mundo. Adicione as linhas abaixo
const engine = Matter.Engine.create({ enableSleeping: false });
const world = engine.world;
Para que nossos objetos sejam afetados pela física do nosso mundo, precisamos adicioná-los ao mundo
Matter.World.add(world, [initialBox, floor]);
Por fim, vamos adicionar o engine e world a nossa lista de entidades com o nome de physics:
entities={{
physics: {
engine: engine,
world: world
},
initialBox: {
body: initialBox,
size: [boxSize, boxSize],
color: 'red',
renderer: Box
},
floor: {
body: floor,
size: [width, boxSize],
color: "green",
renderer: Box
}
}}
Agora nossa lista de objetos do jogo está completa, vamos colocar em funcionamento este mundo. Então precisamos colocar um System ao nosso engine que faz o mundo funcionar.
System é um array contém uma série de funções, que serão chamadas em cada tick do jogo. Ou seja, essas funções serão executadas em uma velocidade muito rápida e podem ser usadas para verificar e atualizar nosso jogo. A primeira função que adicionaremos ao System será:
const Physics = (entities, { time }) => {
let engine = entities["physics"].engine;
Matter.Engine.update(engine, time.delta);
return entities;
};
As funções do sistema recebem dois parâmetros:
Por fim adicionamos o sistema ao engine:
<GameEngine
style={styles.container}
systems={[Physics]}
entities={{
physics: {
engine: engine,
world: world
},
initialBox: {
body: initialBox,
size: [boxSize, boxSize],
color: 'red',
renderer: Box
},
floor: {
body: floor,
size: [width, boxSize],
color: "green",
renderer: Box
}
}}>
<StatusBar hidden={true} />
</GameEngine>
Vamos criar um novo Box a cada touch do usuário. Crie uma nova função acima de App.
let boxIds=0;
const CreateBox = (entities, { touches, screen }) => {
let world = entities["physics"].world;
let boxSize = Math.trunc(Math.max(screen.width, screen.height) * 0.075);
touches
.filter((t) => t.type === "press")
.forEach((t) => {
let body = Matter.Bodies.rectangle(t.event.pageX, t.event.pageY, boxSize, boxSize, { frictionAir: 0.021, restitution: 1.0 });
Matter.World.add(world, [body]);
entities[++boxIds] = {
body: body,
size: [boxSize, boxSize],
color: "#a8f93f",
renderer: Box,
};
});
return entities;
};
Agora, vamos adicionar CreateBox ao array Systems no componente :
systems={[Physics, CreateBox]}
Vamos começar a desenvolver o jogo que apresentei no início da oficina.