matter.js

Matter.js: Aplicação de Força em um Corpo

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

Conceitos Fundamentais

  • Corpos Físicos: Objetos que interagem com física (estáticos ou dinâmicos).

  • Aplicação de Força:

    • Matter.Body.applyForce(body, position, force)

      • body: O corpo que receberá a força.

      • position: Ponto de aplicação (normalmente {x:0, y:0} para o centro).

      • force: Vetor de força ({x: valor, y: valor}).

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: Criando as paredes (arquivo parede.js)

Neste arquivo, criamos uma classe que representa os limites do mundo (chão, teto e paredes laterais):

				
					class Parede 
{
  constructor(x, y, w, h) 
  {
    let options = {
      isStatic: true
    };
    
    this.body = Bodies.rectangle(x, y, w, h, options);
    this.w = w;
    this.h = h;
    World.add(world, this.body);
  }

				
			
  • class Ground: define uma nova classe chamada Ground (chão ou parede).

  • constructor(x, y, w, h): função especial que será chamada sempre que criarmos uma nova parede. Recebe:

    • x e y: coordenadas onde o corpo será posicionado no canvas.

    • w e h: largura e altura do corpo.

  • let options = { isStatic: true }: define que o corpo será estático, ou seja, não será afetado pela gravidade nem por colisões com outros corpos.

  • Bodies.rectangle(x, y, w, h, options): cria um retângulo com base nas coordenadas e dimensões passadas.

  • this.body: armazena o corpo criado.

  • this.w e this.h: armazenam as dimensões, úteis para desenhar depois.

  • World.add(world, this.body): adiciona o corpo ao mundo físico, tornando-o parte da simulação.

				
					  show() {
    var pos = this.body.position;
    push();
    rectMode(CENTER);
    stroke(255);
    fill(127);
    rect(pos.x, pos.y, this.w, this.h);
    pop();
  }
}

				
			
  • show(): método responsável por desenhar o corpo na tela.

  • this.body.position: acessa a posição atual do corpo no mundo simulado.

  • push() e pop(): salvam e restauram o estado de estilo do desenho, garantindo que as configurações não interfiram em outros elementos.

  • rectMode(CENTER): faz com que os retângulos sejam desenhados a partir do centro, o que facilita o posicionamento.

  • stroke(255): define a cor da borda do retângulo como branco.

  • fill(127): define a cor interna como cinza.

  • rect(pos.x, pos.y, this.w, this.h): desenha o retângulo com a posição e tamanho definidos.

Passo 3: 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 ground;
var left;
var right;
var top_wall;
var ball;

var btn1;
var btn2;
				
			
  • Engine: O “cérebro” que calcula todas as interações físicas

  • World: O “container” onde todos os objetos físicos existem

  • Bodies: Ferramenta para criar novos objetos

  • Body: 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(400,400);
 
				
			

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ísica
  • engine.world: Acessa o mundo físico criado

Vamos criar os botões de controle:

				
					  btn1 = createImg('right.png');
  btn1.position(220, 30);
  btn1.size(50, 50);
  btn1.mouseClicked(hForce);

  btn2 = createImg('up.png');
  btn2.position(20, 30);
  btn2.size(50, 50);
  btn2.mouseClicked(vForce);

				
			
  • createImg('right.png'): Carrega uma imagem que será usada como botão (neste caso, uma seta apontando para a direita).

  • position(x, y): Define a posição do botão na tela.

  • size(w, h): Define o tamanho do botão em pixels.

  • mouseClicked(função): Associa uma função que será chamada quando o botão for clicado.

Agora criando as paredes e o chão:

				
					  ground = new Parede(200, 390, 400, 20);
  right = new Parede(390, 200, 20, 400);
  left = new Parede(10, 200, 20, 400);
  top_wall = new Parede(200, 10, 400, 20);

				
			
  • Ground(x, y, w, h): Cria uma parede ou piso com posição (x, y) e dimensões (w, h).

    • ground: chão inferior.

    • right: parede direita.

    • left: parede esquerda.

    • top_wall: teto da simulação.

E criamos a bola:

				
					  var ball_options = {
    restitution: 0.95
  };

  ball = Bodies.circle(200, 100, 20, ball_options);
  World.add(world, ball);

				
			
  • restitution: 0.95: Define um quique alto (95% da energia conservada)
  • Bodies.circle(): Cria um círculo físico
  • World.add(): Adiciona o corpo ao mundo físico

E por fim configuramos os modos de desenho:

				
					rectMode(CENTER);
ellipseMode(RADIUS);
}

				
			
  • rectMode(CENTER): Faz com que os retângulos sejam desenhados a partir do centro (importante para alinhar com os corpos do Matter.js).

  • ellipseMode(RADIUS): Faz com que os círculos sejam desenhados a partir do centro com base no raio, e não no diâmetro.

Passo 5: Renderizando o jogo (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:

				
					  ground.show();
  top_wall.show();
  left.show();
  right.show();

				
			
  • .show(): Função da classe Parede, usada para desenhar cada corpo do tipo retângulo na tela.

Por fim, renderizamos o corpo da bola para aparecem na tela:

				
					  ellipse(ball.position.x, ball.position.y, 20);
}
				
			
  • ellipse(x, y, raio): Desenha a bola na posição atual (x, y) fornecida pelo motor de física (ball.position).

Passo 6: Aplicando forças com botões

Neste passo, criamos dois botões com imagens que, ao serem clicados, aplicam uma força na bola — um para a direita e outro para cima. Isso simula o impulso de um objeto sendo empurrado ou lançado.

  • Matter.Body.applyForce(corpo, ponto, força): Aplica uma força sobre o corpo físico.
				
					function hForce() {
  Matter.Body.applyForce(ball, { x: 0, y: 0 }, { x: 0.05, y: 0 });
}

				
			
				
					function vForce() {
  Matter.Body.applyForce(ball, { x: 0, y: 0 }, { x: 0, y: -0.05 });
}

				
			

Posts Similares

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *