[TIL] 211003

Lee SyongΒ·2021λ…„ 10μ›” 3일
0

TIL

λͺ©λ‘ 보기
46/204
post-thumbnail

πŸ“ 였늘 ν•œ 것

  1. λ―Έλ‹ˆ κ²Œμž„ λ¦¬νŒ©ν† λ§

πŸ“š 배운 것

λ¦¬νŒ©ν† λ§


1. result 클래슀 λ§Œλ“€κΈ°

1) result.js μž‘μ„±

  • result.jsλΌλŠ” νŒŒμΌμ„ λ”°λ‘œ λ§Œλ“€μ–΄μ„œ result와 κ΄€λ ¨λœ μ½”λ“œλ₯Ό 이곳에 적어쀀닀. srcλΌλŠ” 폴더에 result.js와 main.jsλ₯Ό ν•¨κ»˜ λ„£μ–΄ κ΄€λ¦¬ν•œλ‹€. HTML 파일의 script μ½”λ“œ 뢀뢄에 type="module"을 μ λŠ”λ‹€.

  • result.jsμ—μ„œ Result λΌλŠ” classλ₯Ό μ„ μ–Έν•œλ‹€.

  • constructor ν•¨μˆ˜λ₯Ό 톡해 result 클래슀의 멀버 λ³€μˆ˜λ₯Ό λ§Œλ“€μ–΄μ€€λ‹€. ν•„μš”ν•œ DOM μš”μ†Œλ₯Ό 가지고 μ™€μ„œ κ·Έ μ•žμ— thisλ₯Ό 적어쀀닀. μ—¬κΈ°μ„œ thisλŠ” Result 클래슀 객체λ₯Ό μ˜λ―Έν•œλ‹€.

  • πŸ“Œ setClickListener λ©”μ„œλ“œλ₯Ό 등둝해쀀닀. onClickμ΄λΌλŠ” 콜백 ν•¨μˆ˜λ₯Ό Result 클래슀의 onClickμ΄λΌλŠ” 멀버 λ³€μˆ˜μ— ν• λ‹Ήν•œλ‹€.

  • πŸ“Œ onClick 멀버 λ³€μˆ˜κ°€ true라면(λ“±λ‘λœ 콜백 ν•¨μˆ˜κ°€ 있으면) 그것을 μ‹€ν–‰ν•œλ‹€.

  • Result 클래슀 μ•žμ— export default λ₯Ό μ μ–΄μ„œ λ‹€λ₯Έ νŒŒμΌμ—μ„œλ„ Result 클래슀λ₯Ό 읽을 수 μžˆλ„λ‘ ν•΄μ€€λ‹€.

'use strict';

export default class Result {
  constructor () {
    this.gameResult = document.querySelector('.result');
    this.replayBtn = document.querySelector('.replayBtn');
    this.notice = document.querySelector('.notice');
    this.replayBtn.addEventListener('click', () => {
      this.onClick && this.onClick(); // πŸ“Œ 
      this.hide();
    });
  }

  setClickListener (onClick) { // πŸ“Œ
    this.onClick = onClick;
  }

  show (text) {
    this.gameResult.style.display = 'block';
    this.notice.innerHTML = text;
  }

  hide () {
    this.gameResult.style.display = 'none';
  }
}

2) main.js μˆ˜μ •

  • 파일 μœ„μ— import Result from './result.js'; 라고 적어쀀닀.

  • Result 클래슀λ₯Ό μ΄μš©ν•΄ gameFinishBannerλΌλŠ” 객체λ₯Ό 생성해쀀닀. κ·Έλƒ₯ result라고 쓰지 말고, μ •ν™•νžˆ 이게 μ–΄λ–€ 건지 μ„€λͺ…ν•΄μ£ΌλŠ” 이름을 쓰도둝 ν•œλ‹€.

  • gameFinishBanner에 setClickListener λ©”μ„œλ“œλ₯Ό 등둝해쀀닀. 이둜 인해 클릭이 되면 startGame ν•¨μˆ˜κ°€ ν˜ΈμΆœλœλ‹€.

const gameFinishBanner = new Result();

