[JS] Sprite Animation

Park Inhyeยท2022๋…„ 9์›” 4์ผ
0

Javascript

๋ชฉ๋ก ๋ณด๊ธฐ
4/7
post-thumbnail

๐Ÿ’ซ Canvas๋ฅผ ์ด์šฉํ•œ Sprite Animation

์ปดํ“จํ„ฐ ๊ทธ๋ž˜ํ”ฝ์Šค์—์„œ ์Šคํ”„๋ผ์ดํŠธ(์˜์–ด: sprite)๋Š” ์˜์ƒ ์†์— ์ž‘์€ 2์ฐจ์› ๋น„ํŠธ๋งต์ด๋‚˜ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ํ•ฉ์„ฑํ•˜๋Š” ๊ธฐ์ˆ ์ด๋‹ค. ์ดˆ๊ธฐ์—๋Š” 2D ๋น„๋””์˜ค ๊ฒŒ์ž„์—์„œ ๋น„๋””์˜ค ์˜์ƒ๊ณผ ๋ถ„๋ฆฌ๋œ ๋ณ„๋„์˜ ๊ทธ๋ž˜ํ”ฝ์Šค ๊ฐ์ฒด๋ฅผ ์˜๋ฏธํ–ˆ์ง€๋งŒ, ์˜ค๋Š˜๋‚ ์—๋Š” ๋‹ค์–‘ํ•œ ์ธต์˜ ์ด๋ฏธ์ง€, ํ…์ŠคํŠธ ๋“ฑ์„ ๊ฐ๊ฐ์˜ ์šฐ์„ ์ˆœ์œ„๋ฅผ ๋‘๊ณ  ํ•ฉ์„ฑํ•˜๋Š” ๊ธฐ์ˆ ์„ ํ†ตํ‹€์–ด ์ผ์ปซ๋Š”๋‹ค.
From. ์œ„ํ‚ค๋ฐฑ๊ณผ - ์Šคํ”„๋ผ์ดํŠธ (์ปดํ“จํ„ฐ ๊ทธ๋ž˜ํ”ฝ์Šค)

1.๋ฐฉ๋ฒ•

  1. canvas๋ฅผ ํ˜ธ์ถœ
  2. canvas ํฌ๊ธฐ ์„ค์ •
  3. Animation ๋™์ž‘์„ ์„ค์ •ํ•˜๋Š” ํด๋ž˜์Šค ์ƒ์„ฑ
  4. ๋ผ๋””์˜ค ๋ฒ„ํŠผ์— ์ด๋ฒคํŠธ ์„ค์ •

2. ๊ตฌํ˜„

1) canvas๋ฅผ ํ˜ธ์ถœ

const $canvas = document.querySelector('#canvas1');
const _ctx = $canvas.getContext('2d');

2) canvas ํฌ๊ธฐ ์„ค์ •

$canvas.width = 500;
$canvas.height = 500;
  • <canvas>์˜ attr์— ์„ ์–ธํ•ด๋„ ๋œ๋‹ค.

3) Animation ๋™์ž‘์„ ์„ค์ •ํ•˜๋Š” ํด๋ž˜์Šค ์ƒ์„ฑ

  1. constructor ์„ ์–ธ
    • ์‚ฝ์ž…ํ•  ์ด๋ฏธ์ง€
    • sprite ๋„ˆ๋น„
    • sprite ๋†’์ด
    • ๊ฐ€๋กœ ํ”„๋ ˆ์ž„
    • ์„ธ๋กœ ํ”„๋ ˆ์ž„
    • ํฌ๊ธฐ๋น„์œจ
    • ์บ”๋ฒ„์Šค ๋„ˆ๋น„
    • ์บ”๋ฒ„์Šค ๋†’์ด
    • [sprite ์‹œ์ž‘ ์œ„์น˜ x] = [๊ฐ€๋กœ ํ”„๋ ˆ์ž„] * [sprite ๋„ˆ๋น„]
    • [sprite ์‹œ์ž‘ ์œ„์น˜ y] = [์„ธ๋กœ ํ”„๋ ˆ์ž„] * [sprite ๋†’์ด]
    • [์ถœ๋ ฅ ์ด๋ฏธ์ง€ ๋„ˆ๋น„] = [sprite ๋„ˆ๋น„] * [ํฌ๊ธฐ๋น„์œจ]
    • [์ถœ๋ ฅ ์ด๋ฏธ์ง€ ๋†’์ด] = [sprite ๋†’์ด] * [ํฌ๊ธฐ๋น„์œจ]
    • [์ถœ๋ ฅ ์ด๋ฏธ์ง€ ์‹œ์ž‘ ์œ„์น˜ X] = [์บ”๋ฒ„์Šค ๋„ˆ๋น„] / 2 - ( [์ถœ๋ ฅ ์ด๋ฏธ์ง€ ๋„ˆ๋น„] / 2 );
    • [์ถœ๋ ฅ ์ด๋ฏธ์ง€ ์‹œ์ž‘ ์œ„์น˜ Y] = [์บ”๋ฒ„์Šค ๋†’์ด] / 2 - ( [์ถœ๋ ฅ ์ด๋ฏธ์ง€ ๋†’์ด] / 2 );
