JavaScript 스터디

Hvvany·2022년 12월 30일
0

Javascript

목록 보기
8/12

뱀게임🐍

필요한 js메서드

  • querySelector()
  • addEventListener()
  • setInterval()
  • keyCodes
  • pop()
  • push()
  • Array.prototype.unshift()
  • classList.contains()
  • classList.add()
  • classList.remove()

setInterval

const timerId = setInterval(func|code[, delay, param1, param2,...])

두 번째 인수로 전달받은 시간만큼 반복하여 func을 실행시킨다.

keyCodes

키보드의 문자 및 기능을 특정 코드로 정해놓은 것
https://blog.outsider.ne.kr/322

Array.prototype.unshift

const arr = [1, 2]

// 인수로 전달받은 모든 값을 원본 배열의 선두에 요소로 추가하고 변경된 length 값을 반환한다.
let result = arr.unshift(3,4)
console.log(result) //4

//unshift 메서드는 원본 배열을 직접 변경한다.
console.log(arr) //[3, 4, 1, 2]

배열의 맨 앞에 추가하여 배열을 변경시켜준다. 또한 그 값은 추가된 배열의 전체 길이이다.

element.classList

element의 클래스 목록 접근 => css class 변경 가능

  • contain
  • add
  • remove

코드

html

<!DOCTYPE html>
<html lang="en">
  <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" />
    <title>Snake</title>
    <link rel="stylesheet" href="./style.css" />
  </head>
  <body>
    <h1>뱀 게임 🐍</h1>
    <h3>난이도 선택</h3>

    <input type="radio" name="level" value="50" class="checked" />초고수
    <input type="radio" name="level" value="100" />고수
    <input type="radio" name="level" value="500" />중수
    <input type="radio" name="level" value="1000" />초보
    <br />
    <br />
    <br />
    <button class="start" type="submit">Start/Restart</button>

    <h2 class="score">Score:<span>0</span></h2>

    <div class="grid">
      <!-- 10 x 10 grid = 100 divs -->
    </div>

    <script defer src="./main.js" charset="utf-8"></script>
  </body>
</html>

css

.grid {
  width: 600px;
  height: 600px;
  display: flex;
  flex-wrap: wrap;
  border-style: solid;
}

.grid div {
  width: 30px;
  height: 30px;
}

.snake {
  background-color: blue;
}

.apple {
  background-color: red;
}

javascript

const size = 400;
for (let i = 0; i < size; i++) {
  let block = document.createElement("div");
  document.querySelector(".grid").appendChild(block);
}

document.addEventListener("DOMContentLoaded", () => {
  const squares = document.querySelectorAll(".grid div");
  const scoreDisplay = document.querySelector("span");
  const startBtn = document.querySelector(".start");

  const width = 20;
  let currentIndex = 0;
  let appleIndex = 0;
  let currentSnake = [2, 1, 0];
  let direction = 1;
  let score = 0;
  let speed = 0.9;
  let intervalTime = 0;
  let interval = 0;

  // start, restart game
  function startGame() {
    currentSnake.forEach((index) => squares[index].classList.remove("snake"));
    squares[appleIndex].classList.remove("apple");
    clearInterval(interval);
    score = 0;
    randomApple();
    direction = 1;
    scoreDisplay.innerText = score;
    intervalTime = document.querySelector('input[name="level"]:checked').value;
    currentSnake = [2, 1, 0];
    currentIndex = 0;
    currentSnake.forEach((index) => squares[index].classList.add("snake"));
    interval = setInterval(moveOutcomes, intervalTime);
  }

  function moveOutcomes() {
    // 뱀이 벽 또는 자기 자신 부닺힐 경우
    if (
      (currentSnake[0] + width >= width * width && direction === width) || //뱀이 바닥 부딪힘
      (currentSnake[0] % width === width - 1 && direction === 1) || //뱀이 오른쪽 부딪힘
      (currentSnake[0] % width === 0 && direction === -1) || //뱀이 왼쪽 부딪힘
      (currentSnake[0] - width < 0 && direction === -width) || //뱀이 위에 부딪힘
      squares[currentSnake[0] + direction].classList.contains("snake") //스스로에게 부딪힘
    ) {
      alert("gameover!!!");
      startGame();
      return clearInterval(interval);
    }

    const tail = currentSnake.pop(); // 배열 마지막 부분 삭제 및 테일에 담기
    squares[tail].classList.remove("snake"); // 꼬리 클래스 삭제
    currentSnake.unshift(currentSnake[0] + direction); // 배열 맨앞에 방향정보 삽입

    // 뱀이 사과 먹은 경우
    if (squares[currentSnake[0]].classList.contains("apple")) {
      squares[currentSnake[0]].classList.remove("apple");
      squares[tail].classList.add("snake");
      currentSnake.push(tail);
      randomApple();
      // 사과 제거
      score++;
      scoreDisplay.textContent = score;
      clearInterval(interval);
      intervalTime = intervalTime * speed;
      interval = setInterval(moveOutcomes, intervalTime);
    }
    squares[currentSnake[0]].classList.add("snake");
  }
  // 뱀이 사과 먹으면 자동으로 랜덤으로 생성
  function randomApple() {
    do {
      appleIndex = Math.floor(Math.random() * squares.length);
    } while (squares[appleIndex].classList.contains("snake"));
    squares[appleIndex].classList.add("apple");
  }

  function control(e) {
    squares[currentIndex].classList.remove("snake");
    if (e.keyCode === 39) {
      direction = 1; // 방향키 오른쪽 누르면
    } else if (e.keyCode === 38) {
      direction = -width; // 방향키 위 누르면
    } else if (e.keyCode === 37) {
      direction = -1; // 방향키 왼쪽 누르면
    } else if (e.keyCode === 40) {
      direction = +width; // 방향키 아래 누르면
    }
  }

  document.addEventListener("keyup", control);
  startBtn.addEventListener("click", startGame);
});



level 쉬움

level 어려움

profile
Just Do It

0개의 댓글