gameFinishBanner.setClickListener(() => {
  startGame();
});
/*
gameFinishBanner.setClickListener(() => startGame());
gameFinishBanner.setClickListener(startGame);

λͺ¨λ‘ 같은 λœ»μ΄λ‹€.
*/
  • κ·Έ 외에도 main.jsμ—μ„œ result와 κ΄€λ ¨λœ 뢀뢄을 μ‚­μ œν•˜κ±°λ‚˜ μˆ˜μ •ν•œλ‹€. hideGameResult ν•¨μˆ˜μ™€ showGameResult ν•¨μˆ˜λŠ” μ‚­μ œν•œλ‹€. 이 ν•¨μˆ˜κ°€ 호좜된 뢀뢄듀은 gameFinishBanner.show ν˜Ήμ€ gameFinishBanner.hide둜 μˆ˜μ •ν•œλ‹€.

2. Field 클래슀 λ§Œλ“€κΈ°

1) field.js μž‘μ„±

  • field.jsμ—μ„œ Field λΌλŠ” classλ₯Ό μ„ μ–Έν•œλ‹€.

  • constructor ν•¨μˆ˜λ₯Ό 톡해 field 클래슀의 멀버 λ³€μˆ˜λ₯Ό λ§Œλ“€μ–΄μ€€λ‹€. field에 클릭 이벀트λ₯Ό λ“±λ‘ν•˜μ—¬ field 클릭 μ‹œ field 클래슀의 멀버 λ©”μ„œλ“œμΈ onClick ν•¨μˆ˜κ°€ ν˜ΈμΆœλ˜λ„λ‘ 적어쀀닀.

πŸ’‘ this에 바인딩 ν•˜λŠ” 방법

  • class 멀버 ν•¨μˆ˜κ°€ λ‹€λ₯Έ ν•¨μˆ˜ 인자둜 전달될 λ•ŒλŠ”, this에 κ·Έ class의 정보가 μœ μ§€λ˜μ§€ μ•ŠλŠ”λ‹€. λ”°λΌμ„œ μ•„λž˜μ™€ 같이 μž‘μ„±ν•˜λ©΄, onClick ν•¨μˆ˜ λ³Έλ¬Έ(μ•„λž˜ field.js 전체 μ½”λ“œ μ°Έκ³ )μ—μ„œ this.onItemClick 값이 항상 undefinedκ°€ λ˜μ–΄ μ½”λ“œκ°€ μ˜λ„ν•œ λŒ€λ‘œ μ‹€ν–‰λ˜μ§€ μ•ŠλŠ”λ‹€.
this.field.addEventListener('click', this.onClick); // (x)
  • 이λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ μ•„λž˜ 3가지 방법을 μ‚¬μš©ν•  수 μžˆλ‹€. ν™”μ‚΄ν‘œ ν•¨μˆ˜μ—μ„œ thisλŠ” μ–Έμ œλ‚˜ ν™”μ‚΄ν‘œ ν•¨μˆ˜ μƒμœ„ μŠ€μ½”ν”„μ˜ thisλ₯Ό κ°€λ¦¬ν‚€λŠ” 점을 μ΄μš©ν•΄ μž‘μ„±ν•΄λΌ.

βœ” ν™”μ‚΄ν‘œ ν•¨μˆ˜ 이용 β‘ 

this.field.addEventListener('click', (event) => this.onClick(event));

βœ” ν™”μ‚΄ν‘œ ν•¨μˆ˜ 이용 β‘‘

// μ΄λ ‡κ²Œ μ •μ˜λœ onClick ν•¨μˆ˜λ₯Ό
onClick (event) {

}

// μ΄λ ‡κ²Œ λ°”κΎΌλ‹€
onClick = (event) => {

}

βœ” bind λ©”μ„œλ“œ 이용

this.onClick = this.onClick.bind(this);
this.field.addEventListener('click', this.onClick);
  • Field ν΄λž˜μŠ€λŠ” started, timer, limit λ“± κ²Œμž„ 진행 μƒνƒœμ— κ΄€ν•œ μ •λ³΄λŠ” μ²˜λ¦¬ν•  수 μ—†λ‹€. μ›λž˜ fieldμ—μ„œ μΌμ–΄λ‚¬λ˜ 이미지 랜덀 배치 & 클릭 μ΄λ²€νŠΈμ™€ κ΄€λ ¨λœ λΆ€λΆ„λ§Œ main.js μ½”λ“œμ—μ„œ κ°€μ Έμ˜¨λ‹€. class의 멀버 λ³€μˆ˜λ‚˜ 멀버 λ©”μ„œλ“œλ‘œ μ •μ˜λœ 것듀이라면, μ•žμ— thisλ₯Ό 뢙인닀.

  • class λ‚΄μš©κ³Ό μƒκ΄€μ—†λŠ” λ°°κ²½ μŒμ•… μž¬μƒ ν•¨μˆ˜ 등은 λ©”λͺ¨λ¦¬ λ‚­λΉ„λ₯Ό 막기 μœ„ν•΄ class λ°–μœΌλ‘œ λΉΌμ„œ 써쀀닀. (μΆ”ν›„ μˆ˜μ •ν•  λΆ€λΆ„)

  • onClick ν•¨μˆ˜μ˜ if else if κ΅¬λ¬Έμ—μ„œ this.onItemClick ν•¨μˆ˜κ°€ 싀행될 λ•Œ 각각 carrotκ³Ό bugλ₯Ό 인자둜 μ£Όμ–΄ κ΅¬λΆ„λ˜λ„λ‘ ν–ˆλ‹€.

