Introdução ao Matter.js: criando corpos físicos
O Matter.js é uma biblioteca JavaScript que permite criar simulações físicas realistas em 2D. Com ela você pode:
Criar corpos com propriedades físicas (peso, atrito, elasticidade)
Simular colisões e interações entre objetos
Desenvolver jogos e experiências interativas
Exemplo Prático: Simulação de Corpos Físicos
Aqui está a animação que usaremos como referência:
Passo 1: Configurando o ambiente
Antes de começarmos a programar, certifique-se de ter um ambiente de desenvolvimento configurado:
Um editor de código (VS Code)
- Um navegador (Google Chrome)
Arquivo de template
Passo 2: Declaração de variáveis
Aqui estamos declarando as variáveis que serão usadas para armazenar os módulos do Matter.js e os corpos físicos.
// Módulos do Matter.js
const Engine = Matter.Engine;
const World = Matter.World;
const Bodies = Matter.Bodies;
const Body = Matter.Body;
// Variáveis do jogo
let engine;
let world;
var ball;
var ground;
var wall;
var angle=60;
var wall2;
var ball_options;
var ground_options;
var wall_ops;
Engine
: O “cérebro” que calcula todas as interações físicasWorld
: O “container” onde todos os objetos físicos existemBodies
: Ferramenta para criar novos objetosBody
: Permite manipular objetos após a criação (ex.: girar paredes)
Passo 4: Função setup()
A função setup()
é executada apenas uma vez e configura o ambiente do jogo.
createCanvas(400,400)
: Cria uma área de desenho de 550×600 pixels
function setup(){
createCanvas(550,600);
Agora criamos o motor de física:
// Cria o motor de física
engine = Engine.create();
world = engine.world;
Engine.create()
: Inicializa o motor de físicaengine.world
: Acessa o mundo físico criado
Vamos configurar as opções do chão, sabendo que ele é um corpo estático:
// Configuração do chão (objeto estático)
ground_options = {
isStatic: true // Não se move, mesmo com colisões
};
isStatic: true
: Faz o corpo ficar imóvel (perfeito para chão e paredes)
Agora criamos o corpo do chão:
// Cria o chão
ground = Bodies.rectangle(200, 390, 400, 20, ground_options);
World.add(world,ground);
Bodies.rectangle()
: Cria um retângulo físico nas coordenadas (275,590) com 550×20 pixelsWorld.add()
: Adiciona o corpo ao mundo físico
E criamos mais duas paredes com propriedades iguais:
Para a primeira parede temos:
// Parede 1
wall_ops={
isStatic:true
};
wall = Bodies.rectangle(300, 150, 70, 10, ground_options);
World.add(world,wall);
isStatic: true
: Faz o corpo ficar imóvel (perfeito para chão e paredes)Bodies.rectangle()
: Cria um retângulo físicoWorld.add()
: Adiciona o corpo ao mundo físico
Para a segunda parede temos:
// Parede 2
wall_ops={
isStatic:true
};
wall2 = Bodies.rectangle(100,200,100,20,wall_ops);
World.add(world,wall2);
isStatic: true
: Faz o corpo ficar imóvel (perfeito para chão e paredes)Bodies.rectangle()
: Cria um retângulo físicoWorld.add()
: Adiciona o corpo ao mundo físico
E por fim criamos a bola:
// Configuração da bola
ball_options = {
restitution: 0.95,
frictionAir: 0.01
};
ball = Bodies.circle(100,10,20,ball_options);
World.add(world,ball);
}
restitution: 0.95
: Define um quique alto (95% da energia conservada)friction: 0.01
: Muito pouco atritoBodies.circle()
: Cria um círculo físicoWorld.add()
: Adiciona o corpo ao mundo físico
Passo 5: Função draw()
A função draw() é chamada continuamente para atualizar e renderizar:
background("gray")
: Define o fundo da tela como cinza.Engine.update()
: Calcula todas as interações físicas a cada frame
function draw() {
background("gray");
// Atualiza a física
Engine.update(engine);
Agora vamos rotacionar a parede dois gradualmente:
// Rotaciona wall2 gradualmente
Matter.Body.rotate(wall2,angle);
push();
translate(wall2.position.x,wall2.position.y);
rotate(angle);
rect(0,0,100,20);
pop();
angle +=0.1;
Matter.Body.rotate(wall2,angle)
: Rotaciona o corpo físicopush()
: Salva o estado gráfico atualtranslate()
: Move a origem para a posição da parederotate(angle)
: Aplica rotação gráficarect(0,0,100,20)
: Desenha a parede rotacionadapop()
: Restaura o estado gráficoangle +=0.1
: Atualiza o ângulo para animação
Por fim, renderizamos os corpos para aparecem na tela:
// Desenha o chão
fill("green");
rect(ground.position.x,ground.position.y,400,20);
fill("red");
ellipse(ball.position.x,ball.position.y,20);
fill("blue");
rect(wall.position.x,wall.position.y,70,10);
}
fill:
preenchimento com cor do corpoposition.x/y
: Acessa a posição atual do corpo