/* drawImage 
    context.drawImage(
        [์‚ฝ์ž…ํ•  ์ด๋ฏธ์ง€],
        [sprite ์‹œ์ž‘ ์œ„์น˜ x],
        [sprite ์‹œ์ž‘ ์œ„์น˜ y],
        [sprite ๋„ˆ๋น„],
        [sprite ๋†’์ด],
        [์ถœ๋ ฅ ์ด๋ฏธ์ง€ ์‹œ์ž‘ ์œ„์น˜ X],
        [์ถœ๋ ฅ ์ด๋ฏธ์ง€ ์‹œ์ž‘ ์œ„์น˜ Y],
        [์ถœ๋ ฅ ์ด๋ฏธ์ง€ ๋„ˆ๋น„],
        [์ถœ๋ ฅ ์ด๋ฏธ์ง€ ๋†’์ด],
    )
*/
  1. ๋ฉ”์†Œ๋“œ

    • draw
      • ์ด๋ฏธ์ง€ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
    • update
      • ๊ธฐ๋ณธ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์„ค์ •
      • (์ตœ์†Œ ํ”„๋ ˆ์ž„ ~ ์ตœ๋Œ€ ํ”„๋ ˆ์ž„)๋ฅผ ๋ฐ˜๋ณตํ•˜๋Š” ๊ฐ’ ์„ค์ •
      • this.frame์œผ๋กœ row/column ๋ฐ˜๋ณตํ•˜๋Š” ๊ฐ’ ๋„์ถœ
    • setAnimation
      • (ํ”„๋ ˆ์ž„ ์‹œ์ž‘)๊ณผ (ํ”„๋ ˆ์ž„ ๋ ๊ฐ’)์„ ์กฐ์ ˆํ•˜๋„๋ก ์„ค์ •
  2. ํด๋ž˜์Šค ํ˜ธ์ถœ ๋ฐ ๊ธฐ๋ณธ animate ์„ค์ •

    • draw() > update() > requestAnimationFrame(animate) ์ˆœ์œผ๋กœ ํ˜ธ์ถœ
    • requestAnimationFrame(animate)๋Š” canvas์— ๋ชจ๋“  ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๋‚จ๊ธด๋‹ค.
    • _ctx.clearRect๋กœ ์บ”๋ฒ„์Šค๋ฅผ ์ง€์›Œ์ค˜์•ผํ•จ
  const mandrake = new Animation($canvas.width, $canvas.height);

  function animate() {
    // _ctx.clearRect([์บ”๋ฒ„์Šค ์‹œ์ž‘ ์œ„์น˜ X], [์บ”๋ฒ„์Šค ๋ ์œ„์น˜ Y], [์บ”๋ฒ„์Šค ๋„ˆ๋น„], [์บ”๋ฒ„์Šค ๋†’์ด]);
    _ctx.clearRect(0, 0, $canvas.width, $canvas.height);
    mandrake.draw(_ctx);
    mandrake.update();
    requestAnimationFrame(animate);
  }

  animate();

4) ๋ผ๋””์˜ค ๋ฒ„ํŠผ์— ์ด๋ฒคํŠธ ์„ค์ •

์ฝœ๋ฐฑ ํ•จ์ˆ˜์— mandrake.setAnimation([์‹œ์ž‘ ํ”„๋ ˆ์ž„], [๋ ํ”„๋ ˆ์ž„]) ์„ ์–ธ

3. ๋ณ€ํ˜•

  • radio๋ฅผ button์œผ๋กœ ๋ณ€๊ฒฝ
  • button์— data-* ์†์„ฑ์œผ๋กœ [์‹œ์ž‘ ํ”„๋ ˆ์ž„]๊ณผ [๋ ํ”„๋ ˆ์ž„] ์„ค์ •
    dataset์œผ๋กœ ๋ฐ›์•„์˜จ ๊ฐ’์˜ ๋ฐ์ดํ„ฐ ํ˜•์€ ๋ฌธ์ž์—ด์ด๋ฏ€๋กœ ์ˆซ์žํ˜•์œผ๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค.
<!-- index.html -->
<button type="button" data-min="0" data-max="75">Grow</button>
<button type="button" data-min="76" data-max="112">Wink</button>
...
// page_sprite.js
const groupControl = document.querySelector('.group-control');
groupControl.addEventListener('click', function (e) {
    const $target = e.target;
    const _min = $target.dataset.min;
    const _max = $target.dataset.max;

	mandrake.setAnimation(Number(_min), Number(_max));
});

๐Ÿ› ์—๋Ÿฌ

1. .getContext('2d');

'2D'๋Š” ์—๋Ÿฌ๊ฐ€ ๋‚˜๊ณ  '2d'๋Š” ์ •์ƒ์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค.

// ์—๋Ÿฌ
const $canvas = document.querySelector('#sprite_canvas');
const _ctx = $canvas.getContext('2D');

// ์ •์ƒ
const $canvas = document.querySelector('#sprite_canvas');
const _ctx = $canvas.getContext('2d');

2. Canvas ํฌ๊ธฐ์„ค์ •

canvas ํฌ๊ธฐ ๊ฐ’์€ ์ˆซ์žํ˜•์œผ๋กœ ์„ค์ •ํ•œ๋‹ค.

// ์—๋Ÿฌ
$canvas.width = '500px';
$canvas.height = '500px';

// ์ •์ƒ
$canvas.width = 500;
$canvas.height = 500;

์ถœ์ฒ˜
Franks Laboratory - JavaScript Sprite Animation
MDN - getContext

profile
๐Ÿ‘๐Ÿ‘„๐Ÿ‘

0๊ฐœ์˜ ๋Œ“๊ธ€