'use strict';

// μ „μ—­ λ³€μˆ˜λ“€
const CARROT_SIZE = 120;
const BUG_SIZE = 80;

const carrotSound = new Audio('sound/carrot_pull.mp3');

// field 클래슀
export default class Field {
  constructor (carrotCount, bugCount) {
    this.carrotCount = carrotCount;
    this.bugCount = bugCount;
    this.field = document.querySelector('.field');
    this.fieldRect = this.field.getBoundingClientRect();
    this.field.addEventListener('click', (event) => this.onClick(event));
  }

  // 이미지 랜덀 배치
  init () {
    this.field.innerHTML = '';
    this._makeImg('carrot', this.carrotCount, 'img/carrot.png', CARROT_SIZE);
    this._makeImg('bug', this.bugCount, 'img/bug.png', BUG_SIZE);
  }

  // 이미지 생성
  _makeImg (name, count, src, size) { // 이 νŒŒμΌμ—μ„œλ§Œ 뢈릴 ν•¨μˆ˜ μ•žμ— _ ν‘œμ‹œλ₯Ό 뢙인닀
    for (let i = 0; i < count; i++) {
      const item = document.createElement('img');
      item.setAttribute('class', `${name}`);
      item.setAttribute('src', `${src}`);

      const coord = this._randomCoord(size);
      item.style.left = coord[0] + 'px';
      item.style.top = coord[1] + 'px';
      item.style.width = size + 'px';

      this.field.appendChild(item);
    }
  }

  // 랜덀 μ’Œν‘œ 생성
  _randomCoord (size) {
    return [ ( this.fieldRect.width - size ) * Math.random(),
             ( this.fieldRect.height - size ) * Math.random() ];
  }

  // 콜백 ν•¨μˆ˜λ₯Ό class 객체의 λ³€μˆ˜μ— ν• λ‹Ή
  setClickListener (onItemClick) {
    this.onItemClick = onItemClick;
  }

  // field의 클릭 이벀트 λ¦¬μŠ€λ„ˆ
  onClick (event) {
    const target = event.target;

    if (target.matches('.carrot')) {
      target.remove();
      playSound(carrotSound);
      this.onItemClick && this.onItemClick('carrot');
    } else if (target.matches('.bug')) {
      this.onItemClick && this.onItemClick('bug');
    }
  }
}

// λ°°κ²½ μŒμ•… μž¬μƒ ν•¨μˆ˜
function playSound (sound) {
  sound.currentTime = 0;
  sound.play();
}

2) main.js μˆ˜μ •

  • field.js의 onClick ν•¨μˆ˜μ— μžˆλŠ” 이미지 μ‚­μ œλ‚˜ μŒμ•… μž¬μƒμ€ main.js의 onFieldItemClick ν•¨μˆ˜μ— 적지 μ•Šμ•˜λ‹€.

  • initGame ν•¨μˆ˜μ— 기쑴의 init() λŒ€μ‹  gameField.init()을 μ μ–΄μ£Όμ—ˆλ‹€.

const gameField = new Field(CARROT_COUNT, BUG_COUNT);

gameField.setClickListener(onFieldItemClick);

function onFieldItemClick (item) {
  if (!started) {
    return;
  }

  if (item === 'carrot') {
    showGameLimit(--limit);

    if (limit === 0) {
      finishGame(true);
    }
  } else if (item === 'bug') {
    finishGame(false);
  }
}

✨ 내일 ν•  것

  1. 객체 지ν–₯ ν”„λ‘œκ·Έλž˜λ°, class, λͺ¨λ“ˆν™” λ“± ν•™μŠ΅
profile
λŠ₯λ™μ μœΌλ‘œ μ‚΄μž, ν–‰λ³΅ν•˜κ²ŒπŸ˜

0개의 λŒ“κΈ€