Ú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
a
Vamos 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.