200921__JS Falling ball game 정리 (2/2)

Positive Ko·2020년 9월 21일
0

JavaScript

목록 보기
3/28
post-custom-banner

Javascript Game Tutorial for Beginners 에 대해 공부한 TIL 입니다.

Javascript Game Tutorial for Beginners


아래는 keydown에 대한 event를 생성해서 ←→키에 대한 명령을 만들어주는 부분, 그리고 keyup에 대한 event를 생성해서 아무 키도 누르지 않았을 때 클리어 인터벌로 움직이지 않도록 설정해주었다.

both는 중복키 방지의 역할을 한다.

document.addEventListener('keydown', (event) => {
  if (both == 0) {
    both++;
    if (event.key === 'ArrowLeft') {
      interval = setInterval(moveLeft, 1);
    }
    if (event.key === 'ArrowRight') {
      interval = setInterval(moveRight, 1);
    }
  }
});

document.addEventListener('keyup', (event) => {
  clearInterval(interval);
  both = 0;
});

setInterval(function(), 지연시간) : 일정한 시간 간격으로 작업을 수행. clearInterval()로 작업을 중단한다.

setInterval를 사용하여 누르고 있다면 지속하여 지정한 function이 실행된다. (해당 코드에서는 1ms에 moveLeft, moveRight가 실행)


아래 부분은 html에 block과 hole을 div로 만들어 주는 부분. width의 범위 안에서 랜덤하게 hole을 뚫을 수 있도록 floor와 random을 이용해 만들어준다.

block과 hole을 계속해서 만들 수 있도록 똑같이 setInterval를 활용하여 만들어준다. 카운터라는 변수를 만들어 0으로 설정한다. 새로운 블록을 만들 때마다 counter를 하나씩 증가시킨다.

그리고 마지막으로 만들어진 block을 찾고 100px을 더해서 새로운 블록이 만들어지도록 한다. blockLast와 holeLast를 선언해서 제일 마지막에 만들어진(counter -1 값) block과 hole의 top 값에 100px을 더해주는 것이다.

var blocks = setInterval(function () {
  if (counter > 0) {
    var blockLast = document.getElementById('block' + (counter - 1));
    var holeLast = document.getElementById('hole' + (counter - 1));
    var blockLastTop = parseInt(
      window.getComputedStyle(blockLast).getPropertyValue('top')
    );
    var holeLastTop = parseInt(
      window.getComputedStyle(holeLast).getPropertyValue('top')
    );
  }
  if (counter == 0 || blockLastTop < 400) {
    var block = document.createElement('div');
    var hole = document.createElement('div');
    block.setAttribute('class', 'block');
    hole.setAttribute('class', 'hole');
    block.setAttribute('id', 'block' + counter);
    hole.setAttribute('id', 'hole' + counter);
    block.style.top = blockLastTop + 100 + 'px';
    hole.style.top = holeLastTop + 100 + 'px';
    var random = Math.floor(Math.random() * 360);
    hole.style.left = random + 'px';
    game.appendChild(block);
    game.appendChild(hole);
    currentBlocks.push(counter);
    counter++;
  }

볼(character)의 top과 left 값을 받아 위치로 삼고, drop을 0으로 설정한다. 볼이 게임 밖으로 넘어가면 게임이 오버되도록 설정하는 부분. (characterTop ≤ 0)


var characterTop = parseInt(
    window.getComputedStyle(character).getPropertyValue('top')
  );
  var characterLeft = parseInt(
    window.getComputedStyle(character).getPropertyValue('left')
  );
  var drop = 0;
  if (characterTop <= 0) {
    alert('Game over. Score: ' + (counter - 9));
    clearInterval(blocks);
    location.reload();
  }

current를 선언하여 현재의 블록으로 설정하고 각각 iblock, ihole값을 선언한다.

만약 current 블록이 최상단으로 올라가면 (iblockTop < -20) 해당 블록이 하나씩 없어지도록 한다.

볼의 위치가(characterLeft)가 ihole의 위치(iholeLeft ≤ x < ihole+20)에 해당한다면 떨어지도록 만들고(drop=0), 그렇지 않다면 올라가도록 만든다. (drop++)

블록이 올라가는 속도와 볼이 떨어지는 속도는 gameSpeed 값으로 설정하여 조정할 수 있게 했다.

for (var i = 0; i < currentBlocks.length; i++) {
    let current = currentBlocks[i];
    let iblock = document.getElementById('block' + current);
    let ihole = document.getElementById('hole' + current);
    let iblockTop = parseFloat(
      window.getComputedStyle(iblock).getPropertyValue('top')
    );
    let iholeLeft = parseFloat(
      window.getComputedStyle(ihole).getPropertyValue('left')
    );
    var gameSpeed = 0.8;

    iblock.style.top = iblockTop - gameSpeed + 'px';
    ihole.style.top = iblockTop - gameSpeed + 'px';

    if (iblockTop < -20) {
      currentBlocks.shift();
      iblock.remove();
      ihole.remove();
    }
    if (iblockTop - 20 < characterTop && iblockTop > characterTop) {
      drop++;
      if (iholeLeft <= characterLeft && iholeLeft + 20 > characterLeft) {
        drop = 0;
      }
    }
  }
  if (drop == 0) {
    if (characterTop < 480) {
      character.style.top = characterTop + gameSpeed * 3.0 + 'px';
    }
  } else {
    character.style.top = characterTop - gameSpeed + 'px';
  }
}, 1);
profile
내 이름 고은정, 은을 180deg 돌려 고긍정 🤭
post-custom-banner

0개의 댓글