๐พ๋ค์ด๊ฐ๋ฉฐ
์์ฆ ํ์ฐธ ๊ณต๋ถ์ค์ธ Matter.js์ ๋ํด ์ ๋ฆฌํด๋ณด๋ ค๊ณ ํฉ๋๋ค. ์์ง ์ ๋๋ก ์ฌ์ฉํ์ง ๋ชป ํ์ง๋ง, GPT๋ ๋๋ฉด์ ๋ฐฐ์ฐ๊ณ ์์ด์ ์ผ๊ฐํจ์๋ง ๋จธ๋ฆฌ๋ฅผ ์ธ๋งค๋ฉด ๋๊ธฐ์... ๊ธฐ๋ณธ์ ์ธ ๋ด์ฉ๋ถํฐ ์ ๋ฆฌ๋ฅผ ์์ํฉ๋๋คใ
ใ
์ ๋ฆฌํ๋ค๋ณด๋ ์์ฌ์ด ์๊ฒจ์ ์ง๊ธ ๋ง๋ค๊ณ ์๋ ์ธํ๋ฝ๊ธฐ ์ง๊ฒ๊น์ง ๊ฐ์ด ์ฒจ๋ถํฉ๋๋ค!
Matter.js ๊ณต์ ๋ฌธ์ ๋ฐ๋ก๊ฐ๊ธฐ > https://brm.io/matter-js/?utm_source=cdnjs&utm_medium=cdnjs_link&utm_campaign=cdnjs_library
โจ๋ณธ๊ฒฉ์ ์ผ๋ก
โ CDN์ผ๋ก ์์ํด๋ณด์
CDN.js๋ผ๋ ์ฌ์ดํธ์์ Matter.js์ ๋ํ CDN์ ์ ์ ๊ณตํด์ฃผ์ด ํด๋น CDN์ ์ฌ์ฉํ์์ต๋๋ค.
<script
src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.19.0/matter.js"
integrity="sha512-rsntMCBgWYEWKl4HtqWmQ3vdHgvSq8CTtJd19YL7lCtKokLPWt7UEoHVabK1uiNfUdaLit8O090no5BZjcz+bw=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
โ ๊ณต์๋ฌธ์์ ์ํ๊ฐ...
React์ ์ฃผ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ ๊ณต์๋ฌธ์๋ง ๋ณด๋ค๊ฐ Matter.js์ ๊ณต์๋ฌธ์๋ฅผ ๋ณด๋ ์์์ฝ๋๊ฐ ์๊ณ ์ต์ ์ ๋ํ ์ค๋ช ๋ ๋ถ์น์ ํ๊ณ ... ๋ญ๋ง ํ๋ฉด ๊นํ๋ธ๋ก ์ฐ๊ฒฐํด์ ์ง์ ์ฐพ์์ผ๋๋ ๋ถํธํจ์ด ์์์ต๋๋ค. ๊ทธ๋์ ์ด๋ฒ์ ChatGPT(์งํผํฐ)๋ฅผ ์ข ๋ ํ์ฉํด๋ณด๊ธฐ๋ก ํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ๊ธ์ ์ฐ๋ค๊ฐ ๋ฐ๊ฒฌํ ์ปค๋ฎค๋ํฐ! - Matter.js์ ๊นํ๋ธ ์ํค๋ฅผ ๋ณด์๋ฉด ๋ ๋ง์ ์ปค๋ฎค๋ํฐ ๋งํฌ๊ฐ ์์ต๋๋ค!
webflow: https://webflow.com/made-in-webflow/matterjs
์ปค๋ฎค๋ํฐ์์ ๋น์ทํ ์์๋ฅผ ์ฐพ์ ์๋ํด๋ณด๋ ๊ฒ๋ ์ข์ ๋ฏ ํฉ๋๋ค! ์ ์ฌ์ค ์ฝ๋ํ์์ ์์ ์ฐพ์ ๊ฒ ๋์์ด ํฝ๋๋ค.
โ ์์ํ๊ธฐ
Matter.js๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ ์ฌ๋ฌ ๋ชจ๋๋ค์ ๋ถ๋ฌ์์ผ ํฉ๋๋ค. ์ ๋ง ๋ง์ ๋ชจ๋์ ๋ถ๋ฌ์์ผ ํด์ ๊ทธ๋ฐ์ง, ํ์ผ์ ๋ถ๋ฆฌํด์ ์ฌ์ฉํ์ ๋ ์ข ํท๊ฐ๋ ธ์ต๋๋ค.
// module aliases
export const Engine = Matter.Engine,
Render = Matter.Render,
Bodies = Matter.Bodies,
Body = Matter.Body,
Mouse = Matter.Mouse,
Events = Matter.Events,
Composite = Matter.Composite,
Runner = Matter.Runner,
Constraint = Matter.Constraint,
MouseConstraint = Matter.MouseConstraint;
๋ถ๋ฌ์จ ๋ชจ๋์ ์ฌ์ฉํ๊ธฐ ์ํด์๋ ๊ฐ์ฅ ๋จผ์ create()
์ ์ต์
๋ค์ ๋ฃ์ด์(ํน์ ๋น์๋๊ณ ) ๋ณ์๋ฅผ ์ ์ธํด์ค๋๋ค. new ์ฐ์ฐ์๋ฅผ ๋์ ํ๋ ๋ฏ ํฉ๋๋ค.
์ต์
๋ค์ ๋ํ ์ค๋ช
์ ๊ณต์๋ฌธ์๋ณด๋ค๋ ๊นํ๋ธ ์ฝ๋์์ ๋ณด๋ ๊ฒ์ ์ถ์ฒํฉ๋๋ค. ๋ค์์ Body ๋ชจ๋์ create ์ต์
์ ๋ณผ ์ ์๋ ๋งํฌ์
๋๋ค.
https://github.com/liabru/matter-js/blob/0b131a499c7479cab246d5d31c2a547dbc8b79eb/src/body/Body.js#L39
ํ์ผ ๊ฒฝ๋ก๋ src/*
์ด๋ฉฐ, ํ์ผ๋ช
์ด ๋ชจ๋์ด๋ฆ๊ณผ ๊ฐ์ ๊ธ๋ฐฉ ์ฐพ์ ์ ์์ต๋๋ค.
์ด์ ๋ํ ๊ธฐ๋ณธ์ ์ธ ์ฝ๋์ ๋๋ค.
//html์ ํน์ ์์๊ฐ ๋ ์๋ ์์ง๋ง, canvas๊ฐ ๋ฌด๋.
const canvas = document.querySelector("canvas");
// create an engine
export const engine = Engine.create();
export const canvasHeight = 500, canvasWidth = 500;
// create a renderer
//render์ ์ต์
์ผ๋ก canvas๋ฅผ ๋ฃ๊ฑฐ๋, html์์๋ผ๋ฉด elem ์ต์
์ ๋ฃ์.
export const render = Render.create({
canvas: canvas,
engine: engine,
options: {
width: canvasWidth,
height: canvasHeight,
wireframes: false, //์ฌ๋ฌ ์์ ์น ํ ์์๋ค์ด ๋์จ๋ค.
},
});
export const runner = Runner.create();
Render.run(render);
Runner.run(runner, engine);
// Add mouse control
const mouse = Mouse.create(render.canvas);
const mouseConstraint = MouseConstraint.create(engine, {
mouse: mouse,
constraint: {
stiffness: 0.2,
render: {
visible: false,
},
},
});
Composite.add(engine.world, mouseConstraint);
//code..
//render์ ๋ง์ฐ์ค์ ์ค์ ๋ง์ฐ์ค๋ฅผ ์ฐ๋
//์์์์ ์ฝ๋์ ๊ฐ์ฅ ๋ง์ง๋ง์ ๋ฃ๋๋ค.
render.mouse = mouse;
โ ๊ฐ ๋ชจ๋์ ๋ํด ์์๋ณด์
๋จ์ํ ์์๋ฅผ ๋ง๋๋ ๊ฒ ์๋ Matter.js์ ๋ํด ์์๋ณด๊ธฐ๋ก ํ์ผ๋ ๊ฐ ๋ชจ๋๋ค์ด ์ด๋ค ์ญํ ์ ํ๋์ง ์์๋ณด๋ ค๊ณ ํฉ๋๋ค.
์ฃผ์ ๋ชจ๋์ ์งํ๊ฒ ํ์ํ ๊ธ์จ๋ค์
๋๋ค.
๋ชจ๋ | ์ค๋ช - ๊ณต์๋ฌธ์ ์ฐธ๊ณ / ๋ฒ์ญ: ์งํผํฐ |
---|---|
Engine | ์ธ๊ณ ์๋ฎฌ๋ ์ด์
์
๋ฐ์ดํธ๋ฅผ ๊ด๋ฆฌํ๋ ์ปจํธ๋กค๋ฌ. ์์ง ์์ฑ ๋ฐ ์กฐ์์ ์ํ ๋ฉ์๋๋ค์ ํฌํจ. ์ฐธ๊ณ :Runner |
Render | Engine์ ์ธ์คํด์ค๋ฅผ ์๊ฐํํ๊ธฐ ์ํ ๊ฐ๋จํ ์บ๋ฒ์ค ๊ธฐ๋ฐ ๋ ๋๋ฌ. ๊ฐ๋ฐ ๋ฐ ๋๋ฒ๊น ๋ชฉ์ ์ผ๋ก ์ฌ์ฉ๋์ง๋ง ๊ฐ๋จํ ๊ฒ์์๋ ์ ํฉ. ์์ด์ดํ๋ ์, ์คํ๋ผ์ดํธ ๋ฐ ๋ทฐํฌํธ ์ง์์ ํฌํจํ ๋ค์ํ ๊ทธ๋ฆฌ๊ธฐ ์ต์ ์ด ํฌํจ. |
Runner | ๋ธ๋ผ์ฐ์ ๋ด์์ Engine์ ์ง์์ ์ผ๋ก ์
๋ฐ์ดํธํ๋ ๊ฒ์ ๋ฃจํ๋ฅผ ์ ๊ณตํ๋ ์ ํ์ ์ ํธ๋ฆฌํฐ. ๊ฐ๋ฐ ๋ฐ ๋๋ฒ๊น ๋ชฉ์ ์ผ๋ก ๊ณ ์๋์์ง๋ง ๊ฐ๋จํ ๊ฒ์์๋ ์ ํฉ. ์์ฒด ๊ฒ์ ๋ฃจํ๋ฅผ ์ฌ์ฉ ์ค์ด๋ผ๋ฉด Runner ๋์ ์ Engine.update(engine, delta)๋ฅผ ์์ฒด ๋ฃจํ์์ ํธ์ถ. |
Bodies | ์ง์ฌ๊ฐํ, ์ ๋ฐ ๋ค๋ฅธ ๋ค๊ฐํ๊ณผ ๊ฐ์ ์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉ๋๋ ๋ฐ๋ ๊ตฌ์ฑ์ ๊ฐ๋ ๊ฐ์ฒด ๋ฐ๋ ๋ชจ๋ธ์ ๋ง๋๋ ํฉํ ๋ฆฌ ๋ฉ์๋ |
Body | ๊ฐ์ฒด ๋ฐ๋๋ฅผ ๋ง๋ค๊ณ ์กฐ์ํ๋ ๋ฉ์๋๊ฐ ํฌํจ |
Composite | Body, Constraint ๋ฐ ๋ค๋ฅธ Composite ๊ฐ์ฒด์ ๋ชจ์. ๋ฌผ๋ฆฌ์ ์ผ๋ก ์ฐ๊ฒฐ๋์ด ์์ง ์๋๋ผ๋ ์ฌ๋ฌ ๋ถ๋ถ์ผ๋ก ๊ตฌ์ฑ๋ ๋ณตํฉ ๊ฐ์ฒด๋ฅผ ๋ํ๋ผ ์ ์๋ ์ปจํ ์ด๋. ์ปดํฌ์งํธ์๋ ํ๋์ ๋ณธ์ฒด์์๋ถํฐ ์ ์ธ๊ณ๊น์ง ๋ชจ๋ ๊ฒ์ด ํฌํจ. ์ปดํฌ์งํธ๋ฅผ ์์ ํ ๋๋ ์์ฑ์ ์ง์ ์์ ํ๋ ๋์ ํฌํจ๋ ํจ์๋ฅผ ์ฌ์ฉ |
Composites | ์คํ ๋ฐ ์ฒด์ธ๊ณผ ๊ฐ์ ์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉ๋๋ ๊ตฌ์ฑ์ผ๋ก ๋ณตํฉ ๋ฐ๋๋ฅผ ๋ง๋๋ ํฉํ ๋ฆฌ ๋ฉ์๋ |
Constraint | ์ ์ฝ ์กฐ๊ฑด์ ์์ฑํ๊ณ ์กฐ์ํ๋ ๋ฐ ์ฌ์ฉ๋๋ ๋ฉ์๋๊ฐ ํฌํจ. ๋ ๊ฐ์ฒด(๋๋ ๊ฐ์ฒด์ ๊ณ ์ ๋ ์๋ ๊ณต๊ฐ ์์น) ์ฌ์ด์ ๊ณ ์ ๋ ๊ฑฐ๋ฆฌ๋ฅผ ์ ์งํด์ผ ํจ์ ์ง์ ํ๋ ๋ฐ ์ฌ์ฉ. ๊ฐ์ฑ์ ์คํ๋ง์ด๋ ํ์ฑ์ ๋ง๋ค๊ธฐ ์ํด ์์ ๊ฐ๋ฅ. |
Mouse | ๋ง์ฐ์ค ์ ๋ ฅ์ ์์ฑํ๊ณ ์กฐ์ํ๋ ๋ฉ์๋๊ฐ ํฌํจ |
MouseConstraint | ์ฌ์ฉ์ ์ํธ ์์ฉ์ ํ์ฉํ๊ณ ๋ง์ฐ์ค ๋๋ ํฐ์น๋ฅผ ํตํด ์ ์ฒด๋ฅผ ์ด๋์ํค๋ ๊ธฐ๋ฅ์ ์ ๊ณต |
Events | ๋ค๋ฅธ ๊ฐ์ฒด์์ ์ด๋ฒคํธ๋ฅผ ๋ฐ์ ๋ฐ ๋ฆฌ์ค๋ |
Common | ๋ชจ๋ ๋ชจ๋์ ๊ณตํต์ ์ผ๋ก ์ฌ์ฉ๋๋ ์ ํธ๋ฆฌํฐ ํจ์๊ฐ ํฌํจ |
Plugin | ๋ชจ๋์ ํ๋ฌ๊ทธ์ธ์ ๋ฑ๋กํ๊ณ ์ค์นํ๋ ๊ธฐ๋ฅ์ด ํฌํจ |
Bounds | ์ถ์ธ ์ถ์ ๋ง์ถ ๋ฐ์ด๋ฉ ๋ฐ์ค(AABB)๋ฅผ ์์ฑํ๊ณ ์กฐ์ํ๋ ๋ฉ์๋๋ฅผ ํฌํจ |
Collision | ์ฃผ์ด์ง ๋ ๋ฐ๋ ์ ์ฌ์ด์ ์ถฉ๋์ ๊ฐ์งํ๋ ๋ฉ์๋๋ฅผ ํฌํจ. ์ฐธ๊ณ : Detecto, Query |
Contact | ์ถฉ๋ ์ ์ด์ ๋ง๋ค๊ณ ์กฐ์ํ๋ ๋ฉ์๋๋ฅผ ํฌํจ |
Detector | ๋์ ๋ฒ์ ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ์ฌ ๋ชธ์ฒด ๋ชฉ๋ก ๊ฐ์ ์ถฉ๋์ ํจ์จ์ ์ผ๋ก ๊ฐ์งํ๋ ๋ฉ์๋๋ฅผ ํฌํจ |
Matter | ์ต์์ ๋ค์์คํ์ด์ค. ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์์ ํ๋ฌ๊ทธ์ธ์ ์ค์นํ๋ ํจ์๋ ํฌํจ |
Pair | ์ถฉ๋ ์์ ๋ง๋ค๊ณ ์กฐ์ํ๋ ๋ฉ์๋๊ฐ ํฌํจ |
Pairs | ์ถฉ๋ ํ์ด ์ธํธ๋ฅผ ์์ฑํ๊ณ ์กฐ์ํ๋ ๋ฉ์๋๊ฐ ํฌํจ |
Query | ์ถฉ๋ ์ฟผ๋ฆฌ๋ฅผ ์ํํ๋ ๋ฐฉ๋ฒ |
Resolver | ์ถฉ๋ ์์ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ด ํฌํจ |
Sleeping | ๊ฐ์ฒด์ ํด๋ฉด ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ๋ฉ์๋๊ฐ ํฌํจ |
Svg | SVG ์ด๋ฏธ์ง๋ฅผ ๋ฒกํฐ ํฌ์ธํธ ๋ฐฐ์ด๋ก ๋ณํํ๋ ๋ฉ์๋๊ฐ ํฌํจ. SVGPathSeg ํด๋ฆฌํ๋ ํ์ |
Vector | ๋ฒกํฐ๋ฅผ ์์ฑํ๊ณ ์กฐ์ํ๋ ๋ฐฉ๋ฒ์ด ํฌํจ. ๋ฒกํฐ๋ ์์ง์ ๋ชจ๋ ํ์ ๊ด๋ จ ์์ ์ ๊ธฐ์ด๋ก ๊ฐ์ฒด Matter.Vector์ ํ์์ { x: 0, y: 0 }. |
Vertices | Matter.Vector์์ ์ฝ์
ํ ์ถ๊ฐ ์ธ๋ฑ์ฑ ์์ฑ์ด ์๋ ๋ฐฐ์ด. ์ ์ ์ธํธ๋ฅผ ์์ฑํ๊ณ ์กฐ์ํ๊ธฐ ์ํ ๋ฉ์๋๊ฐ ํฌํจ. |
์ ๊ฐ ์ดํดํ ๋ฐ๋ก ,
Engine์ด ๊ธฐ๋ณธ ๋ฒ ์ด์ค๋ก Render์ Runner๊ฐ ๋์์ฃผ๋ ์ญํ ์ ํ๋ฉฐ, Engine์ Composite๋ฅผ ์์ฑํ๊ณ , Composite๋ Bodies๋ก ์์ฑํ ๋ชจ๋ธ๋ค, Constraint ๋ฑ์ด ๋ค์ด์์ผ๋ฉฐ, Events๋ก ์ด๋ฒคํธ๋ฅผ ๋ฐ์ํ๊ณ , Mouse์ MouseConstraint๋ก ๋ง์ฐ์ค ์ ๋ ฅ์ ์กฐ์ ํ๋ค
์ ๋๋ค.
์์ง ์ฝ๋๋ง ๋ณด๊ณ ๋ ์ ํํ ์ด๋ค ์๋ฆฌ๋ก ๋์ํ๋์ง ์ ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์ ๋๋ต ์ ๋ ๊ฒ์ด ์์ฝ์ต๋๋ค...
โ ์ง์ ๋ง๋ค์ด๋ณผ๊น?
๊ฐ๋จํ๊ฒ Constraint๋ฅผ ์ฌ์ฉํด ์ฐ๊ฒฐํ์ฌ ์ธํ๋ฝ๊ธฐ ์ง๊ฒ๋ฅผ ๋ง๋ค์ด๋ณด์์ต๋๋ค.
์ฌ์ค ์ด๊ฑธ ๋ง๋ ๋ค๊ณ ์งํผํฐ์ 3์๊ฐ์ฉ 5์ผ ๋์ ๊ณ ์์ ํ์ง๋ง,,, ๊ฒฐ๊ตญ ์๊ณ ํ๋ฃจ๋ง์ ๋ค์ ๋ง๋ค์๋ ์ถ์ต์ดใ
ใ
์ฐ์ ๊ธฐ๋ณธ์ ์ผ๋ก HTML์ CDN์ ์ฌ์ฉํ์ต๋๋ค. canvas๋ ์์ง ์๊ณ ์ ์ด์ค์๋ค.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script
src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.19.0/matter.js"
integrity="sha512-rsntMCBgWYEWKl4HtqWmQ3vdHgvSq8CTtJd19YL7lCtKokLPWt7UEoHVabK1uiNfUdaLit8O090no5BZjcz+bw=="
crossorigin="anonymous"
referrerpolicy="no-referrer"
></script>
<title>matterJs</title>
</head>
<body>
<canvas></canvas>
<script type="module" src="./index.js"></script>
</body>
</html>
index.js ํ์ผ์์ ์์์ ์ธ๊ธํ ๊ธฐ๋ณธ ์ฝ๋๋ฅผ ๋จผ์ ์ธํ ํด์ค๋๋ค.
- ์ฌ๊ฐํ(๋ชจ๋ธ) ๋ง๋ค๊ธฐ
๊ธฐ๋ณธ์ ์ผ๋ก ์ฌ๊ฐํ์ ์ถ๊ฐํ๋ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
const rectangle = Bodies.rectangle(x, y, width, length, {
...option,
});
์ฌ๋ด) option์๋ ์ฌ๋ฌ๊ฐ์ง๊ฐ ๋ค์ด๊ฐ ์ ์๊ณ ์์์ ๋ง์๋๋ ธ๋ฏ github์์ ์ฐพ์๋ณด๋ ๊ฒ ์ข์ต๋๋ค.
์ด๋ ๊ฒ ์ฌ๊ฐํ์ ๊ทธ๋ฅ ๋ง๋ค๋ฉด ์์๊ฐ์ ํ๋ฉด์ ๊ฐ์ฅ ์๋๋ก ์ฌ๋ผ์ ธ ๋ฒ๋ฆฝ๋๋ค. ์ค๋ ฅ์ด ์์ฉํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ๊ทธ๋ฌ๋ฏ๋ก ์ค๋ ฅ์ด ์์ฉํด๋ canvas ์ธ๋ถ๋ก ๋๊ฐ์ง ์๊ฒ ์ฌ๋ฐฉ์ ๋ฒฝ์ ์ธ์์ค ๊ฒ๋๋ค.
const groundHeight = 20;
const ground = Bodies.rectangle(
canvasWidth / 2,
canvasHeight - groundHeight / 2,
canvasWidth,
groundHeight,
{
isStatic: true,
}
);
์ต์ ์ผ๋ก isStatic: true๋ฅผ ์ฃผ์๋๋ฐ, ์ค๋ ฅ์ ๋ฌด์ํ๋ ๊ฒ์ ๋๋ค.
๋ ๋ค๋ฅธ ํน์ดํ ์ ์ด ๋์ ๋๋๋ค. x์ y ์ขํ๊ฐ ๊ฐ๊ฐ canvasWidth / 2, canvasHeight - groundHeight / 2๋ก ๋์ด์์ต๋๋ค. canvas์๋ ๋ค๋ฅด๊ฒ ์ฌ๊ฐํ์ ๋ง๋ค ๋ ์ค์ฌ์ขํ๋ฅผ ์ฃผ๊ธฐ ๋๋ฌธ์ ๋๋ค.
์ผ์ชฝ ์๋จ์ (0,0)์ผ๋ก ๋ดค์ ๋, ์ค๋ฅธ์ชฝ์ผ๋ก ๊ฐ์๋ก x ์ขํ๊ฐ ์๋๋ก ๊ฐ์๋ก y์ขํ๊ฐ ์ฆ๊ฐํฉ๋๋ค. ์ฆ, (0,0)์ ๋ฐ๋ ์ขํ๋ (canvasWidth, canvasHeight)์ ๋๋ค.
canvas๋ ์ฒ์ ์์์ ๊ณผ ๋์ ์ ์ก๊ณ ๊ทธ๋ฆฌ๊ธฐ ๋๋ฌธ์ ์ด๊ธฐ์๋ ํท๊ฐ๋ฆฌ์ง๋ง ๊ธ๋ฐฉ ์ต์ํด์ง๋๋ค.
์์ ์ฝ๋๋ฅผ ์ด์ฉํด ์ฌ๋ฐฉ์ ๋ง์์ค๋๋ค. ๋ฒฝ์ด ํ์ด๋์์ ๋ณด๋ ๊ฒ ์ซ๋ค๋ฉด ์บ๋ฒ์ค์์ ๋ณด์ด์ง ์๊ฒ ์ขํ์ ์ฌ๊ฐํ์ ๊ธธ์ด / 2๋ฅผ ํ ๊ฐ์ ์ ์ ํ ๋ํด์ค๋๋ค.
๋ํ ๋ฒฝ์ ๋ง๋ค๊ธฐ ์ ์ ํ๋ฉด ๋ฐ์ผ๋ก ๋๊ฐ๋ ์ฌ๊ฐํ์ ๊ณ์ ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ ์ด์๊ฐ ์๊ธธ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋ ํ๋ฉด ์ธ๋ถ๋ก ๋๊ฐ ๋ชจ๋ธ๋ค์ ๋ค ์ญ์ ํด์ค๋๋ค.
- ๋ชจ๋ธ ์ถ๊ฐ ๋ฐ ์ญ์ ํ๊ธฐ
Composite.add(engine.world, [ground, leftWall, rightWall]); //์ถ๊ฐ
Composite.clear(engine.world, rectangle); //์ฐ๊ด๋ ๊ฐ์ฒด ๋ชจ๋ ์ญ์
Composite.remove(engine.world, rectangle);//rectangle ์ญ์
๊ทธ๋ ๋ค๋ฉด ๋ชจ๋ธ๋ค์ด ์ด๋ป๊ฒ ๋ฐ์ผ๋ก ๋๊ฐ๋์ง ์ ์ ์์๊น์?
๋ฐ๋ก, ํด๋น ๊ฐ์ฒด์ ์ ๋ณด๋ฅผ ์ฝ์์ ์ฐ์ด๋ด ์๋ค.
๊ฐ์ฒด์๋ ์ต์ ๋ค์ ๋ฃ์ด์คฌ๋ ์ ๋ณด๋ค๋ ์์ต๋๋ค. ๋์ค์ ์ด๋ค ์ต์ ์ด ๊ถ๊ธํ ์ง ๋น ๋ฅด๊ฒ ํ์ธํ ๋ ์ด๋ ๊ฒ ์ฝ์์ ์ฐ์ด๋ ๊ด์ฐฎ์ ๋ฏ ํฉ๋๋คใ ใ
์ ๊ธฐ์์ position์ ๊ฐ์ด canvas ๋ฒ์ ๋ฐ์ ์๋์ง ํ์ธํ๋ฉด ๋ฉ๋๋ค. ์ด ๋ถ๋ถ์ ์กฐ๊ฑด๋ฌธ์ผ๋ก ์ฒ๋ฆฌํด์ ์ฌ์ฐ๋, ํ๋ฉด์ด ์ ๋ฐ์ดํธํ ๋๋ง๋ค ์ฝ๋๋ฅผ ์คํํ์ง ์์ต๋๋ค. ์ฒ์ ํ ๋ฒ๋ง ์คํํ ๋ฟ์ด์ฃ .
๊ทธ๋ ๋ค๋ฉด! ์ฌ๊ธฐ์์ ๋ฑ์ฅํ๋ ๊ฒ์ด ๋ฐ๋ก ์ด๋ฒคํธ์ ๋๋ค.
- ์ด๋ฒคํธ ๋ชจ๋ ์ฌ์ฉํ๊ธฐ
Events.on(mouseConstraint, "mousedown", () => {
//code ...
});
์ด๊ธฐ์ mouseConstraint๋ฅผ ์ ์ธํ ๊ฒ์ ์ด๋ฒคํธ์ ์ฒซ๋ฒ์งธ ์ธ์๋ก, ๋๋ฒ์งธ ์ธ์๋ ์ด๋ฒคํธ์ ์ด๋ฆ์, ์ธ๋ฒ์งธ๋ ์คํํ ์ฝ๋ฐฑํจ์๋ฅผ ๋ฃ์ด์ค๋๋ค. ์ฒซ๋ฒ์งธ ์ธ์๋ง ์ถ๊ฐ๋ ๊ฒ์ ๋นผ๋ฉด ๊ธฐ๋ณธ ์ด๋ฒคํธ์ ์๊น์๊ฐ ๋น์ทํด์ ์ฝ์ต๋๋ค. ๊ทธ๋ฌ๋ mouse ์ด๋ฒคํธ๊ฐ ์ข ์ ์ ๋ฟ์ ๋๋ค. mouseup, mousedown, mousemove ์ ๋..? ๊ทธ๋์ mouseover๋ mouseleave ๋ฑ์ canvas ์์ฒด์ addEventListener๋ฅผ ์ด์ฉํด ๊ฑธ์ด์ฃผ๊ธฐ๋ ํฉ๋๋ค.
๋ง์ฐ์ค ์ด๋ฒคํธ ๋ฟ ์๋๋ผ, runner๋ ์ด๋ฒคํธ์ ์ฒซ๋ฒ์งธ ์ธ์๋ก ๋ฃ์ ์ ์์ต๋๋ค. runner์ ์ด๋ฒคํธ๋ค์๋ ํ๋ฉด ๋ ๋๋ง์ ์๋ช ์ฃผ๊ธฐ๊ฐ์ ์น๊ตฌ์ ๋๋ค.
- on afterTick
- on afterUpdate
- on beforeTick
- on beforeUpdate
- on tick
์ด๋ ๊ฒ 5๊ฐ์ง์ ์ด๋ฒคํธ๊ฐ ์์ผ๋ฉฐ, ์ด๋ฒคํธ์ ์ธ์๋ก ์ ๋ฌํ ๋๋ ์์ on์ ๋นผ์ผ ํฉ๋๋ค! ์ด ์ด๋ฒคํธ๋ค์ requestAnimationFrame์ผ๋ก ์๋ํฉ๋๋ค. << ์ฝ๋: https://github.com/liabru/matter-js/blob/master/src/core/Runner.js
๊ทธ๋ฌ๋ runner ์ด๋ฒคํธ ์ค tick(์ฌ์ค ์๋ฌด๊ฑฐ๋ ์๊ด์์ ๋ฏ)์ ์ด์ฉํด์ ์ธ๋ถ๋ก ๋๊ฐ ์ฌ๊ฐํ๋ค์ ๋ชจ์กฐ๋ฆฌ ์ญ์ ํด์ค์๋ค.
Events.on(runner, "tick", () => {
engine.world.bodies.forEach((body) => {
const isOutside = body.position.y > canvasHeight;
if (isOutside) Composite.remove(engine.world, body);
});
});
์ ์์ง ๊ฐ๊ธธ์ด ๋ฉ๋๋ค! ์ด์ ์ฌ๊ฐํ๋ ๋ง๋ค์๊ณ ์ฑ๋ฅ ๋๋น๋ ํ์ผ๋ ์ง์ง์ง์ง์ง์ง ์ง๊ฒ๋ฅผ ๋ง๋ค ์ฐจ๋ก์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ์ ์ ํ๋ ๋..ใ ใ Constraint๋ฅผ ์์๋ด ์๋ค.
(์ฌ๊ธฐ๊น์ง ์ธ๊ฐ์ ํตํด ๋ฐฐ์ ๋ ๋ด์ฉ์ ๋๋ค. ์ดํ๋ถํฐ๋ ๋ ํ ์ค! - ํน์ ๋์ ๊ฑฐ์ฌ๋ฆฌ๋ ๋ถ๋ถ ์๋ค๋ฉด ๋๊ธ๋ก ์๋ ค์ฃผ์ธ์~!)
- Constraint ์์๋ณด๊ธฐ
Constraint๋ ๋ชจ๋ธ๋ค์ ์ฐ๊ฒฐํด์ค๋๋ค. ๋ณ๋๋ก ์ ์ธํ์ง ์์ผ๋ฉด ๋ชจ๋ธ๋ค์ ์ค์ ์ ๊ธฐ์ค์ผ๋ก ์ฐ๊ฒฐํด์ค๋๋ค. ์ค๋ ฅ๊ณผ ๊ณต๊ธฐ์ ํญ, ๋ง์ฐฐ๋ ฅ์ ์ํฅ์ ๋ฐ์ง๋ง ์ผ๋จ ๋์ฌ์ฒ๋ผ ๊ณ ์ ๋ฉ๋๋ค.
const constraint = Constraint.create({
bodyA: rectA,
//rectA์ ๋ก์ปฌ์ขํ๋ก rectA์๊ฒ ๋งค๋ฌ๋ฆด ์ขํ
//์ฆ, rectB๊ฐ ๋งค๋ฌ๋ฆฌ๊ฒ ํ ์ขํ
pointA: {x : 0, y: 0},
bodyB: rectB
//rectB์ ๋ก์ปฌ์ขํ๋ก rectB๊ฐ ๋งค๋ฌ๋ฆฐ ์ขํ
pointB: { x: 0, y: 0 },
length: 0,
});
์ด๋ ๊ฒ ์ต์ ์ ๋ค ์ฑ์์ ์จ๋ ๋๋ฉฐ, ๋ช๊ฐ์ง๋ ๋น ์ ธ๋ ๋ฉ๋๋ค. << ์ด ๋ถ๋ถ์ ์์ง ์ฐ๊ตฌ์ค
์ฌ๊ธฐ์์๋ ์ขํ(์ฌ์ค ๋ฒกํฐ๋ผ๋ ๋ง์ด ๋ง๋ค - ๊ณต์๋ฌธ์)๊ฐ ๋์ค๋๋ฐ, ์ฃผ์์์๋ ์จ๋จ์ง๋ง ๋ก์ปฌ ์ขํ๋ฅผ ๊ธฐ์ค์ผ๋ก ํฉ๋๋ค. ์ด ๋ก์ปฌ ์ขํ๋ ๋ชจ๋ธ์ ๋ง๋ค ๋ ์ด ์ค์ ์ (0,0)์ผ๋ก ๋ด์ ์กฐ๊ธ์ด๋ผ๋ ๋ณต์กํ ๋ํ๋ผ๋ฆฌ ์ฐ๊ฒฐํ ๋ ๋งค์ฐ ์ด๋ ต์ต๋๋ค. ํนํ ํ์ ํ๋ ๊ฒ ๋ค์ด๊ฐ๋ฉด sin, cos... ์ผ๊ฐํจ์๋ฅผ ๊ธฐ๋ณธ์ผ๋ก ๊น์์ผ ํฉ๋๋ค. (์๊ณ ์ถ์ง ์์์ต๋๋ค)
โ ์ธํ๋ฝ๊ธฐ ์ง๊ฒ ๋ง๋ค๊ธฐ!
์ด์ ์ง์ง์ง์ง์ง์ง์ง์ง ์์ํ ๊ฑด๋ฐ์, ์ค๊ฐ์ ํ์ํ ๊ฐ๋ ๋ค์ ๋จผ์ ์ค๋ช ํ๊ณ ๊ฐ๋๋ค. (..์์ง๋..?)
์์ gif์์๋ ๋์ค์ง๋ง, Constraint๋ฅผ ๊ธฐ์ค์ผ๋ก ํ์ ํฉ๋๋ค. ์ฌ๊ฐํ์ ๊ฐ๋๋ง ๋ฐ๊พธ๊ฒ ๋๋ค๋ฉด, ์ค์ ์ ๊ธฐ์ค์ผ๋ก๋ง ๋ ๋ฟ, Constraint๋ฅผ ๊ธฐ์ค์ผ๋ก ๋์ง ์์ต๋๋ค.
๊ทธ๋์ ํ์ํ ๊ณ์ฐ์ ๋ฐ๋ก ์ ์์ ์ ์ ์ขํ์ ๋๋ค. ์ค์ ์ด (x, y), ๋ฐ์ง๋ฆ์ด r, ํ์ ๊ฐ์ด theta๋ผ๊ณ ํ ๋ ์ ์์ ์ ์ ์ขํ๋ ( x + r * cos(theta), y + r * sin(theta) ) ์ ๋๋ค. ์ค์ ์ ๊ธฐ์ค์ผ๋ก ์ด๋ ์์น์ ์๋ ๊ฐ์ ๋ฐ๋ผ์ ์ค์ ์ ๋ํ ์ง, ๋บ์ง๋ฅผ ๊ฒฐ์ ํ๋ ๊ฒ๋ ์ข์ง๋ง, ์์ ํ ์ค์ ์ ๊ธฐ์ค์ผ๋ก ํ์ ํ๋ ์ขํ๋ฅผ ๊ตฌํ๊ธฐ ์ํด์ theta์ ๊ฐ๋ง์ผ๋ก ์กฐ์ ํ๋ ๊ฒ์ด ํธํฉ๋๋ค.
์ฒ์์ ์ฒ์ฅ์ ๋งค๋ฌ๋ ค ์๋ ์ฌ๊ฐํ์ ๋ง๋ค์ด์ค๋๋ค. ๋๋ถ์ด ์์ผ๋ก ์์ฃผ ์ธ ์ซ์๋ค๋ ์์๋ก ๋ง๋ค์ด์ค๋๋ค.
const DEG_TO_RAD = Math.PI / 180;
const BAR_INIT_LENGTH = 80;
const BAR_INIT_WIDTH = 5;
const BAR_INIT_ANGLE = 60; //์ฒซ๋ฒ์งธ ํ์ ๊ฐ
const BAR_SECOND_ANGLE = -90; //๋๋ฒ์งธ ํ์ ๊ฐ. ์์๊ฐ์ผ๋ก ๊ณ ์
const currentMousePosition = mouse.position.x; //๋ง์ฐ์ค์ ํ์ฌ ์์น์ x ์ขํ
const bar = Bodies.rectangle(
currentMousePosition,
BAR_INIT_LENGTH,
BAR_INIT_WIDTH,
BAR_INIT_LENGTH,
{
render: {
fillStyle: "#fff",
},
inertia: Infinity,
}
);
์ฐธ๊ณ ๋ก ์ง๊ฒ์ ๋ชจ๋ ์ต์ ์ bar์ ์ต์ ๊ณผ ๋์ผํฉ๋๋ค!
๋ค์์ผ๋ก ์ฒ์ฅ์ ๊พธ์คํ ๋งค๋ฌ๋ ค ์๊ฒ ํ๊ธฐ ์ํด ์ฒ์ฅ๊ณผ ์ฐ๊ฒฐ๋๋ Constraint๋ฅผ ๋ง๋ค์ด์ค๋๋ค.
const barConstraint = Constraint.create({
bodyA: bar,
pointA: { x: 0, y: -BAR_INIT_LENGTH / 2 },
pointB: { x: currentMousePosition, y: 0 },
length: 0,
});
์ด์ ๋๋ฒ์งธ ์ฐ๊ฒฐ๋๋ ์ฌ๊ฐํ์ ๋ง๋ญ๋๋ค.
const initialAngleRad = BAR_INIT_ANGLE * DEG_TO_RAD;
const secondAngleRad = BAR_SECOND_ANGLE * DEG_TO_RAD;
const bar_bar1 = Bodies.rectangle(
currentMousePosition,
BAR_INIT_LENGTH + BAR_INIT_LENGTH / 2,
BAR_INIT_WIDTH,
BAR_INIT_LENGTH / 2,
);
//angle์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ค์ ์ ์์ง์ผ๋ก ๋ฐ๊ฟ์ค๋ค.
Body.setAngle(bar_bar1, Math.PI / 2)
const bar1_localPosition = {
x: parseInt(((BAR_INIT_LENGTH / 2) * Math.cos(initialAngleRad)) / 2),
y: parseInt(((BAR_INIT_LENGTH / 2) * Math.sin(initialAngleRad)) / 2),
}
//๊ธฐ๋ณธ ๊ฐ๋๋ฅผ ์ค ์ํ์์ ์ถ๊ฐ์ ์ผ๋ก ๋๋ ค์ค๋ค.
Body.rotate(bar_bar1, initialAngleRad);
//bar์ ์ขํ๊ฐ ๋๋ถ๋ถ ๊ณ ์ ์ด๋ผ bar1์ ํ๊ณต์๋ค๊ฐ ๊ณ ์ ๊ฐ๋ฅ
const bar1_Constraint = Constraint.create({
pointA: bar1_localPosition,
bodyA: bar_bar1,
pointB: { x: currentMousePosition, y: BAR_INIT_LENGTH },
length: 0,
});
๋ง์ง๋ง ์ฌ๊ฐํ์ ๋ง๋ญ๋๋ค.
const bar_bar1_bar2 = Bodies.rectangle(
currentMousePosition,
2 * BAR_INIT_LENGTH + BAR_INIT_LENGTH / 4,
BAR_INIT_WIDTH,
BAR_INIT_LENGTH / 4,
{
render: {
fillStyle: "#fff",
},
}
);
Body.setAngle(bar_bar1_bar2, Math.PI / 2 - secondAngleRad);
Body.rotate(bar_bar1_bar2, -30);
const bar2_localPosition = {
x: parseInt(((BAR_INIT_LENGTH / 4) * Math.cos( Math.PI / 2 - secondAngleRad )) / 2),
y: parseInt(((BAR_INIT_LENGTH / 4) * Math.sin( Math.PI / 2 - secondAngleRad )) / 2),
}
const bar2_Constraint = Constraint.create({
bodyA: bar_bar1,
pointA: { x: -localPosition.x, y: -localPosition.y },
bodyB: bar_bar1_bar2,
pointB: bar2_localPosition,
length: 0,
});
์ฌ๊ธฐ์์ bar1์ bar2๋ ์ข์ฐ๋์นญ์ผ๋ก ๋ง๋ค์ด์ผ ํ๊ณ , ๊ฐ๋๋ง ๋์นญ์ผ๋ก ํด ๋ง๋ค ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋, bar1๊ณผ bar2๋ฅผ ์ ์ธํ๋ ๋ถ๋ถ์ ํจ์๋ก ๋ง๋ค๊ณ , ํจ์ ๋ด์์ Composite์ add๊น์ง ํ ์ ์๋๋ก ์ธ๋ถ์ ๋ฐฐ์ด์ ์ ์ธํ์ฌ ์์๋ก ๋ฃ์ด์ค์๋ค.
const composites = [];
function createChain(currentMousePosition, index, rads = []) { /*...code...*/ }
createChain(currentMousePosition, index, [-initialAngleRad, secondAngleRad]);
createChain(currentMousePosition, index, [
Math.PI + initialAngleRad,
-secondAngleRad,
]);
์ด์ ์ง๊ฒ๊ฐ ์์ง์ผ ์ ์๋๋ก ์ด๋ฒคํธ๋ฅผ ๋ฌ์๋ด ๋๋ค. ์ผ๋ถ ๋ณ์์ ์์น๊ฐ ๋ณ๊ฒฝ๋๋ค๋ ์ ์ ์ ์ํด์ฃผ์ธ์!
let isMove = false;
let isMouseOn = false;
let isDown = true;
let isClick = true;
let index = 0;
Events.on(mouseConstraint, "mousedown", () => {
isClick = !isMove;
if (isClick) isMove = true;
});
render.canvas.addEventListener("mouseover", (event) => {
isMouseOn = true;
});
render.canvas.addEventListener("mouseleave", () => {
isMouseOn = false;
});
Events.on(runner, "tick", () => {
const currentMousePosition = mouse.position.x;
const currentMousePositionY = mouse.position.y;
let ceilingBarLength = BAR_INIT_LENGTH + index;
const initialAngleRad =
BAR_INIT_ANGLE * DEG_TO_RAD - index / currentMousePositionY / 2;
const secondAngleRad =
BAR_SECOND_ANGLE * DEG_TO_RAD - index / currentMousePositionY; //initialAngle๊ณผ ์ผ์ง์ ๋ณด๋ค ๋์ง ์๊ฒ ์กฐ์
composites.forEach((comp) => {
Composite.remove(engine.world, comp);
});
composites.length = 0; // ๋ฐฐ์ด ์ด๊ธฐํ
if (ceilingBarLength >= currentMousePositionY * 2) isDown = false;
if (ceilingBarLength < BAR_INIT_LENGTH) isDown = true;
createChain(currentMousePosition, index, [-initialAngleRad, secondAngleRad]);
createChain(currentMousePosition, index, [
Math.PI + initialAngleRad,
-secondAngleRad,
]);
if (isMove) {
if (ceilingBarLength < BAR_INIT_LENGTH && isDown) {
index = 0;
isMove = false;
}
index = isDown ? index + 2 : index - 2;
}
Composite.add(engine.world, composites);
});
์ด๋ ๊ฒ ํด๋ฆญํ ๊ณณ๊น์ง ๋ด๋ ค์ค๋ ์ง๊ฒ ์๋ฃ!
โ๏ธ๊ฒฐ๋ก
์ฌ์ค ์์ง ์ ๋ฆฌ๊ฐ ์ ์๋ ์ฝ๋์ด๊ธฐ๋ ํ๊ณ , ๊ฐ๋ ๊ณ์ฐ์์ ์ข ๋ง์ด ํค๋งธ๋ ํฐ๋ผ ์ฝ๋๊ฐ ๊ทธ๋ ๊ฒ ๊น๋ํ์ง ์์ต๋๋ค. ๊ทธ๋์ ์ด ์ฝ๋๋ค์ ์กฐํฉํ๋ฉด ์ ์ฒด ์ฝ๋๊ฐ ๋์ง๋ง, ์ ์ฒด ์ฝ๋๋ ์ข ๋ ๋์ค์ ์ธํ๋ฝ๊ธฐ๊ฐ ์๋ฃ๋๋ฉด ๋ณด์ฌ๋๋ฆฌ๋๋ก ํ๊ฒ ์ต๋๋ค.
์ฌ์ด๋ ํ๋ก์ ํธ๋ฅผ ์ค๋นํ๋ฉด์ ์ต๊ทผ์ ๊ธฐํ๊ณผ ๋์์ธ๋ง ํ๋๋ผ ๊ฐ๋ฐ์ ์์ ๋ชป ๋๋ค๋ณด๋ ๋๋ฌด ์ฌ์ฌํด์ ๋ด์งํ ๊ฒฐ๊ณผ์ ๋๋ค. ์ค๋๋ง์ ์ผ๊ฐํจ์ ๋๋ฌธ์ ์์ดํจ๋๋ก ํ๋์ฉ ๊ณ์ฐ๋ ํด๋ณด๊ณ ์ฌ๋ฐ์์ต๋๋ค..........ใ
'Create' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์๊ณ ๋ฆฌ์ฆ] ์ด๊ฒ ๋๋ค...? (1) | 2024.06.03 |
---|---|
[์๊ณ ๋ฆฌ์ฆ] ๋ ๊ทธ๋๋ ํ๊ธด ํ์์ด...? (1) | 2024.05.30 |
[React] ์ ๋ฐ์ํ ํ ์คํธ๋ฐ์ค๋ ์คํ์ผ๋ก ๋ง๋๋๊ฐ? (0) | 2024.05.11 |
[React] ๋ฆฌํฉํ ๋ง - ๋ฐ์ดํฐ/์ก์ /๊ณ์ฐ์ผ๋ก ๋ถ๋ฆฌํ๊ณ ์ฟผ๋ฆฌ ์คํธ๋ง์ ์ฌ์ฉํ์ (0) | 2024.05.08 |
[React] ์ปดํฌ๋ํธ๋ ํ ๋ฒ์ ํ๋์ ์ฑ ์๋ง ์ง๋ค. (0) | 2024.05.05 |