Learning
레슨 3 / 8·20분

이벤트와 인터랙션

충돌 감지와 이벤트

Matter.js의 Events 시스템은 물리 시뮬레이션에서 발생하는 다양한 이벤트(충돌, 프레임 업데이트 등)를 감지합니다. Mouse와 MouseConstraint를 사용하면 마우스로 바디를 클릭하고 드래그할 수 있어 인터랙티브한 물리 시뮬레이션을 만들 수 있습니다.

javascript
const { Events, Mouse, MouseConstraint, Body } = Matter;

// ── 충돌 이벤트 감지 ──
Events.on(engine, 'collisionStart', (event) => {
  // 충돌이 시작된 모든 쌍을 순회
  event.pairs.forEach((pair) => {
    const { bodyA, bodyB } = pair;
    console.log("충돌 감지: " + bodyA.label + " ↔ " + bodyB.label);

    // 충돌 시 색상 변경 효과
    bodyA.render.fillStyle = '#ff0000';
    bodyB.render.fillStyle = '#ff0000';

    // 0.5초 후 원래 색으로 복원
    setTimeout(() => {
      bodyA.render.fillStyle = bodyA.originalColor || '#3498db';
      bodyB.render.fillStyle = bodyB.originalColor || '#e74c3c';
    }, 500);
  });
});

// 충돌 종료 이벤트
Events.on(engine, 'collisionEnd', (event) => {
  event.pairs.forEach((pair) => {
    console.log('충돌 종료');
  });
});

마우스 인터랙션

javascript
// ── 마우스로 바디 드래그하기 ──
const mouse = Mouse.create(render.canvas);
const mouseConstraint = MouseConstraint.create(engine, {
  mouse: mouse,
  constraint: {
    stiffness: 0.2,     // 드래그 강도
    render: {
      visible: true,
      strokeStyle: '#90cdf4',
      lineWidth: 2,
    },
  },
});

World.add(engine.world, mouseConstraint);

// 렌더러에 마우스 동기화
render.mouse = mouse;

// ── 마우스 이벤트 ──
Events.on(mouseConstraint, 'mousedown', (event) => {
  const { mouse } = event;
  console.log("클릭 위치: (" + mouse.position.x + ", " + mouse.position.y + ")");
});

Events.on(mouseConstraint, 'startdrag', (event) => {
  console.log('드래그 시작:', event.body.label);
});
javascript
// ── 힘과 속도 적용 ──
const ball = Bodies.circle(400, 300, 30, {
  label: 'ball',
  render: { fillStyle: '#3498db' },
});
World.add(engine.world, ball);

// applyForce — 특정 지점에서 힘 가하기
Body.applyForce(ball, ball.position, {
  x: 0.05,  // 오른쪽으로 힘
  y: -0.08, // 위쪽으로 힘
});

// setVelocity — 직접 속도 설정
Body.setVelocity(ball, { x: 5, y: -10 });

// setAngularVelocity — 회전 속도
Body.setAngularVelocity(ball, 0.1);

// ── 키보드로 제어하기 ──
document.addEventListener('keydown', (e) => {
  const force = 0.005;
  switch (e.key) {
    case 'ArrowLeft':
      Body.applyForce(ball, ball.position, { x: -force, y: 0 });
      break;
    case 'ArrowRight':
      Body.applyForce(ball, ball.position, { x: force, y: 0 });
      break;
    case 'ArrowUp':
      Body.applyForce(ball, ball.position, { x: 0, y: -force });
      break;
  }
});
  • Events.on(engine, "collisionStart") — 충돌 시작 감지
  • Mouse.create(canvas) — 캔버스에 마우스 입력 연결
  • MouseConstraint — 마우스로 바디를 드래그할 수 있게 함
  • Body.applyForce(body, position, force) — 특정 지점에 힘 적용
  • Body.setVelocity(body, {x, y}) — 속도를 직접 설정
  • Body.setAngularVelocity(body, speed) — 회전 속도 설정
💡

applyForce의 힘 값은 매우 작은 수(0.001~0.05)를 사용하세요. 값이 너무 크면 바디가 순간이동하듯 날아갑니다. setVelocity는 현재 속도를 덮어쓰므로 자연스러운 물리 효과를 원하면 applyForce가 더 적합합니다.