레슨 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가 더 적합합니다.