웹 브라우저에서 물리엔진을 구현하기 위한 JavaScript 라이브러리이다.
HTML5 canvas를 기반으로, 그린 요소에 중력, 다른 요소와의 충돌, 드래그 기능 등을 추가 할 수 있다.
Matter.Engine
으로 선언한다.Engine.create()
를 통해서 엔진을 생성하고,Engine.run(engine)
으로 실행할 수 있다.Matter.Render
으로 선언한다.Bodies.rectangle(x,y,width,height,options);
: 직사각형 바디를 생성한다(생성)Bodies.setPosition(body,{ x:200, y:300 });
: 위치를 옮긴다(조작)engine.world
에 자동으로 포함된다.World.add(world, body);
월드에 body 객체 추가world.gravity.x = 0
월드에 gravity x방향에 관한 속성 설정이제 Matter.js와 리액트로 간단하게 웹사이트에서 중력, 드래그, 충돌 기능을 구현해보자.
시작을 위한 라이브러리 설치
npm i matter-js
div를 선언하고 useRef로 div를 참조한다.
또한 사용하기 편하도록 Matter안의 모듈들을 다시 선언해주었다.
import React,{ useRef, useEffect } from 'react'
import Matter from 'matter-js'
function Canvas(){
const canvasRef = useRef();
useEffect(()=>{
//기초 설정
const Engine = Matter.Engine;
const World = Matter.World;
const Bodies = Matter.Bodies;
const Render = Matter.Render;
const engine = Engine.create(); //엔진 생성
const world = engine.world;
const runner = Matter.Runner.create(); //러너도 만들어줘야함.
})
return(
<div ref={canvasRef}>
//여기에 canvas 생성
</div>
);
}
export default Canvas;
//렌더 설정
const render = Render.create({
element: canvasRef.current,
engine: engine,
options: {
width:800,
height:600,
wireframes:false, //색까지 칠하기
}
});
runner를 create 해야 하는줄 모르고 겁나 헤맸다..
//엔진 구동 및 렌더 진행
Matter.Runner.run(runner,engine); //러너 추가해야함.
Render.run(render);
//위치와 모양이 랜덤인 바디 6개 생성
for(let i=0;i<=5;i++){
let x = Math.random()*400+300;
let y = Math.random()*150;
let shape = (Math.random() <= 0.5) ? (Bodies.rectangle(x,y,40,40)):(Bodies.circle(x,y,40,40));
World.add(world,shape);
}
return () => {
Render.stop(render);
World.clear(world, false);
Engine.clear(engine);
render.canvas.remove();
}; // 컴포넌트가 unmount 될 때 초기화
여기까지 했다면 아래와 같은 화면이 나올 것이다.
//마우스 드래그 기능
const mouse = Matter.Mouse.create(render.canvas) //마우스 객체 생성
const mouseConstraint =
//마우스로 화면에서 바디를 클릭, 드래그 할 수 있도록 함
Matter.MouseConstraint.create(engine,{
mouse: mouse,
constraint: {
stiffness: 0.2, // 탄성정도
render:{
visible: false //마우스 드래그 시 제약조건 보이기X
}
}
})
World.add(world,mouseConstraint)
전체코드
import React,{ useRef, useEffect } from 'react'
import Matter from 'matter-js'
function Canvas(){
const canvasRef = useRef();
useEffect(()=>{
//기초 설정
const Engine = Matter.Engine;
const World = Matter.World;
const Bodies = Matter.Bodies;
const Render = Matter.Render
const engine = Engine.create(); //엔진 생성
const world = engine.world;
engine.gravity.y = 1.5;
const runner = Matter.Runner.create();
//렌더 설정
const render = Render.create({
element: canvasRef.current,
engine: engine,
options: {
width:800,
height:600,
isStatic:false,
wireframes:false, //색까지 칠하기
background: "white"
}
});
// 바닥&벽 만들고 world에 추가
const ground = Bodies.rectangle(400,590,810,20,{isStatic:true});
const wallLeft = Bodies.rectangle(0,300,30,600,{isStatic:true});
const wallRight = Bodies.rectangle(800,300,30,600,{isStatic:true});
World.add(world,[ground,wallLeft,wallRight]);
//마우스 드래그 기능
const mouse = Matter.Mouse.create(render.canvas) //마우스 객체 생성
const mouseConstraint = Matter.MouseConstraint.create(engine,{ //마우스로 화면에서 바디를 클릭, 드래그 할 수 있도록 함
mouse: mouse,
constraint: {
stiffness: 0.2, // 탄성정도
render:{
visible: false //마우스 드래그 시 제약조건 보이기X
}
}
})
World.add(world,mouseConstraint)
//엔진 구동 및 렌더 진행
Matter.Runner.run(runner,engine);
Render.run(render);
// 위치와 모양이 랜덤인 바디 6개 생성
for(let i=0;i<=5;i++){
let x = Math.random()*400+300;
let y = Math.random()*150;
let shape = (Math.random() <= 0.5) ?
(Bodies.rectangle(x,y,40,40)):(Bodies.circle(x,y,40,40));
World.add(world,shape);
}
return () => {
Render.stop(render);
World.clear(world, false);
Engine.clear(engine);
render.canvas.remove();
}; // 컴포넌트가 unmount 될 때 초기화
},[]);
return(
<div ref={canvasRef}>
</div>
);
}
export default Canvas;
참고
Github-matter-js
velog-Matter.js로 브라우저에서 물리엔진 구현하기
tstory-Matter.js 맛보기
우와 모션이 되게 부드럽네요!!